diff --git a/pkg/front_end/lib/src/base/incremental_compiler.dart b/pkg/front_end/lib/src/base/incremental_compiler.dart index 2dd3f6d5d7d..2145b9bec82 100644 --- a/pkg/front_end/lib/src/base/incremental_compiler.dart +++ b/pkg/front_end/lib/src/base/incremental_compiler.dart @@ -91,6 +91,7 @@ import '../dill/dill_loader.dart' show DillLoader; import '../dill/dill_target.dart' show DillTarget; import '../kernel/benchmarker.dart' show BenchmarkPhases, Benchmarker; import '../kernel/dart_scope_calculator.dart' show DartScope, DartScopeBuilder2; +import '../kernel/external_ast_helper.dart' as extern; import '../kernel/hierarchy/hierarchy_builder.dart' show ClassHierarchyBuilder; import '../kernel/internal_ast.dart' show InternalVariableGet, InternalVariableSet, InternalVariable; @@ -2228,7 +2229,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator { MemoryFileSystem fs = hfs.memory; fs.entityForUri(debugExprUri).writeAsStringSync(expression); - InternalVariable? extensionThis; + Variable? extensionThis; // TODO: pass variable declarations instead of // parameter names for proper location detection. @@ -2239,13 +2240,18 @@ class IncrementalCompiler implements IncrementalKernelGenerator { positionalParameters: usedDefinitions.entries.map(( MapEntry def, ) { - InternalVariable variable = intern.createPositionalParameter( - isClosureContextLoweringEnabled: - lastGoodKernelTarget.loader.isClosureContextLoweringEnabled, - cosmeticName: def.key, - type: def.value, - fileOffset: offsetToUse ?? libraryBuilder.library.fileOffset, - ); + Variable variable = + lastGoodKernelTarget.loader.isClosureContextLoweringEnabled + ? extern.createPositionalParameter( + cosmeticName: def.key, + type: def.value, + fileOffset: offsetToUse ?? libraryBuilder.library.fileOffset, + ) + : extern.createLegacyVariable( + name: def.key, + type: def.value, + fileOffset: offsetToUse ?? libraryBuilder.library.fileOffset, + ); if (isExtensionOrExtensionTypeInstanceMember && isExtensionThisName(def.key) && @@ -2253,7 +2259,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator { // The `#this` variable is special. extensionThis = variable..isLowered = true; } - return variable.astVariable; + return variable; }).toList(), ); diff --git a/pkg/front_end/lib/src/builder/formal_parameter_builder.dart b/pkg/front_end/lib/src/builder/formal_parameter_builder.dart index 9eb4b66ae14..f2e1650b670 100644 --- a/pkg/front_end/lib/src/builder/formal_parameter_builder.dart +++ b/pkg/front_end/lib/src/builder/formal_parameter_builder.dart @@ -422,7 +422,7 @@ class FormalParameterBuilder extends NamedBuilderImpl declaredType: variable.type, hasDeclaredInitializer: hasDeclaredInitializer, ); - variable.initializer = initializer..parent = variable; + variable.initializer = initializer..parent = variable.astVariable; if (initializer is InvalidExpression) { variable.isErroneouslyInitialized = true; } @@ -430,7 +430,7 @@ class FormalParameterBuilder extends NamedBuilderImpl } else if (kind.isOptional) { // As done by BodyBuilder.endFormalParameter. variable.initializer = extern.createNullLiteral(fileOffset: fileOffset) - ..parent = variable; + ..parent = variable.astVariable; } } } diff --git a/pkg/front_end/lib/src/fragment/field/declaration.dart b/pkg/front_end/lib/src/fragment/field/declaration.dart index 6732953a71c..63ac01d5b81 100644 --- a/pkg/front_end/lib/src/fragment/field/declaration.dart +++ b/pkg/front_end/lib/src/fragment/field/declaration.dart @@ -24,6 +24,7 @@ import '../../kernel/body_builder_context.dart'; import '../../kernel/hierarchy/class_member.dart'; import '../../kernel/hierarchy/members_builder.dart'; import '../../kernel/implicit_field_type.dart'; +import '../../kernel/internal_ast.dart'; import '../../kernel/late_lowering.dart' as late_lowering; import '../../kernel/macro/metadata.dart'; import '../../kernel/type_algorithms.dart'; @@ -947,7 +948,7 @@ abstract class FieldFragmentDeclaration { required CoreTypes coreTypes, required Uri fileUri, Expression? initializer, - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, }); BodyBuilderContext createBodyBuilderContext(); @@ -1003,7 +1004,7 @@ mixin FieldFragmentDeclarationMixin implements FieldFragmentDeclaration { required CoreTypes coreTypes, required Uri fileUri, Expression? initializer, - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, }) { if (_fieldInitializerCache != null) { if (!hasBodyBeenBuilt) { diff --git a/pkg/front_end/lib/src/kernel/assigned_variables_impl.dart b/pkg/front_end/lib/src/kernel/assigned_variables_impl.dart index 85385db4e3b..498f1f358ac 100644 --- a/pkg/front_end/lib/src/kernel/assigned_variables_impl.dart +++ b/pkg/front_end/lib/src/kernel/assigned_variables_impl.dart @@ -6,10 +6,13 @@ import 'package:_fe_analyzer_shared/src/type_inference/assigned_variables.dart'; import 'package:_fe_analyzer_shared/src/type_inference/promotion_key_store.dart'; import 'package:kernel/ast.dart'; -class AssignedVariablesImpl implements AssignedVariables { - final AssignedVariables _delegate; - final AssignedVariables? _insideAsserts; - final AssignedVariables? _outsideAsserts; +import 'internal_ast.dart'; + +class AssignedVariablesImpl + implements AssignedVariables { + final AssignedVariables _delegate; + final AssignedVariables? _insideAsserts; + final AssignedVariables? _outsideAsserts; int _assertDepth = 0; final Map? _deferredInsideAssertsByDeferredDelegate; @@ -18,10 +21,10 @@ class AssignedVariablesImpl implements AssignedVariables { new(this._delegate, {required bool isClosureContextLoweringEnabled}) : _insideAsserts = isClosureContextLoweringEnabled - ? new AssignedVariables() + ? new AssignedVariables() : null, _outsideAsserts = isClosureContextLoweringEnabled - ? new AssignedVariables() + ? new AssignedVariables() : null, _deferredInsideAssertsByDeferredDelegate = isClosureContextLoweringEnabled ? new Map< @@ -68,7 +71,7 @@ class AssignedVariablesImpl implements AssignedVariables { } @override - void declare(Variable variable, {bool ignoreDuplicates = false}) { + void declare(InternalVariable variable, {bool ignoreDuplicates = false}) { _delegate.declare(variable, ignoreDuplicates: ignoreDuplicates); _insideAsserts?.declare(variable, ignoreDuplicates: ignoreDuplicates); _outsideAsserts?.declare(variable, ignoreDuplicates: ignoreDuplicates); @@ -149,7 +152,7 @@ class AssignedVariablesImpl implements AssignedVariables { } @override - PromotionKeyStore get promotionKeyStore { + PromotionKeyStore get promotionKeyStore { return _delegate.promotionKeyStore; } @@ -161,7 +164,7 @@ class AssignedVariablesImpl implements AssignedVariables { } @override - void read(Variable variable) { + void read(InternalVariable variable) { _delegate.read(variable); if (_isInsideAssert) { _insideAsserts?.read(variable); @@ -199,7 +202,7 @@ class AssignedVariablesImpl implements AssignedVariables { } @override - void write(Variable variable) { + void write(InternalVariable variable) { _delegate.write(variable); if (_isInsideAssert) { // Coverage-ignore-block(suite): Not run. diff --git a/pkg/front_end/lib/src/kernel/body_builder.dart b/pkg/front_end/lib/src/kernel/body_builder.dart index 834df9c6f3f..5df49bc3c15 100644 --- a/pkg/front_end/lib/src/kernel/body_builder.dart +++ b/pkg/front_end/lib/src/kernel/body_builder.dart @@ -337,7 +337,7 @@ class BodyBuilderImpl extends StackListenerImpl /// If the current member is an instance member of a non-extension /// declaration, and the closure context lowering experiment is enabled, this /// field contains the variable representing `this`. - ThisVariable? _internalThisVariable; + InternalThisVariable? _internalThisVariable; final List? thisTypeParameters; @@ -370,7 +370,7 @@ class BodyBuilderImpl extends StackListenerImpl required this.typeEnvironment, required ConstantContext constantContext, required this.extensionScope, - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, }) : _context = context, benchmarker = libraryBuilder.loader.target.benchmarker, _localScopes = new LocalStack([enclosingScope]), @@ -380,13 +380,13 @@ class BodyBuilderImpl extends StackListenerImpl this.constantContext = constantContext; if (formalParameterScope != null) { for (VariableBuilder builder in formalParameterScope!.localVariables) { - assignedVariables.declare(builder.variable.astVariable); + assignedVariables.declare(builder.variable); } } if (thisVariable != null && context.isConstructor) { // The this variable is not part of the [formalParameterScope] in // constructors. - assignedVariables.declare(thisVariable.astVariable); + assignedVariables.declare(thisVariable); } if (isClosureContextLoweringEnabled && _internalThisVariable != null) { assignedVariables.declare(_internalThisVariable!); @@ -623,7 +623,7 @@ class BodyBuilderImpl extends StackListenerImpl // when [InferenceVisitorBase.flowAnalysis] will use // [InternalExpressionVariable] instead of [ExpressionVariable] (that is, // pass it for the `VariableDeclaration` type parameter of [FlowAnalysis]). - assignedVariables.write(variable.astVariable); + assignedVariables.write(variable); } @override @@ -632,7 +632,7 @@ class BodyBuilderImpl extends StackListenerImpl expression, isClosureContextLoweringEnabled: isClosureContextLoweringEnabled, ); - assignedVariables.declare(variable.astVariable); + assignedVariables.declare(variable); return variable; } @@ -1990,7 +1990,7 @@ class BodyBuilderImpl extends StackListenerImpl ]; for (InternalVariable variable in jointVariables) { declareVariable(variable, _localScope); - assignedVariables.declare(variable.astVariable); + assignedVariables.declare(variable); } push( intern.createOrPattern( @@ -2495,7 +2495,7 @@ class BodyBuilderImpl extends StackListenerImpl @override void registerVariableRead(InternalVariable variable) { if (!variable.isLocalFunction && !variable.isWildcard) { - assignedVariables.read(variable.astVariable); + assignedVariables.read(variable); } } @@ -3424,7 +3424,7 @@ class BodyBuilderImpl extends StackListenerImpl internalVariable, fileOffset: offsetForToken(equalsToken), ); - assignedVariables.declare(internalVariable.astVariable); + assignedVariables.declare(internalVariable); push(variableDeclaration); } @@ -3441,7 +3441,7 @@ class BodyBuilderImpl extends StackListenerImpl if (parameters != null) { Map local = {}; for (FormalParameterBuilder formal in parameters) { - assignedVariables.declare(formal.variable.astVariable); + assignedVariables.declare(formal.variable); local[formal.name] = formal; } _localScopes.push( @@ -3869,7 +3869,7 @@ class BodyBuilderImpl extends StackListenerImpl internalVariables.add(internalVariable); declareVariable(internalVariable, _localScope); - assignedVariables.declare(internalVariable.astVariable); + assignedVariables.declare(internalVariable); } push(intermediateVariables); push(internalVariables); @@ -5550,10 +5550,7 @@ class BodyBuilderImpl extends StackListenerImpl // previously passed to `declare` in the `BodyBuilder` constructor. // TODO(62401): Remove the cast when the flow analysis uses // [InternalExpressionVariable]s. - assignedVariables.declare( - functionParameter.astVariable, - ignoreDuplicates: true, - ); + assignedVariables.declare(functionParameter, ignoreDuplicates: true); } @override @@ -8071,7 +8068,7 @@ class BodyBuilderImpl extends StackListenerImpl _thisVariables.push(variable); _parameterlessAnonymousMethodDepth++; - assignedVariables.declare(variable.astVariable); + assignedVariables.declare(variable); push(NullValues.FormalParameters); } @@ -9032,7 +9029,7 @@ class BodyBuilderImpl extends StackListenerImpl for (InternalVariable jointVariable in jointPatternVariables) { assert(_localScope.kind == LocalScopeKind.jointVariables); declareVariable(jointVariable, _localScope); - assignedVariables.declare(jointVariable.astVariable); + assignedVariables.declare(jointVariable); } } } @@ -11104,7 +11101,7 @@ class BodyBuilderImpl extends StackListenerImpl declaredVariable, ); declareVariable(declaredVariable, _localScope); - assignedVariables.declare(declaredVariable.astVariable); + assignedVariables.declare(declaredVariable); } push(pattern); } @@ -11496,10 +11493,7 @@ class BodyBuilderImpl extends StackListenerImpl for (FormalParameterBuilder formal in formals) { // We pass `ignoreDuplicates: true` because the variable might have been // previously passed to `declare` in the `BodyBuilder` constructor. - assignedVariables.declare( - formal.variable.astVariable, - ignoreDuplicates: true, - ); + assignedVariables.declare(formal.variable, ignoreDuplicates: true); } } token = parser.parseInitializersOpt(token); @@ -11648,7 +11642,7 @@ class BodyBuilderImpl extends StackListenerImpl if (formals != null) { for (FormalParameterBuilder formalParameterBuilder in formals) { - assignedVariables.declare(formalParameterBuilder.variable.astVariable); + assignedVariables.declare(formalParameterBuilder.variable); } } @@ -11674,7 +11668,7 @@ class BodyBuilderImpl extends StackListenerImpl enterLocalScope(extraKnownVariablesScope); for (InternalVariable extraVariable in extraKnownVariables) { declareVariable(extraVariable, _localScope); - assignedVariables.declare(extraVariable.astVariable); + assignedVariables.declare(extraVariable); } } diff --git a/pkg/front_end/lib/src/kernel/body_builder_context.dart b/pkg/front_end/lib/src/kernel/body_builder_context.dart index 5ed7f182738..2982f9ee9c5 100644 --- a/pkg/front_end/lib/src/kernel/body_builder_context.dart +++ b/pkg/front_end/lib/src/kernel/body_builder_context.dart @@ -401,7 +401,7 @@ abstract class BodyBuilderContext { /// Declarations with synthesized `this`, such as extensions and extension /// types, don't have an internal [ThisVariable] because `this` is desugared /// as a parameter in that case. - ThisVariable? createInternalThisVariable() { + InternalThisVariable? createInternalThisVariable() { return thisType != null && isDeclarationInstanceContext ? intern.createThisVariable( type: thisType!, diff --git a/pkg/front_end/lib/src/kernel/external_ast_helper.dart b/pkg/front_end/lib/src/kernel/external_ast_helper.dart index 9679e489334..9f56eb313f7 100644 --- a/pkg/front_end/lib/src/kernel/external_ast_helper.dart +++ b/pkg/front_end/lib/src/kernel/external_ast_helper.dart @@ -109,12 +109,14 @@ AssertStatement createAssertStatement( AssignedVariablePattern createAssignedVariablePattern({ required Variable variable, + required Variable? setter, required DartType matchedValueType, required bool needsCast, required bool hasObservableEffect, required int fileOffset, }) { return new AssignedVariablePattern(variable) + ..setter = setter ..matchedValueType = matchedValueType ..needsCast = needsCast ..hasObservableEffect = hasObservableEffect @@ -601,6 +603,44 @@ LateVariable createLateVariable({ )..fileOffset = fileOffset; } +LegacyVariable createLegacyVariable({ + required String? name, + required DartType type, + bool isFinal = false, + bool isConst = false, + bool isWildcard = false, + bool isLate = false, + bool isInitializingFormal = false, + bool isSuperInitializingFormal = false, + bool isCovariantByDeclaration = false, + bool isRequired = false, + bool isLowered = false, + bool isSynthesized = false, + required int fileOffset, + int fileEqualsOffset = TreeNode.noOffset, + Expression? initializer, + bool hasDeclaredInitializer = false, +}) { + return new LegacyVariable( + name, + type: type, + isFinal: isFinal, + isConst: isConst, + isLate: isLate, + isWildcard: isWildcard, + isInitializingFormal: isInitializingFormal, + isSuperInitializingFormal: isSuperInitializingFormal, + isCovariantByDeclaration: isCovariantByDeclaration, + isRequired: isRequired, + isLowered: isLowered, + isSynthesized: isSynthesized, + initializer: initializer, + hasDeclaredInitializer: hasDeclaredInitializer, + ) + ..fileOffset = fileOffset + ..fileEqualsOffset = fileEqualsOffset; +} + /// Creates a [Let] of [variable] with the given [body] using /// `variable.fileOffset` as the file offset for the let. Let createLet(Variable variable, Expression body, {int? fileOffset}) { @@ -1326,9 +1366,10 @@ Expression createVariableSet( bool allowFinalAssignment = false, required int fileOffset, }) { - if (variable is VariableDeclarationImpl && variable.lateSetter != null) { + // TODO(johnniwinther): + if (variable.parent is FunctionDeclaration) { return createLocalFunctionInvocation( - variable.lateSetter!, + variable, arguments: createArguments([value], fileOffset: fileOffset), fileOffset: fileOffset, ); diff --git a/pkg/front_end/lib/src/kernel/internal_ast.dart b/pkg/front_end/lib/src/kernel/internal_ast.dart index afc0fe4af4a..4e6e4f8d455 100644 --- a/pkg/front_end/lib/src/kernel/internal_ast.dart +++ b/pkg/front_end/lib/src/kernel/internal_ast.dart @@ -21,7 +21,6 @@ library; import 'package:_fe_analyzer_shared/src/type_inference/type_analysis_result.dart' as shared; -import 'package:_fe_analyzer_shared/src/types/shared_type.dart'; import 'package:kernel/ast.dart'; import 'package:kernel/names.dart'; import 'package:kernel/src/printer.dart'; @@ -41,7 +40,12 @@ import 'external_ast_helper.dart' as extern; /// @docImport 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart'; typedef SharedMatchContext = - shared.MatchContext; + shared.MatchContext< + TreeNode, + Expression, + InternalPattern, + InternalVariable + >; mixin InternalTreeNode implements TreeNode { @override @@ -1150,11 +1154,11 @@ class ReturnStatementImpl extends ReturnStatement { } /// Front end specific implementation of [Variable]. -class VariableDeclarationImpl extends LegacyVariable - with InternalVariableMixin - implements InternalVariable { +class InternalLegacyVariable extends TreeNode + with InternalVariableMixin, DelegatingVariableMixin + implements LegacyVariable, InternalVariable { @override - Variable get astVariable => this; + final Variable astVariable; @override final bool forSyntheticToken; @@ -1165,69 +1169,22 @@ class VariableDeclarationImpl extends LegacyVariable @override final bool isLocalFunction; - new( - String? name, { + new({ + required this.astVariable, this.forSyntheticToken = false, - bool hasDeclaredInitializer = false, - Expression? initializer, - DartType? type, - bool isFinal = false, - bool isConst = false, - bool isInitializingFormal = false, - bool isSuperInitializingFormal = false, - bool isCovariantByDeclaration = false, + this.isImplicitlyTyped = false, bool isLocalFunction = false, - bool isLate = false, - bool isRequired = false, - bool isLowered = false, - bool isSynthesized = false, bool isStaticLate = false, - bool isWildcard = false, bool isLateFinalWithoutInitializer = false, required int fileOffset, int fileEqualsOffset = TreeNode.noOffset, - }) : isImplicitlyTyped = type == null, - isLocalFunction = isLocalFunction, - super( - name, - initializer: initializer, - type: type ?? const DynamicType(), - isFinal: isFinal, - isConst: isConst, - isInitializingFormal: isInitializingFormal, - isSuperInitializingFormal: isSuperInitializingFormal, - isCovariantByDeclaration: isCovariantByDeclaration, - isLate: isLate, - isRequired: isRequired, - isLowered: isLowered, - isSynthesized: isSynthesized, - hasDeclaredInitializer: hasDeclaredInitializer, - isWildcard: isWildcard, - ) { + }) : isLocalFunction = isLocalFunction { this.isStaticLate = isStaticLate; this.isLateFinalWithoutInitializer = isLateFinalWithoutInitializer; this.fileOffset = fileOffset; this.fileEqualsOffset = fileEqualsOffset; } - // Coverage-ignore(suite): Not run. - new forEffect(Expression initializer) - : forSyntheticToken = false, - isImplicitlyTyped = false, - isLocalFunction = false, - super.forValue(initializer) { - isStaticLate = false; - } - - // Coverage-ignore(suite): Not run. - new forValue(Expression initializer) - : forSyntheticToken = false, - isImplicitlyTyped = true, - isLocalFunction = false, - super.forValue(initializer) { - isStaticLate = false; - } - @override bool get isAssignable { if (isStaticLate) return true; @@ -1240,13 +1197,14 @@ class VariableDeclarationImpl extends LegacyVariable printer.writeVariableInitialization( this, isLate: isLate || lateGetter != null, + isImplicitlyTyped: isImplicitlyTyped, type: lateType ?? type, ); } @override String toString() { - return "VariableDeclarationImpl(${toStringInternal()})"; + return "$runtimeType(${toStringInternal()})"; } } @@ -1775,7 +1733,6 @@ mixin DelegatingVariableMixin on InternalVariableMixin String? get cosmeticName => astVariable.cosmeticName; @override - // Coverage-ignore(suite): Not run. TreeNode? get parent => astVariable.parent; @override @@ -1793,13 +1750,11 @@ mixin DelegatingVariableMixin on InternalVariableMixin } @override - // Coverage-ignore(suite): Not run. void addAnnotation(Expression node) { astVariable.addAnnotation(node); } @override - // Coverage-ignore(suite): Not run. void set cosmeticName(String? value) { astVariable.cosmeticName = value; } @@ -1824,7 +1779,6 @@ mixin DelegatingVariableMixin on InternalVariableMixin bool get isConst => astVariable.isConst; @override - // Coverage-ignore(suite): Not run. void set isConst(bool value) { astVariable.isConst = value; } @@ -1850,11 +1804,9 @@ mixin DelegatingVariableMixin on InternalVariableMixin } @override - // Coverage-ignore(suite): Not run. bool get isErroneouslyInitialized => astVariable.isErroneouslyInitialized; @override - // Coverage-ignore(suite): Not run. void set isErroneouslyInitialized(bool value) { astVariable.isErroneouslyInitialized = value; } @@ -1863,7 +1815,6 @@ mixin DelegatingVariableMixin on InternalVariableMixin bool get isFinal => astVariable.isFinal; @override - // Coverage-ignore(suite): Not run. void set isFinal(bool value) { astVariable.isFinal = value; } @@ -1901,7 +1852,6 @@ mixin DelegatingVariableMixin on InternalVariableMixin bool get isLowered => astVariable.isLowered; @override - // Coverage-ignore(suite): Not run. void set isLowered(bool value) { astVariable.isLowered = value; } @@ -1926,7 +1876,6 @@ mixin DelegatingVariableMixin on InternalVariableMixin } @override - // Coverage-ignore(suite): Not run. bool get isSynthesized => astVariable.isSynthesized; @override @@ -2158,13 +2107,11 @@ mixin DelegatingVariableMixin on InternalVariableMixin int get fileEqualsOffset => astVariable.fileEqualsOffset; @override - // Coverage-ignore(suite): Not run. void set fileEqualsOffset(int value) { astVariable.fileEqualsOffset = value; } @override - // Coverage-ignore(suite): Not run. Variable get variable => astVariable.variable; @override @@ -2174,7 +2121,6 @@ mixin DelegatingVariableMixin on InternalVariableMixin } @override - // Coverage-ignore(suite): Not run. void clearAnnotations() { astVariable.clearAnnotations(); } @@ -5938,6 +5884,8 @@ sealed class InternalForInElement { /// Base implementation for non-pattern for-in elements. sealed class _BaseForInElement extends InternalForInElement { + InternalVariable? get _declaredVariable => null; + /// Computes the type context from the element. This is type context used for /// inferring the for-in iterable. DartType _computeElementTypeContext(InferenceVisitorBase visitor); @@ -6004,6 +5952,7 @@ sealed class _BaseForInElement extends InternalForInElement { ); return new ForInHeaderResult( + declaredVariable: _declaredVariable, loopVariable: variable, iterable: iterableResult.expression, computeEncoding: () => _computeEncoding(visitor, loopVariable: variable), @@ -6028,6 +5977,9 @@ class SingleVariableDeclarationForInElement extends _BaseForInElement { new({required this.variableDeclaration, required this.error}); + @override + InternalVariable get _declaredVariable => variableDeclaration.variable; + @override Variable _computeLoopVariable( InferenceVisitorBase visitor, @@ -6035,6 +5987,7 @@ class SingleVariableDeclarationForInElement extends _BaseForInElement { required int forOffset, required bool isClosureContextLoweringEnabled, }) { + //InternalVariable internalLoopVariable = variableDeclaration.variable; Variable loopVariable = variableDeclaration.variable.astVariable; DartType loopVariableType; bool checkAssignment = true; @@ -6070,11 +6023,11 @@ class SingleVariableDeclarationForInElement extends _BaseForInElement { // and assign to the declared variable in the loop. loopVariable.initializer = assignmentResult.expression ..parent = loopVariable; - visitor.flowAnalysis.declare( - loopVariable, - new SharedTypeView(loopVariableType), - initialized: true, - ); + // visitor.flowAnalysis.declare( + // internalLoopVariable, + // new SharedTypeView(loopVariableType), + // initialized: true, + // ); _variableForSideEffect = extern.createVariableDeclaration(loopVariable); loopVariable = tempVariable; } @@ -6267,6 +6220,7 @@ class PatternForInElement extends InternalForInElement { inOffset: inOffset, ); return new ForInHeaderResult( + declaredVariable: null, loopVariable: data.loopVariable, iterable: data.iterable, computeEncoding: () => new ForInEncoding( @@ -6362,7 +6316,7 @@ class ExistingVariableForInElement extends _BaseForInElement { @override DartType _computeElementTypeContext(InferenceVisitorBase visitor) { DartType? promotedType = visitor.flowAnalysis - .promotedType(variable.astVariable) + .promotedType(variable) ?.unwrapTypeView(); return promotedType ?? variable.type; } @@ -6668,6 +6622,9 @@ class ForInEncoding { /// The result of inferring a for-in loop element and iterable. class ForInHeaderResult { + /// The [InternalVariable] declared in the for-in statement, if any. + final InternalVariable? declaredVariable; + /// The [Variable] that should be used as the variable in the /// emitted [ForInStatement]. final Variable loopVariable; @@ -6684,6 +6641,7 @@ class ForInHeaderResult { final ForInEncoding Function() computeEncoding; new({ + required this.declaredVariable, required this.loopVariable, required this.iterable, required this.computeEncoding, @@ -8459,6 +8417,43 @@ class InternalLet extends InternalExpression { } } +class InternalThisVariable extends TreeNode + with InternalVariableMixin, DelegatingVariableMixin + implements ThisVariable, InternalVariable { + @override + final ThisVariable astVariable; + + new({required this.astVariable, required int fileOffset}) { + this.fileOffset = fileOffset; + } + @override + // Coverage-ignore(suite): Not run. + String get cosmeticName => astVariable.cosmeticName; + + @override + // Coverage-ignore(suite): Not run. + bool get forSyntheticToken => false; + + @override + // Coverage-ignore(suite): Not run. + bool get isImplicitlyTyped => false; + + @override + // Coverage-ignore(suite): Not run. + bool get isLocalFunction => false; + + @override + // Coverage-ignore(suite): Not run. + void toTextInternal(AstPrinter printer) { + printer.write('this'); + } + + @override + String toString() { + return "$runtimeType(${toStringInternal()})"; + } +} + final InternalPattern dummyInternalPattern = new InternalConstantPattern( expression: dummyExpression, fileOffset: TreeNode.noOffset, @@ -8495,10 +8490,9 @@ final InternalCatch dummyInternalCatch = new InternalCatch( fileOffset: TreeNode.noOffset, ); -final InternalVariable dummyInternalVariable = new VariableDeclarationImpl( - null, +final InternalVariable dummyInternalVariable = new InternalLegacyVariable( + astVariable: dummyVariable, fileOffset: TreeNode.noOffset, - isSynthesized: true, ); final InternalVariableDeclaration dummyInternalVariableDeclaration = diff --git a/pkg/front_end/lib/src/kernel/internal_ast_helper.dart b/pkg/front_end/lib/src/kernel/internal_ast_helper.dart index 47a17e15bd4..9dbef53f6ea 100644 --- a/pkg/front_end/lib/src/kernel/internal_ast_helper.dart +++ b/pkg/front_end/lib/src/kernel/internal_ast_helper.dart @@ -211,13 +211,16 @@ InternalVariable createCatchVariable({ fileOffset: fileOffset, ); } else { - return new VariableDeclarationImpl( - name, + return new InternalLegacyVariable( + astVariable: extern.createLegacyVariable( + name: name, + type: type, + isWildcard: isWildcard, + isFinal: isFinal, + fileOffset: fileOffset, + ), fileOffset: fileOffset, - // [VariableDeclarationImpl] uses `null` to signal an omitted type. - type: isImplicitlyTyped ? null : type, - isWildcard: isWildcard, - isFinal: isFinal, + isImplicitlyTyped: isImplicitlyTyped, ); } } @@ -677,19 +680,24 @@ InternalVariable createLateVariable({ fileOffset: fileOffset, ); } else { - return new VariableDeclarationImpl( - name, + return new InternalLegacyVariable( + astVariable: extern.createLegacyVariable( + name: name, + fileOffset: fileOffset, + hasDeclaredInitializer: hasDeclaredInitializer, + initializer: initializer, + type: type ?? const DynamicType(), + isFinal: isFinal, + isConst: isConst, + isLate: true, + isWildcard: isWildcard, + fileEqualsOffset: fileEqualsOffset, + ), fileOffset: fileOffset, forSyntheticToken: forSyntheticToken, - hasDeclaredInitializer: hasDeclaredInitializer, - initializer: initializer, - type: type, - isFinal: isFinal, - isConst: isConst, - isLate: true, isStaticLate: isStaticLate, - isWildcard: isWildcard, fileEqualsOffset: fileEqualsOffset, + isImplicitlyTyped: isImplicitlyTyped, ); } } @@ -785,19 +793,24 @@ InternalVariable createLocalVariable({ fileEqualsOffset: fileEqualsOffset, ); } else { - return new VariableDeclarationImpl( - name, + return new InternalLegacyVariable( + astVariable: extern.createLegacyVariable( + name: name, + fileOffset: fileOffset, + hasDeclaredInitializer: hasDeclaredInitializer, + initializer: initializer, + type: type ?? const DynamicType(), + isFinal: isFinal, + isConst: isConst, + isWildcard: isWildcard, + fileEqualsOffset: fileEqualsOffset, + ), fileOffset: fileOffset, forSyntheticToken: forSyntheticToken, - hasDeclaredInitializer: hasDeclaredInitializer, - initializer: initializer, - type: type, - isFinal: isFinal, - isConst: isConst, isLocalFunction: isLocalFunction, isStaticLate: isStaticLate, - isWildcard: isWildcard, fileEqualsOffset: fileEqualsOffset, + isImplicitlyTyped: isImplicitlyTyped, ); } } @@ -961,22 +974,25 @@ InternalVariable createNamedParameter({ fileOffset: fileOffset, ); } else { - return new VariableDeclarationImpl( - parameterName, + return new InternalLegacyVariable( + astVariable: extern.createLegacyVariable( + name: parameterName, + fileOffset: fileOffset, + hasDeclaredInitializer: hasDeclaredDefaultValue, + initializer: defaultValue, + type: type, + isFinal: isFinal, + isInitializingFormal: isInitializingFormal, + isSuperInitializingFormal: isSuperInitializingFormal, + isCovariantByDeclaration: isCovariantByDeclaration, + isRequired: isRequired, + isLowered: isLowered, + isSynthesized: isSynthesized, + isWildcard: isWildcard, + ), fileOffset: fileOffset, forSyntheticToken: forSyntheticToken, - hasDeclaredInitializer: hasDeclaredDefaultValue, - initializer: defaultValue, - // [VariableDeclarationImpl] uses `null` to signal an omitted type. - type: isImplicitlyTyped ? null : type, - isFinal: isFinal, - isInitializingFormal: isInitializingFormal, - isSuperInitializingFormal: isSuperInitializingFormal, - isCovariantByDeclaration: isCovariantByDeclaration, - isRequired: isRequired, - isLowered: isLowered, - isSynthesized: isSynthesized, - isWildcard: isWildcard, + isImplicitlyTyped: isImplicitlyTyped, ); } } @@ -1232,23 +1248,25 @@ InternalVariable createPositionalParameter({ fileOffset: fileOffset, ); } else { - return new VariableDeclarationImpl( - cosmeticName, + return new InternalLegacyVariable( + astVariable: extern.createLegacyVariable( + name: cosmeticName, + fileOffset: fileOffset, + hasDeclaredInitializer: hasDeclaredDefaultValue, + initializer: defaultValue, + type: type, + isFinal: isFinal, + isInitializingFormal: isInitializingFormal, + isSuperInitializingFormal: isSuperInitializingFormal, + isCovariantByDeclaration: isCovariantByDeclaration, + isRequired: isRequired, + isLowered: isLowered, + isSynthesized: isSynthesized, + isWildcard: isWildcard, + ), fileOffset: fileOffset, forSyntheticToken: forSyntheticToken, - hasDeclaredInitializer: hasDeclaredDefaultValue, - initializer: defaultValue, - // [VariableDeclarationImpl] uses `null` to signal an omitted - // type. - type: isImplicitlyTyped ? null : type, - isFinal: isFinal, - isInitializingFormal: isInitializingFormal, - isSuperInitializingFormal: isSuperInitializingFormal, - isCovariantByDeclaration: isCovariantByDeclaration, - isRequired: isRequired, - isLowered: isLowered, - isSynthesized: isSynthesized, - isWildcard: isWildcard, + isImplicitlyTyped: isImplicitlyTyped, ); } } @@ -1524,14 +1542,18 @@ InternalVariable createSyntheticVariable({ fileOffset: fileOffset, ); } else { - return new VariableDeclarationImpl( - name, - type: type, - initializer: initializer, - isFinal: isFinal, - isSynthesized: isSynthesized, - hasDeclaredInitializer: initializer != null, + return new InternalLegacyVariable( + astVariable: extern.createLegacyVariable( + name: name, + type: type ?? const DynamicType(), + initializer: initializer, + isFinal: isFinal, + isSynthesized: isSynthesized, + hasDeclaredInitializer: initializer != null, + fileOffset: fileOffset, + ), fileOffset: fileOffset, + isImplicitlyTyped: type == null, ); } } @@ -1569,11 +1591,14 @@ Expression createThisExpression({required int fileOffset}) { return new ThisExpression()..fileOffset = fileOffset; } -ThisVariable createThisVariable({ +InternalThisVariable createThisVariable({ required DartType type, required int fileOffset, }) { - return new ThisVariable(type: type)..fileOffset = fileOffset; + return new InternalThisVariable( + astVariable: new ThisVariable(type: type)..fileOffset = fileOffset, + fileOffset: fileOffset, + ); } /// Return a representation of a throw expression at the given [fileOffset]. diff --git a/pkg/front_end/lib/src/kernel/resolver.dart b/pkg/front_end/lib/src/kernel/resolver.dart index c06c8e258b4..e5e7963dc36 100644 --- a/pkg/front_end/lib/src/kernel/resolver.dart +++ b/pkg/front_end/lib/src/kernel/resolver.dart @@ -5,7 +5,6 @@ import 'package:_fe_analyzer_shared/src/parser/parser.dart' show FormalParameterKind; import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token; -import 'package:_fe_analyzer_shared/src/type_inference/assigned_variables.dart'; import 'package:_fe_analyzer_shared/src/types/shared_type.dart'; import 'package:front_end/src/codes/diagnostic.dart' as diag; import 'package:kernel/ast.dart'; @@ -275,7 +274,7 @@ class Resolver { ConstantContext constantContext = bodyBuilderContext.constantContext; List? primaryConstructorInitializerScopeParameters = bodyBuilderContext.primaryConstructorInitializerScopeParameters; - ThisVariable? internalThisVariable = bodyBuilderContext + InternalThisVariable? internalThisVariable = bodyBuilderContext .createInternalThisVariable(); BodyBuilder bodyBuilder = _createBodyBuilder( context: context, @@ -404,7 +403,7 @@ class Resolver { functionBodyBuildingContext.inferenceDataForTesting, ); ConstantContext constantContext = bodyBuilderContext.constantContext; - ThisVariable? internalThisVariable = bodyBuilderContext + InternalThisVariable? internalThisVariable = bodyBuilderContext .createInternalThisVariable(); BodyBuilder bodyBuilder = _createBodyBuilder( context: context, @@ -476,7 +475,7 @@ class Resolver { ProblemReporting problemReporting = libraryBuilder; LibraryFeatures libraryFeatures = libraryBuilder.libraryFeatures; ConstantContext constantContext = bodyBuilderContext.constantContext; - ThisVariable? internalThisVariable = bodyBuilderContext + InternalThisVariable? internalThisVariable = bodyBuilderContext .createInternalThisVariable(); BodyBuilder bodyBuilder = _createBodyBuilder( context: context, @@ -689,7 +688,7 @@ class Resolver { functionBodyBuildingContext.inferenceDataForTesting, ); ConstantContext constantContext = bodyBuilderContext.constantContext; - ThisVariable? internalThisVariable = bodyBuilderContext + InternalThisVariable? internalThisVariable = bodyBuilderContext .createInternalThisVariable(); BodyBuilder bodyBuilder = _createBodyBuilder( context: context, @@ -768,7 +767,7 @@ class Resolver { ProblemReporting problemReporting = libraryBuilder; LibraryFeatures libraryFeatures = libraryBuilder.libraryFeatures; ConstantContext constantContext = bodyBuilderContext.constantContext; - ThisVariable? internalThisVariable = bodyBuilderContext + InternalThisVariable? internalThisVariable = bodyBuilderContext .createInternalThisVariable(); BodyBuilder bodyBuilder = _createBodyBuilder( context: context, @@ -874,7 +873,7 @@ class Resolver { required Procedure procedure, required List extraKnownVariables, required ExpressionEvaluationHelper expressionEvaluationHelper, - required InternalVariable? extensionThis, + required Variable? extensionThis, }) { _ResolverContext context = new _ResolverContext( typeInferenceEngine: _typeInferenceEngine, @@ -886,42 +885,30 @@ class Resolver { LibraryFeatures libraryFeatures = libraryBuilder.libraryFeatures; ConstantContext constantContext = bodyBuilderContext.constantContext; - ThisVariable? internalThisVariable = bodyBuilderContext + InternalThisVariable? internalThisVariable = bodyBuilderContext .createInternalThisVariable(); - BodyBuilder bodyBuilder = _createBodyBuilder( - context: context, - bodyBuilderContext: bodyBuilderContext, - scope: scope, - thisVariable: extensionThis, - constantContext: constantContext, - // TODO(johnniwinther): Should we provide these? - thisTypeParameters: null, - formalParameterScope: null, - internalThisVariable: internalThisVariable, - ); - int fileOffset = token.charOffset; FunctionNode parameters = procedure.function; - - List? typeParameterBuilders; - for (TypeParameter typeParameter in parameters.typeParameters) { - typeParameterBuilders ??= []; - typeParameterBuilders.add( - new DillNominalParameterBuilder( - typeParameter, - loader: libraryBuilder.loader, - ), - ); - } int wildcardVariableIndex = 0; + InternalVariable? internalExtensionThis; List? formals = parameters.positionalParameters.length == 0 ? null : new List.generate( parameters.positionalParameters.length, (int i) { + Variable parameter = parameters.positionalParameters[i]; InternalVariable formal = - parameters.positionalParameters[i] as InternalVariable; + libraryBuilder.loader.isClosureContextLoweringEnabled + ? new InternalPositionalParameter( + astVariable: parameter as PositionalParameter, + isImplicitlyTyped: false, + fileOffset: parameter.fileOffset, + ) + : new InternalLegacyVariable( + astVariable: parameter, + fileOffset: parameter.fileOffset, + ); String formalName = formal.cosmeticName!; bool isWildcard = libraryFeatures.wildcardVariables.isEnabled && @@ -930,6 +917,9 @@ class Resolver { if (isWildcard) { wildcardIndex = wildcardVariableIndex++; } + if (parameter == extensionThis) { + internalExtensionThis = formal; + } return new FormalParameterBuilder( kind: FormalParameterKind.requiredPositional, modifiers: Modifiers.empty, @@ -948,6 +938,30 @@ class Resolver { growable: false, ); + BodyBuilder bodyBuilder = _createBodyBuilder( + context: context, + bodyBuilderContext: bodyBuilderContext, + scope: scope, + thisVariable: internalExtensionThis, + constantContext: constantContext, + // TODO(johnniwinther): Should we provide these? + thisTypeParameters: null, + formalParameterScope: null, + internalThisVariable: internalThisVariable, + ); + int fileOffset = token.charOffset; + + List? typeParameterBuilders; + for (TypeParameter typeParameter in parameters.typeParameters) { + typeParameterBuilders ??= []; + typeParameterBuilders.add( + new DillNominalParameterBuilder( + typeParameter, + loader: libraryBuilder.loader, + ), + ); + } + BuildSingleExpressionResult result = bodyBuilder.buildSingleExpression( token: token, extraKnownVariables: extraKnownVariables, @@ -960,7 +974,7 @@ class Resolver { for (int i = 0; i < formals.length; i++) { InternalVariable variable = formals[i].variable; context.typeInferrer.flowAnalysis.declare( - variable.astVariable, + variable, new SharedTypeView(variable.type), initialized: true, ); @@ -968,7 +982,7 @@ class Resolver { } for (InternalVariable extraVariable in extraKnownVariables) { context.typeInferrer.flowAnalysis.declare( - extraVariable.astVariable, + extraVariable, new SharedTypeView(extraVariable.type), initialized: true, ); @@ -1129,7 +1143,7 @@ class Resolver { required InternalVariable? thisVariable, required List? thisTypeParameters, required LocalScope? formalParameterScope, - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, }) { _benchmarker // Coverage-ignore(suite): Not run. @@ -1158,7 +1172,7 @@ class Resolver { required InternalVariable? thisVariable, required List? thisTypeParameters, required ConstantContext constantContext, - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, }) { return new BodyBuilderImpl( libraryBuilder: context.libraryBuilder, @@ -1179,7 +1193,7 @@ class Resolver { } _SuperParameterArguments? _createSuperParameterArguments({ - required AssignedVariables assignedVariables, + required AssignedVariablesImpl assignedVariables, required List? formals, }) { if (formals == null) { @@ -1232,12 +1246,12 @@ class Resolver { /// Helper method to create a [VariableGet] of the [variable] using /// [fileOffset] as the file offset. Expression _createVariableGet({ - required AssignedVariables assignedVariables, + required AssignedVariablesImpl assignedVariables, required InternalVariable variable, required int fileOffset, }) { if (!variable.isLocalFunction && !variable.isWildcard) { - assignedVariables.read(variable.astVariable); + assignedVariables.read(variable); } return intern.createVariableGet(variable, fileOffset: fileOffset); } @@ -1252,7 +1266,7 @@ class Resolver { // `thisVariable` usually appears in `_context.formals`, but for a // constructor, it doesn't. So declare it separately. typeInferrer.flowAnalysis.declare( - thisVariable.astVariable, + thisVariable, new SharedTypeView(thisVariable.type), initialized: true, ); @@ -1264,7 +1278,7 @@ class Resolver { // TODO(62401): Remove the cast when the flow analysis uses // [InternalExpressionVariable]s. typeInferrer.flowAnalysis.declare( - variable.astVariable, + variable, new SharedTypeView(variable.type), initialized: true, ); @@ -1287,7 +1301,7 @@ class Resolver { required List initializers, required bool forPrimaryConstructor, required List parameters, - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, required ContextAllocationStrategy contextAllocationStrategy, }) { _InitializerBuilder initializerBuilder = new _InitializerBuilder( @@ -1354,10 +1368,10 @@ class Resolver { required InternalVariable? thisVariable, required List initializers, required ConstantContext constantContext, - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, required bool forPrimaryConstructor, }) { - AssignedVariables assignedVariables = context.assignedVariables; + AssignedVariablesImpl assignedVariables = context.assignedVariables; // Create variable get expressions for super parameters before finishing // the analysis of the assigned variables. Creating the expressions later diff --git a/pkg/front_end/lib/src/kernel/resolver_helpers.dart b/pkg/front_end/lib/src/kernel/resolver_helpers.dart index 3567db10501..1a7e88c4f3f 100644 --- a/pkg/front_end/lib/src/kernel/resolver_helpers.dart +++ b/pkg/front_end/lib/src/kernel/resolver_helpers.dart @@ -42,7 +42,7 @@ class ResolverForTesting extends Resolver { required InternalVariable? thisVariable, required List? thisTypeParameters, required ConstantContext constantContext, - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, }) { return bodyBuilderCreator( libraryBuilder: context.libraryBuilder, @@ -218,7 +218,7 @@ class _InitializerBuilder { ScopeProviderInfo? _inferInitializers( List initializers, { required List parameters, - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, required ContextAllocationStrategy contextAllocationStrategy, required bool isConstructorWithoutBody, }) { @@ -248,7 +248,7 @@ class _InitializerBuilder { required AsyncModifier asyncModifier, required bool forPrimaryConstructor, required List parameters, - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, required ContextAllocationStrategy contextAllocationStrategy, required bool isConstructorWithoutBody, }) { @@ -603,7 +603,7 @@ class _InitializerBuilder { required TypeInferrer typeInferrer, required _SuperParameterArguments? superParameterArguments, required List parameters, - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, required ScopeProviderInfo? scopeProviderInfo, required ContextAllocationStrategy contextAllocationStrategy, required bool isFirstInitializer, diff --git a/pkg/front_end/lib/src/source/source_loader.dart b/pkg/front_end/lib/src/source/source_loader.dart index 77bb9b1a489..975f58c0625 100644 --- a/pkg/front_end/lib/src/source/source_loader.dart +++ b/pkg/front_end/lib/src/source/source_loader.dart @@ -1490,7 +1490,7 @@ severity: $severity String? enclosingClassOrExtension, bool isClassInstanceMember, Procedure procedure, - InternalVariable? extensionThis, + Variable? extensionThis, List extraKnownVariables, ExpressionEvaluationHelper expressionEvaluationHelper, ) async { diff --git a/pkg/front_end/lib/src/type_inference/inference_visitor.dart b/pkg/front_end/lib/src/type_inference/inference_visitor.dart index cfc39669659..444593b28d3 100644 --- a/pkg/front_end/lib/src/type_inference/inference_visitor.dart +++ b/pkg/front_end/lib/src/type_inference/inference_visitor.dart @@ -130,13 +130,13 @@ class InferenceVisitorImpl extends InferenceVisitorBase TreeNode, Statement, Expression, - Variable, + InternalVariable, InternalPattern, InvalidExpression, TypeDeclarationType, TypeDeclaration >, - NullShortingMixin, + NullShortingMixin, StackChecker, ExpressionVisitor1ExperimentExclusionMixin< ExpressionInferenceResult, @@ -354,7 +354,6 @@ class InferenceVisitorImpl extends InferenceVisitorBase new NullAwareGuard(variable, variable.fileOffset, this), flowAnalysis.getExpressionInfo(variable.initializer!), new SharedTypeView(variable.type), - guardVariable: variable, ), ); } @@ -1364,7 +1363,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase flowAnalysis.getExpressionInfo(result.expression), new SharedTypeView(result.inferredType), isNullAware: node.isNullAware, - guardVariable: node.variable.astVariable, + guardVariable: node.variable, ); Cascade? previousEnclosingCascade = _enclosingCascade; @@ -3402,17 +3401,29 @@ class InferenceVisitorImpl extends InferenceVisitorBase flowAnalysis.forEach_bodyBegin(node); - flowAnalysis.declare( - variable, - new SharedTypeView(variable.type), - initialized: true, - ); - - if (isClosureContextLoweringEnabled) { - _contextAllocationStrategy.handleDeclarationOfVariable( - variable, - captureKind: _captureKindForVariable(variable), + InternalVariable? declaredVariable = headerResult.declaredVariable; + if (declaredVariable != null) { + flowAnalysis.declare( + declaredVariable, + new SharedTypeView(declaredVariable.type), + initialized: true, ); + + if (isClosureContextLoweringEnabled) { + _contextAllocationStrategy.handleDeclarationOfVariable( + declaredVariable.astVariable, + captureKind: _captureKindForVariable(declaredVariable), + ); + } + } + if (isClosureContextLoweringEnabled) { + if (declaredVariable?.astVariable != variable) { + // [variable] is synthesized. + _contextAllocationStrategy.handleDeclarationOfVariable( + variable, + captureKind: CaptureKind.notCaptured, + ); + } } ForInEncoding encoding = headerResult.computeEncoding(); @@ -3590,7 +3601,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase if (isClosureContextLoweringEnabled) { _contextAllocationStrategy.handleDeclarationOfVariable( node.variable.astVariable, - captureKind: _captureKindForVariable(node.variable.astVariable), + captureKind: _captureKindForVariable(node.variable), ); capturedContexts = _contextAllocationStrategy .computeCapturedVariableContexts(_capturedVariablesForNode(node)); @@ -3627,7 +3638,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase } variable.type = inferredType; flowAnalysis.declare( - variable.astVariable, + variable, new SharedTypeView(variable.type), initialized: true, ); @@ -3650,6 +3661,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase ); libraryBuilder.loader.dataForTesting // Coverage-ignore(suite): Not run. + ?.registerAlias(variable, variable.astVariable); + libraryBuilder.loader.dataForTesting + // Coverage-ignore(suite): Not run. ?.registerAlias(node, replacement); return new StatementInferenceResult.single(replacement); } @@ -3657,7 +3671,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase @override ScopeProviderInfo beginClosureContextAllocation( List parameters, { - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, required ScopeProviderInfo? scopeProviderInfo, }) { scopeProviderInfo ??= _contextAllocationStrategy.enterScopeProvider( @@ -3667,7 +3681,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase ); if (internalThisVariable != null) { _contextAllocationStrategy.handleDeclarationOfVariable( - internalThisVariable, + internalThisVariable.astVariable, captureKind: _captureKindForVariable(internalThisVariable), ); } @@ -3682,10 +3696,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase void _handleDeclarationsOfParameters(List parameters) { for (InternalVariable parameter in parameters) { - Variable parameterAstVariable = parameter.astVariable; _contextAllocationStrategy.handleDeclarationOfVariable( - parameterAstVariable, - captureKind: _captureKindForVariable(parameterAstVariable), + parameter.astVariable, + captureKind: _captureKindForVariable(parameter), ); } } @@ -3911,7 +3924,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase { for (InternalVariable variable in node.patternGuard.pattern.declaredVariables) - variable.cosmeticName!: variable.astVariable, + variable.cosmeticName!: variable, }, ); @@ -4334,7 +4347,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase variables: { for (InternalVariable variable in element.internalPatternGuard.pattern.declaredVariables) - variable.cosmeticName!: variable.astVariable, + variable.cosmeticName!: variable, }, guard: element.internalPatternGuard.guard, ifTrue: element.then, @@ -4601,16 +4614,29 @@ class InferenceVisitorImpl extends InferenceVisitorBase flowAnalysis.forEach_bodyBegin(node); - flowAnalysis.declare( - variable, - new SharedTypeView(variable.type), - initialized: true, - ); - if (isClosureContextLoweringEnabled) { - _contextAllocationStrategy.handleDeclarationOfVariable( - variable, - captureKind: _captureKindForVariable(variable), + InternalVariable? declaredVariable = result.declaredVariable; + if (declaredVariable != null) { + flowAnalysis.declare( + declaredVariable, + new SharedTypeView(declaredVariable.type), + initialized: true, ); + if (isClosureContextLoweringEnabled) { + _contextAllocationStrategy.handleDeclarationOfVariable( + declaredVariable.astVariable, + captureKind: _captureKindForVariable(declaredVariable), + ); + } + } + if (isClosureContextLoweringEnabled) { + if (declaredVariable?.astVariable != variable) { + // Coverage-ignore-block(suite): Not run. + // [variable] is synthesized. + _contextAllocationStrategy.handleDeclarationOfVariable( + variable, + captureKind: CaptureKind.notCaptured, + ); + } } node.encoding = result.computeEncoding(); @@ -7486,7 +7512,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase variables: { for (InternalVariable variable in entry.internalPatternGuard.pattern.declaredVariables) - variable.cosmeticName!: variable.astVariable, + variable.cosmeticName!: variable, }, guard: entry.internalPatternGuard.guard, ifTrue: entry.then, @@ -7807,18 +7833,30 @@ class InferenceVisitorImpl extends InferenceVisitorBase flowAnalysis.forEach_bodyBegin(node); - flowAnalysis.declare( - variable, - new SharedTypeView(variable.type), - initialized: true, - ); - if (isClosureContextLoweringEnabled) { - _contextAllocationStrategy.handleDeclarationOfVariable( - variable, - captureKind: _captureKindForVariable(variable), + InternalVariable? declaredVariable = result.declaredVariable; + if (declaredVariable != null) { + flowAnalysis.declare( + declaredVariable, + new SharedTypeView(declaredVariable.type), + initialized: true, ); + if (isClosureContextLoweringEnabled) { + _contextAllocationStrategy.handleDeclarationOfVariable( + declaredVariable.astVariable, + captureKind: _captureKindForVariable(declaredVariable), + ); + } + } + if (isClosureContextLoweringEnabled) { + if (declaredVariable?.astVariable != variable) { + // Coverage-ignore-block(suite): Not run. + // [variable] is synthesized. + _contextAllocationStrategy.handleDeclarationOfVariable( + variable, + captureKind: CaptureKind.notCaptured, + ); + } } - node.encoding = result.computeEncoding(); // Actual types are added by the recursive call. @@ -11975,12 +12013,12 @@ class InferenceVisitorImpl extends InferenceVisitorBase node.variable.initializer = initializer..parent = node.variable; flowAnalysis.declare( - node.variable.astVariable, + node.variable, new SharedTypeView(node.variable.type), initialized: false, ); flowAnalysis.initialize( - node.variable.astVariable, + node.variable, new SharedTypeView(node.variable.type), flowAnalysis.getExpressionInfo(node.variable.initializer!), isFinal: false, @@ -11992,7 +12030,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase flow.nullAwareAccess_rightBegin( flowAnalysis.getExpressionInfo(node.variable.initializer!), new SharedTypeView(initializerType), - guardVariable: node.variable.astVariable, + guardVariable: node.variable, ); } @@ -12168,12 +12206,12 @@ class InferenceVisitorImpl extends InferenceVisitorBase node.variable.initializer = initializer..parent = node.variable; flowAnalysis.declare( - node.variable.astVariable, + node.variable, new SharedTypeView(node.variable.type), initialized: false, ); flowAnalysis.initialize( - node.variable.astVariable, + node.variable, new SharedTypeView(node.variable.type), flowAnalysis.getExpressionInfo(node.variable.initializer!), isFinal: false, @@ -12204,7 +12242,6 @@ class InferenceVisitorImpl extends InferenceVisitorBase new NullAwareGuard(tempVar!, node.variable.fileOffset, this), flowAnalysis.getExpressionInfo(tempVar.initializer!), new SharedTypeView(tempVar.type), - guardVariable: tempVar, ); } } @@ -13624,8 +13661,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase Catch visitCatch(InternalCatch node) { ScopeProviderInfo? scopeProviderInfo; - Variable? exception = node.exception?.astVariable; - Variable? stackTrace = node.stackTrace?.astVariable; + InternalVariable? exception = node.exception; + InternalVariable? stackTrace = node.stackTrace; if (isClosureContextLoweringEnabled) { scopeProviderInfo = _contextAllocationStrategy.enterScopeProvider( scopeProviderInfoKind: ScopeProviderInfoKind.Catch, @@ -13634,7 +13671,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase // TODO(62401): Remove the casts when the flow analysis uses // [InternalExpressionVariable]s. _contextAllocationStrategy.handleDeclarationOfVariable( - exception, + exception.astVariable, captureKind: _captureKindForVariable(exception), ); } @@ -13642,7 +13679,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase // TODO(62401): Remove the casts when the flow analysis uses // [InternalExpressionVariable]s. _contextAllocationStrategy.handleDeclarationOfVariable( - stackTrace, + stackTrace.astVariable, captureKind: _captureKindForVariable(stackTrace), ); } @@ -13656,8 +13693,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase } return extern.createCatch( guard: node.guard, - exception: exception, - stackTrace: stackTrace, + exception: exception?.astVariable, + stackTrace: stackTrace?.astVariable, body: body, scope: scope, fileOffset: node.fileOffset, @@ -13685,8 +13722,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase // TODO(62401): Remove the casts when the flow analysis uses // [InternalExpressionVariable]s. flowAnalysis.tryCatchStatement_catchBegin( - catchBlock.exception?.astVariable, - catchBlock.stackTrace?.astVariable, + catchBlock.exception, + catchBlock.stackTrace, ); catchBlocks.add(visitCatch(catchBlock)); flowAnalysis.tryCatchStatement_catchEnd(); @@ -13791,7 +13828,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase if (isClosureContextLoweringEnabled) { _contextAllocationStrategy.handleDeclarationOfVariable( node.variable.astVariable, - captureKind: _captureKindForVariable(node.variable.astVariable), + captureKind: _captureKindForVariable(node.variable), ); } return variableDeclarationInferenceResult; @@ -14506,9 +14543,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase case InternalAndPattern(): return analyzeLogicalAndPatternSchema(node.left, node.right); case InternalAssignedVariablePattern(): - return analyzeAssignedVariablePatternSchema( - node.variable.astVariable, - ); + return analyzeAssignedVariablePatternSchema(node.variable); case InternalCastPattern(): return analyzeCastPatternSchema(); case InternalConstantPattern(): @@ -14818,21 +14853,25 @@ class InferenceVisitorImpl extends InferenceVisitorBase } @override - FlowAnalysis get flow => + FlowAnalysis get flow => flowAnalysis; @override - SwitchExpressionMemberInfo + SwitchExpressionMemberInfo getSwitchExpressionMemberInfo(Expression node, int index) { InternalSwitchExpressionCase switchExpressionCase = (node as InternalSwitchExpression).cases[index]; InternalPattern pattern = switchExpressionCase.patternGuard.pattern; - Map variables = { + Map variables = { for (InternalVariable declaredVariable in pattern.declaredVariables) - declaredVariable.cosmeticName!: declaredVariable.astVariable, + declaredVariable.cosmeticName!: declaredVariable, }; - return new SwitchExpressionMemberInfo( - head: new CaseHeadOrDefaultInfo( + return new SwitchExpressionMemberInfo< + TreeNode, + Expression, + InternalVariable + >( + head: new CaseHeadOrDefaultInfo( pattern: pattern, guard: switchExpressionCase.patternGuard.guard, variables: variables, @@ -14842,7 +14881,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase } @override - SwitchStatementMemberInfo + SwitchStatementMemberInfo getSwitchStatementMemberInfo( covariant InternalSwitchStatement node, int caseIndex, @@ -14872,7 +14911,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase variables: { for (InternalVariable variable in patternGuard.pattern.declaredVariables) - variable.cosmeticName!: variable.astVariable, + variable.cosmeticName!: variable, }, ), if (case_.isDefault) @@ -14881,7 +14920,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase body: [case_.body], variables: { for (InternalVariable jointVariable in case_.jointVariables) - jointVariable.cosmeticName!: jointVariable.astVariable, + jointVariable.cosmeticName!: jointVariable, }, hasLabels: case_.hasLabel, ); @@ -15003,7 +15042,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase void handleCase_afterCaseHeads( Statement node, int caseIndex, - Iterable variables, + Iterable variables, ) {} @override @@ -15079,7 +15118,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase } @override - void setVariableType(Variable variable, SharedTypeView type) { + void setVariableType(InternalVariable variable, SharedTypeView type) { variable.type = type.unwrapTypeView(); } @@ -15111,7 +15150,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase analyzeDeclaredVariablePattern( context, node, - node.variable.astVariable, + node.variable, node.variableName, node.type?.wrapSharedTypeView(), ); @@ -16425,10 +16464,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase // TODO(johnniwinther): Share this through the type analyzer. Pattern? replacement; InternalVariable variable = node.variable; - bool isDefinitelyAssigned = flowAnalysis.isAssigned(variable.astVariable); - bool isDefinitelyUnassigned = flowAnalysis.isUnassigned( - variable.astVariable, - ); + bool isDefinitelyAssigned = flowAnalysis.isAssigned(variable); + bool isDefinitelyUnassigned = flowAnalysis.isUnassigned(variable); if ((variable.isLate && variable.isFinal) || variable.isLateFinalWithoutInitializer) { if (isDefinitelyAssigned) { @@ -16479,11 +16516,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase } AssignedVariablePatternResult analysisResult = - analyzeAssignedVariablePattern( - context, - node, - node.variable.astVariable, - ); + analyzeAssignedVariablePattern(context, node, node.variable); DartType matchedValueType = analysisResult.matchedValueType .unwrapTypeView(); @@ -16507,6 +16540,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase replacement ?? extern.createAssignedVariablePattern( variable: node.variable.astVariable, + setter: node.variable.lateSetter, matchedValueType: matchedValueType, needsCast: needsCast, hasObservableEffect: hasObservableEffect, @@ -16725,7 +16759,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase @override void finishJoinedPatternVariable( - Variable variable, { + InternalVariable variable, { required JoinedPatternVariableLocation location, required JoinedPatternVariableInconsistency inconsistency, required bool isFinal, @@ -17363,7 +17397,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase return node is DotShorthand; } - CaptureKind _captureKindForVariable(Variable variable) { + CaptureKind _captureKindForVariable(InternalVariable variable) { int variableKey = assignedVariables.promotionKeyStore.keyForVariable( variable, ); @@ -17384,12 +17418,16 @@ class InferenceVisitorImpl extends InferenceVisitorBase AssignedVariablesNodeInfo nodeInfo = assignedVariables.getInfoForNode(node); for (int variableKey in nodeInfo.read) { capturedVariables.add( - assignedVariables.promotionKeyStore.variableForKey(variableKey)!, + assignedVariables.promotionKeyStore + .variableForKey(variableKey)! + .astVariable, ); } for (int variableKey in nodeInfo.written) { capturedVariables.add( - assignedVariables.promotionKeyStore.variableForKey(variableKey)!, + assignedVariables.promotionKeyStore + .variableForKey(variableKey)! + .astVariable, ); } return capturedVariables; @@ -17466,14 +17504,14 @@ class InferenceVisitorImpl extends InferenceVisitorBase internalVariable.type = inferredType; } flowAnalysis.declare( - internalVariable.astVariable, + internalVariable, new SharedTypeView(internalVariable.type), initialized: internalVariable.hasDeclaredInitializer, ); if (initializerResult != null) { DartType initializerType = initializerResult.inferredType; flowAnalysis.initialize( - internalVariable.astVariable, + internalVariable, new SharedTypeView(initializerType), flowAnalysis.getExpressionInfo(initializerResult.expression), isFinal: internalVariable.isFinal, @@ -17682,6 +17720,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase fileOffset: internalVariable.fileOffset, ); } + libraryBuilder.loader.dataForTesting + // Coverage-ignore(suite): Not run. + ?.registerAlias(internalVariable, internalVariable.astVariable); return new VariableDeclarationInferenceResult.direct( extern.createVariableDeclaration( internalVariable.astVariable, @@ -17693,7 +17734,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase @override ScopeProviderInfo beginFieldInference({ - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, }) { ScopeProviderInfo scopeProviderInfo = _contextAllocationStrategy .enterScopeProvider( @@ -17703,7 +17744,7 @@ class InferenceVisitorImpl extends InferenceVisitorBase ); if (internalThisVariable != null) { _contextAllocationStrategy.handleDeclarationOfVariable( - internalThisVariable, + internalThisVariable.astVariable, captureKind: _captureKindForVariable(internalThisVariable), ); } diff --git a/pkg/front_end/lib/src/type_inference/inference_visitor_base.dart b/pkg/front_end/lib/src/type_inference/inference_visitor_base.dart index 225ce284660..28eb5cff72b 100644 --- a/pkg/front_end/lib/src/type_inference/inference_visitor_base.dart +++ b/pkg/front_end/lib/src/type_inference/inference_visitor_base.dart @@ -159,8 +159,8 @@ abstract class InferenceVisitorBase implements InferenceVisitor { InferenceDataForTesting? get dataForTesting => _inferrer.dataForTesting; - FlowAnalysis get flowAnalysis => - _inferrer.flowAnalysis; + FlowAnalysis + get flowAnalysis => _inferrer.flowAnalysis; /// Provides access to the [OperationsCfe] object. This is needed by /// [isAssignable] and for caching types. @@ -2302,7 +2302,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { for (InternalVariable parameter in function.positionalParameters) { flowAnalysis.declare( - parameter.astVariable, + parameter, new SharedTypeView(parameter.type), initialized: true, ); @@ -2318,7 +2318,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { } for (InternalVariable parameter in function.namedParameters) { flowAnalysis.declare( - parameter.astVariable, + parameter, new SharedTypeView(parameter.type), initialized: true, ); @@ -2398,6 +2398,22 @@ abstract class InferenceVisitorBase implements InferenceVisitor { for (InternalVariable parameter in function.namedParameters) parameter.astVariable, ]; + if (libraryBuilder.loader.dataForTesting != null) { + // Coverage-ignore-block(suite): Not run. + for (InternalVariable parameter in function.positionalParameters) { + libraryBuilder.loader.dataForTesting?.registerAlias( + parameter, + parameter.astVariable, + ); + } + for (InternalVariable parameter in function.namedParameters) { + libraryBuilder.loader.dataForTesting?.registerAlias( + parameter, + parameter.astVariable, + ); + } + } + return new LocalFunctionResult( returnType: returnType, positionalParameters: positionalParameters, @@ -4164,7 +4180,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { // Don't promote local functions. SharedTypeView? wrappedPromotedType; (wrappedPromotedType, expressionInfo) = flowAnalysis.variableRead( - variable.astVariable, + variable, ); promotedType = wrappedPromotedType?.unwrapTypeView(); } @@ -4191,7 +4207,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { resultExpression = result..variable = variable.astVariable; } - bool isUnassigned = !flowAnalysis.isAssigned(variable.astVariable); + bool isUnassigned = !flowAnalysis.isAssigned(variable); if (isUnassigned) { dataForTesting // Coverage-ignore(suite): Not run. @@ -4199,9 +4215,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { .potentiallyUnassignedNodes // Coverage-ignore(suite): Not run. .add(result); } - bool isDefinitelyUnassigned = flowAnalysis.isUnassigned( - variable.astVariable, - ); + bool isDefinitelyUnassigned = flowAnalysis.isUnassigned(variable); if (isDefinitelyUnassigned) { dataForTesting // Coverage-ignore(suite): Not run. @@ -4275,7 +4289,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { computeVariableSetTypeAndWriteContext(InternalVariable variable) { DartType declaredOrInferredType = variable.lateType ?? variable.type; DartType? promotedType = flowAnalysis - .promotedType(variable.astVariable) + .promotedType(variable) ?.unwrapTypeView(); return (declaredOrInferredType, promotedType ?? declaredOrInferredType); } @@ -4292,10 +4306,8 @@ abstract class InferenceVisitorBase implements InferenceVisitor { required int assignOffset, required int nameOffset, }) { - bool isDefinitelyAssigned = flowAnalysis.isAssigned(variable.astVariable); - bool isDefinitelyUnassigned = flowAnalysis.isUnassigned( - variable.astVariable, - ); + bool isDefinitelyAssigned = flowAnalysis.isAssigned(variable); + bool isDefinitelyUnassigned = flowAnalysis.isUnassigned(variable); rhsResult = ensureAssignableResult( variableType, rhsResult, @@ -4309,7 +4321,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { result, flowAnalysis.write( result, - variable.astVariable, + variable, new SharedTypeView(rhsResult.inferredType), flowAnalysis.getExpressionInfo(rhsResult.expression), ), @@ -5576,7 +5588,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { /// [parameters] are those of the function being inferred. ScopeProviderInfo beginClosureContextAllocation( List parameters, { - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, required ScopeProviderInfo? scopeProviderInfo, }); @@ -5585,7 +5597,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { /// Performs preliminary computations before inferring the field initializer. ScopeProviderInfo beginFieldInference({ - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, }); /// Finishes computations after inferring the field initializer. @@ -5653,7 +5665,12 @@ FunctionType replaceReturnType(FunctionType functionType, DartType returnType) { } class _WhyNotPromotedVisitor - implements NonPromotionReasonVisitor, Node, Variable> { + implements + NonPromotionReasonVisitor< + List, + Node, + InternalVariable + > { final InferenceVisitorBase inferrer; Member? propertyReference; @@ -5662,7 +5679,7 @@ class _WhyNotPromotedVisitor @override List visitDemoteViaExplicitWrite( - DemoteViaExplicitWrite reason, + DemoteViaExplicitWrite reason, ) { TreeNode node = reason.node as TreeNode; if (inferrer.dataForTesting != null) { diff --git a/pkg/front_end/lib/src/type_inference/matching_expressions.dart b/pkg/front_end/lib/src/type_inference/matching_expressions.dart index 44d223632f1..2893403688c 100644 --- a/pkg/front_end/lib/src/type_inference/matching_expressions.dart +++ b/pkg/front_end/lib/src/type_inference/matching_expressions.dart @@ -57,7 +57,7 @@ class MatchingExpressionVisitor } return new DelayedAssignment( matchingCache, - node.variable, + node.setter ?? node.variable, node.variable.type, valueExpression, fileOffset: node.fileOffset, diff --git a/pkg/front_end/lib/src/type_inference/shared_type_analyzer.dart b/pkg/front_end/lib/src/type_inference/shared_type_analyzer.dart index c69e5c53edb..302737a5426 100644 --- a/pkg/front_end/lib/src/type_inference/shared_type_analyzer.dart +++ b/pkg/front_end/lib/src/type_inference/shared_type_analyzer.dart @@ -23,7 +23,7 @@ class SharedTypeAnalyzerErrors TreeNode, Statement, Expression, - Variable, + InternalVariable, InternalPattern, InvalidExpression > { @@ -75,14 +75,14 @@ class SharedTypeAnalyzerErrors @override InvalidExpression duplicateAssignmentPatternVariable({ - required Variable variable, + required InternalVariable variable, required InternalPattern original, required InternalPattern duplicate, }) { return problemReporting.buildProblem( compilerContext: compilerContext, message: diag.duplicatePatternAssignmentVariable.withArguments( - variableName: variable.name!, + variableName: variable.cosmeticName!, ), fileUri: uri, fileOffset: duplicate.fileOffset, @@ -155,8 +155,8 @@ class SharedTypeAnalyzerErrors @override void inconsistentJoinedPatternVariable({ - required Variable variable, - required Variable component, + required InternalVariable variable, + required InternalVariable component, }) { // TODO(johnniwinther): How should we handle errors that are not report // here? Should we have a sentinel error node, allow a nullable result, or ? diff --git a/pkg/front_end/lib/src/type_inference/type_constraint_gatherer.dart b/pkg/front_end/lib/src/type_inference/type_constraint_gatherer.dart index cc4fc789df4..7dabd7b9ec1 100644 --- a/pkg/front_end/lib/src/type_inference/type_constraint_gatherer.dart +++ b/pkg/front_end/lib/src/type_inference/type_constraint_gatherer.dart @@ -12,6 +12,7 @@ import 'package:_fe_analyzer_shared/src/types/shared_type.dart'; import 'package:kernel/ast.dart'; import 'package:kernel/type_algebra.dart'; +import '../kernel/internal_ast.dart'; import 'type_inference_engine.dart'; import 'type_schema.dart'; import 'type_schema_environment.dart'; @@ -21,14 +22,14 @@ import 'type_schema_environment.dart'; class TypeConstraintGatherer extends shared.TypeConstraintGenerator< - Variable, + InternalVariable, TypeDeclarationType, TypeDeclaration, TreeNode > with shared.TypeConstraintGeneratorMixin< - Variable, + InternalVariable, TypeDeclarationType, TypeDeclaration, TreeNode diff --git a/pkg/front_end/lib/src/type_inference/type_inference_engine.dart b/pkg/front_end/lib/src/type_inference/type_inference_engine.dart index 1d03498f6c9..9634afda43d 100644 --- a/pkg/front_end/lib/src/type_inference/type_inference_engine.dart +++ b/pkg/front_end/lib/src/type_inference/type_inference_engine.dart @@ -379,14 +379,14 @@ class TypeInferenceEngineImpl extends TypeInferenceEngine { if (dataForTesting != null) { // Coverage-ignore-block(suite): Not run. dataForTesting.flowAnalysisResult.assignedVariables = - new AssignedVariablesForTesting(); + new AssignedVariablesForTesting(); assignedVariables = new AssignedVariablesImpl( dataForTesting.flowAnalysisResult.assignedVariables!, isClosureContextLoweringEnabled: isClosureContextLoweringEnabled, ); } else { assignedVariables = new AssignedVariablesImpl( - new AssignedVariables(), + new AssignedVariables(), isClosureContextLoweringEnabled: isClosureContextLoweringEnabled, ); } @@ -415,7 +415,11 @@ class TypeInferenceEngineImpl extends TypeInferenceEngine { // TODO(cstefantsova): Merge with [TypeInferenceResultForTesting]. class InferenceDataForTesting - extends shared.TypeConstraintGenerationDataForTesting { + extends + shared.TypeConstraintGenerationDataForTesting< + InternalVariable, + TreeNode + > { final FlowAnalysisResult flowAnalysisResult = new FlowAnalysisResult(); final TypeInferenceResultForTesting typeInferenceResult = @@ -446,7 +450,7 @@ class FlowAnalysisResult { final List definitelyUnassignedNodes = []; /// The assigned variables information that computed for the member. - AssignedVariablesForTesting? assignedVariables; + AssignedVariablesForTesting? assignedVariables; /// For each expression that led to an error because it was not promoted, a /// string describing the reason it was not promoted. @@ -461,14 +465,14 @@ class FlowAnalysisResult { class OperationsCfe with TypeAnalyzerOperationsMixin< - Variable, + InternalVariable, TypeDeclarationType, TypeDeclaration, TreeNode > implements TypeAnalyzerOperations< - Variable, + InternalVariable, TypeDeclarationType, TypeDeclaration, TreeNode @@ -595,7 +599,7 @@ class OperationsCfe bool isExtensionTypeInternal(DartType type) => type is ExtensionType; @override - bool isFinal(Variable variable) { + bool isFinal(InternalVariable variable) { return variable.isFinal; } @@ -683,14 +687,11 @@ class OperationsCfe } @override - SharedTypeView variableType(Variable variable) { + SharedTypeView variableType(InternalVariable variable) { // When late variables get lowered, their type is changed, but the // original type is stored in `VariableDeclarationImpl.lateType`, so we // use that if it exists. - DartType? lateType = variable is InternalVariable - ? (variable as InternalVariable).lateType - : null; - return new SharedTypeView(lateType ?? variable.type); + return new SharedTypeView(variable.lateType ?? variable.type); } @override @@ -772,7 +773,7 @@ class OperationsCfe } @override - bool isVariableFinal(Variable node) { + bool isVariableFinal(InternalVariable node) { return node.isFinal; } @@ -1097,7 +1098,7 @@ class OperationsCfe @override TypeConstraintGenerator< - Variable, + InternalVariable, TypeDeclarationType, TypeDeclaration, TreeNode @@ -1184,7 +1185,11 @@ class OperationsCfe /// Type inference results used for testing. class TypeInferenceResultForTesting - extends shared.TypeConstraintGenerationDataForTesting { + extends + shared.TypeConstraintGenerationDataForTesting< + InternalVariable, + TreeNode + > { final Map> inferredTypeArguments = {}; final Map inferredVariableTypes = {}; } diff --git a/pkg/front_end/lib/src/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/type_inference/type_inferrer.dart index 33b3f8d86f1..ef4a29e80e1 100644 --- a/pkg/front_end/lib/src/type_inference/type_inferrer.dart +++ b/pkg/front_end/lib/src/type_inference/type_inferrer.dart @@ -41,7 +41,8 @@ abstract class TypeInferrer { ExtensionScope get extensionScope; /// Returns the [FlowAnalysis] used during inference. - FlowAnalysis get flowAnalysis; + FlowAnalysis + get flowAnalysis; AssignedVariablesImpl get assignedVariables; @@ -55,7 +56,7 @@ abstract class TypeInferrer { DartType? declaredType, required Expression initializer, required InferenceDefaultType inferenceDefaultType, - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, }); /// Performs type inference on the given function body. @@ -66,7 +67,7 @@ abstract class TypeInferrer { required AsyncModifier asyncModifier, required Statement body, required List parameters, - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, required ScopeProviderInfo? scopeProviderInfo, required ContextAllocationStrategy contextAllocationStrategy, required ConstructorContext? constructorContext, @@ -79,7 +80,7 @@ abstract class TypeInferrer { required ConstructorContext constructorContext, required List initializers, required List parameters, - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, required ContextAllocationStrategy contextAllocationStrategy, required bool isConstructorWithoutBody, }); @@ -124,7 +125,7 @@ class TypeInferrerImpl implements TypeInferrer { TypeAnalyzerOptions typeAnalyzerOptions; @override - late final FlowAnalysis + late final FlowAnalysis flowAnalysis = new FlowAnalysis( operations, assignedVariables, @@ -210,7 +211,7 @@ class TypeInferrerImpl implements TypeInferrer { DartType? declaredType, required Expression initializer, required InferenceDefaultType inferenceDefaultType, - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, }) { InferenceVisitorBase visitor = _createInferenceVisitor( fileUri: fileUri, @@ -261,7 +262,7 @@ class TypeInferrerImpl implements TypeInferrer { required AsyncModifier asyncModifier, required Statement body, required List parameters, - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, required ScopeProviderInfo? scopeProviderInfo, required ContextAllocationStrategy contextAllocationStrategy, required ConstructorContext? constructorContext, @@ -331,25 +332,39 @@ class TypeInferrerImpl implements TypeInferrer { InferenceVisitorBase.createContextAllocationStrategy(), ); + List positionalParameters = [ + for (Variable positionalParameter + in redirectingFactoryFunction.positionalParameters) + isClosureContextLoweringEnabled + ? new InternalPositionalParameter( + astVariable: positionalParameter as PositionalParameter, + isImplicitlyTyped: false, + fileOffset: positionalParameter.fileOffset, + ) + : new InternalLegacyVariable( + astVariable: positionalParameter, + fileOffset: positionalParameter.fileOffset, + ), + ]; + List namedParameters = [ + for (Variable namedParameter + in redirectingFactoryFunction.namedParameters) + isClosureContextLoweringEnabled + ? new InternalNamedParameter( + astVariable: namedParameter as NamedParameter, + isImplicitlyTyped: false, + fileOffset: namedParameter.fileOffset, + ) + : new InternalLegacyVariable( + astVariable: namedParameter, + fileOffset: namedParameter.fileOffset, + ), + ]; + ScopeProviderInfo? scopeProviderInfo; if (isClosureContextLoweringEnabled) { scopeProviderInfo = visitor.beginClosureContextAllocation( - [ - for (Variable positionalParameter - in redirectingFactoryFunction.positionalParameters) - new InternalPositionalParameter( - astVariable: positionalParameter as PositionalParameter, - isImplicitlyTyped: false, - fileOffset: positionalParameter.fileOffset, - ), - for (Variable namedParameter - in redirectingFactoryFunction.namedParameters) - new InternalNamedParameter( - astVariable: namedParameter as NamedParameter, - isImplicitlyTyped: false, - fileOffset: namedParameter.fileOffset, - ), - ], + [...positionalParameters, ...namedParameters], internalThisVariable: null, scopeProviderInfo: null, ); @@ -357,60 +372,30 @@ class TypeInferrerImpl implements TypeInferrer { List arguments = []; int positionalCount = 0; - for (Variable parameter - in redirectingFactoryFunction.positionalParameters) { + for (InternalVariable parameter in positionalParameters) { flowAnalysis.declare( parameter, new SharedTypeView(parameter.type), initialized: true, ); - Expression variableGet; - if (isClosureContextLoweringEnabled) { - variableGet = intern.createVariableGet( - new InternalPositionalParameter( - astVariable: parameter as PositionalParameter, - isImplicitlyTyped: false, - fileOffset: parameter.fileOffset, - ), - fileOffset: parameter.fileOffset, - ); - } else { - variableGet = intern.createVariableGet( - parameter as InternalVariable, - fileOffset: parameter.fileOffset, - ); - } + Expression variableGet = intern.createVariableGet( + parameter, + fileOffset: parameter.fileOffset, + ); arguments.add(new PositionalArgument(variableGet)); positionalCount++; } - for (Variable parameter in redirectingFactoryFunction.namedParameters) { + for (InternalVariable parameter in namedParameters) { flowAnalysis.declare( parameter, new SharedTypeView(parameter.type), initialized: true, ); - NamedExpression namedExpression; - if (isClosureContextLoweringEnabled) { - namedExpression = new NamedExpression( - parameter.name!, - intern.createVariableGet( - new InternalNamedParameter( - astVariable: parameter as NamedParameter, - isImplicitlyTyped: false, - fileOffset: parameter.fileOffset, - ), - fileOffset: parameter.fileOffset, - ), - ); - } else { - namedExpression = new NamedExpression( - parameter.name!, - intern.createVariableGet( - parameter as InternalVariable, - fileOffset: parameter.fileOffset, - ), - ); - } + NamedExpression namedExpression = new NamedExpression( + parameter.cosmeticName!, + intern.createVariableGet(parameter, fileOffset: parameter.fileOffset), + ); + arguments.add(new NamedArgument(namedExpression)); } // If arguments are created using [ArgumentsImpl], and the @@ -451,7 +436,7 @@ class TypeInferrerImpl implements TypeInferrer { required ConstructorContext constructorContext, required List initializers, required List parameters, - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, required ContextAllocationStrategy contextAllocationStrategy, required bool isConstructorWithoutBody, }) { @@ -554,8 +539,8 @@ class TypeInferrerImplBenchmarked implements TypeInferrer { AssignedVariablesImpl get assignedVariables => impl.assignedVariables; @override - FlowAnalysis get flowAnalysis => - impl.flowAnalysis; + FlowAnalysis + get flowAnalysis => impl.flowAnalysis; @override TypeSchemaEnvironment get typeSchemaEnvironment => impl.typeSchemaEnvironment; @@ -566,7 +551,7 @@ class TypeInferrerImplBenchmarked implements TypeInferrer { DartType? declaredType, required Expression initializer, required InferenceDefaultType inferenceDefaultType, - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, }) { benchmarker.beginSubdivide(BenchmarkSubdivides.inferFieldInitializer); InferredFieldInitializer result = impl.inferFieldInitializer( @@ -588,7 +573,7 @@ class TypeInferrerImplBenchmarked implements TypeInferrer { required AsyncModifier asyncModifier, required Statement body, required List parameters, - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, required ScopeProviderInfo? scopeProviderInfo, required ContextAllocationStrategy contextAllocationStrategy, required ConstructorContext? constructorContext, @@ -618,7 +603,7 @@ class TypeInferrerImplBenchmarked implements TypeInferrer { required ConstructorContext constructorContext, required List initializers, required List parameters, - required ThisVariable? internalThisVariable, + required InternalThisVariable? internalThisVariable, required ContextAllocationStrategy contextAllocationStrategy, required bool isConstructorWithoutBody, diff --git a/pkg/front_end/lib/src/type_inference/type_schema_environment.dart b/pkg/front_end/lib/src/type_inference/type_schema_environment.dart index 5c50906d2a6..16c30deb2aa 100644 --- a/pkg/front_end/lib/src/type_inference/type_schema_environment.dart +++ b/pkg/front_end/lib/src/type_inference/type_schema_environment.dart @@ -14,17 +14,19 @@ import 'package:kernel/src/hierarchy_based_type_environment.dart' import 'package:kernel/type_algebra.dart'; import 'package:kernel/type_environment.dart'; +import '../kernel/internal_ast.dart'; import 'standard_bounds.dart' show TypeSchemaStandardBounds; import 'type_constraint_gatherer.dart' show TypeConstraintGatherer; import 'type_inference_engine.dart'; import 'type_demotion.dart'; import 'type_schema.dart' show UnknownType; -typedef GeneratedTypeConstraint = shared.GeneratedTypeConstraint; +typedef GeneratedTypeConstraint = + shared.GeneratedTypeConstraint; typedef MergedTypeConstraint = shared.MergedTypeConstraint< - Variable, + InternalVariable, TypeDeclarationType, TypeDeclaration, TreeNode @@ -32,7 +34,7 @@ typedef MergedTypeConstraint = typedef UnknownTypeConstraintOrigin = shared.UnknownTypeConstraintOrigin< - Variable, + InternalVariable, TypeDeclarationType, TypeDeclaration, TreeNode diff --git a/pkg/front_end/test/generator_to_string_test.dart b/pkg/front_end/test/generator_to_string_test.dart index d87be641c54..63860ee920f 100644 --- a/pkg/front_end/test/generator_to_string_test.dart +++ b/pkg/front_end/test/generator_to_string_test.dart @@ -52,7 +52,8 @@ import 'package:kernel/ast.dart' TypeParameter, Variable, VariableGet, - defaultLanguageVersion; + defaultLanguageVersion, + LegacyVariable; import 'package:kernel/class_hierarchy.dart'; import 'package:kernel/core_types.dart'; import 'package:kernel/target/targets.dart' show NoneTarget, TargetFlags; @@ -177,9 +178,8 @@ Future main() async { new TypeParameter("T", const DynamicType(), const DynamicType()), loader: null, ); - InternalVariable variable = new VariableDeclarationImpl( - null, - isSynthesized: true, + InternalVariable variable = new InternalLegacyVariable( + astVariable: new LegacyVariable(null, isSynthesized: true), fileOffset: -1, ); diff --git a/pkg/front_end/test/id_tests/assigned_variables_test.dart b/pkg/front_end/test/id_tests/assigned_variables_test.dart index a906d8e977f..234899a61f2 100644 --- a/pkg/front_end/test/id_tests/assigned_variables_test.dart +++ b/pkg/front_end/test/id_tests/assigned_variables_test.dart @@ -9,6 +9,7 @@ import 'package:_fe_analyzer_shared/src/testing/id.dart' import 'package:_fe_analyzer_shared/src/testing/id_testing.dart' show DataInterpreter, runTests; import 'package:_fe_analyzer_shared/src/type_inference/assigned_variables.dart'; +import 'package:front_end/src/kernel/internal_ast.dart'; import 'package:front_end/src/source/source_loader.dart'; import 'package:front_end/src/source/source_member_builder.dart'; import 'package:front_end/src/testing/id_testing_helper.dart'; @@ -50,10 +51,11 @@ class AssignedVariablesDataComputer extends CfeDataComputer<_Data> { Map> actualMap, { bool? verbose, }) { - SourceMemberBuilder memberBuilder = - lookupMemberBuilder(testResultData.compilerResult, member) - as SourceMemberBuilder; - AssignedVariablesForTesting? assignedVariables = + SourceMemberBuilder memberBuilder = lookupMemberBuilder( + testResultData.compilerResult, + member, + ) as SourceMemberBuilder; + AssignedVariablesForTesting? assignedVariables = memberBuilder .dataForTesting! .inferenceData @@ -72,7 +74,8 @@ class AssignedVariablesDataComputer extends CfeDataComputer<_Data> { class AssignedVariablesDataExtractor extends CfeDataExtractor<_Data> { final SourceLoaderDataForTesting _sourceLoaderDataForTesting; - final AssignedVariablesForTesting _assignedVariables; + final AssignedVariablesForTesting + _assignedVariables; new( InternalCompilerResult compilerResult, diff --git a/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart b/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart index 5cf3874f9b3..b162e8c7dad 100644 --- a/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart +++ b/pkg/front_end/test/text_representation/internal_ast_text_representation_test.dart @@ -226,10 +226,16 @@ void _testVariableDeclarations() { testStatement( forest.variablesDeclaration([ new InternalVariableDeclaration( - new VariableDeclarationImpl('a', fileOffset: TreeNode.noOffset), + new InternalLegacyVariable( + astVariable: new LegacyVariable('a'), + fileOffset: TreeNode.noOffset, + ), ), new InternalVariableDeclaration( - new VariableDeclarationImpl('b', fileOffset: TreeNode.noOffset), + new InternalLegacyVariable( + astVariable: new LegacyVariable('b'), + fileOffset: TreeNode.noOffset, + ), ), ], dummyUri), ''' @@ -238,16 +244,14 @@ dynamic a, b;''', testStatement( forest.variablesDeclaration([ new InternalVariableDeclaration( - new VariableDeclarationImpl( - 'a', - type: const VoidType(), + new InternalLegacyVariable( + astVariable: new LegacyVariable('a', type: const VoidType()), fileOffset: TreeNode.noOffset, ), ), new InternalVariableDeclaration( - new VariableDeclarationImpl( - 'b', - initializer: new NullLiteral(), + new InternalLegacyVariable( + astVariable: new LegacyVariable('b', initializer: new NullLiteral()), fileOffset: TreeNode.noOffset, ), ), @@ -263,23 +267,35 @@ void _testTryStatement() { Block returnBlock1 = new Block([new ReturnStatement()]); Block returnBlock2 = new Block([new ReturnStatement()]); InternalCatch emptyCatchBlock = new InternalCatch( - exception: new VariableDeclarationImpl('e', fileOffset: TreeNode.noOffset), + exception: new InternalLegacyVariable( + astVariable: new LegacyVariable('e'), + fileOffset: TreeNode.noOffset, + ), body: new Block([]), fileOffset: TreeNode.noOffset, ); InternalCatch emptyCatchBlockOnVoid = new InternalCatch( - exception: new VariableDeclarationImpl('e', fileOffset: TreeNode.noOffset), + exception: new InternalLegacyVariable( + astVariable: new LegacyVariable('e'), + fileOffset: TreeNode.noOffset, + ), body: new Block([]), guard: const VoidType(), fileOffset: TreeNode.noOffset, ); InternalCatch returnCatchBlock = new InternalCatch( - exception: new VariableDeclarationImpl('e', fileOffset: TreeNode.noOffset), + exception: new InternalLegacyVariable( + astVariable: new LegacyVariable('e'), + fileOffset: TreeNode.noOffset, + ), body: new Block([new ReturnStatement()]), fileOffset: TreeNode.noOffset, ); InternalCatch returnCatchBlockOnVoid = new InternalCatch( - exception: new VariableDeclarationImpl('e', fileOffset: TreeNode.noOffset), + exception: new InternalLegacyVariable( + astVariable: new LegacyVariable('e'), + fileOffset: TreeNode.noOffset, + ), body: new Block([new ReturnStatement()]), guard: const VoidType(), fileOffset: TreeNode.noOffset, @@ -393,7 +409,11 @@ void _testInternalForInStatement() { new InternalForInStatement( new SingleVariableDeclarationForInElement( variableDeclaration: new InternalVariableDeclaration( - new VariableDeclarationImpl('e', fileOffset: -1), + new InternalLegacyVariable( + astVariable: new LegacyVariable('e'), + isImplicitlyTyped: true, + fileOffset: -1, + ), ), error: null, ), @@ -411,9 +431,8 @@ for (var e in null) {}''', new InternalForInStatement( new SingleVariableDeclarationForInElement( variableDeclaration: new InternalVariableDeclaration( - new VariableDeclarationImpl( - 'e', - type: const VoidType(), + new InternalLegacyVariable( + astVariable: new LegacyVariable('e', type: const VoidType()), fileOffset: -1, ), ), @@ -436,16 +455,16 @@ for (void e in null) {}''', patterns: [ new InternalVariablePattern( type: const VoidType(), - variable: new VariableDeclarationImpl( - 'a', + variable: new InternalLegacyVariable( + astVariable: new LegacyVariable('a'), fileOffset: TreeNode.noOffset, ), fileOffset: TreeNode.noOffset, ), new InternalVariablePattern( type: null, - variable: new VariableDeclarationImpl( - 'b', + variable: new InternalLegacyVariable( + astVariable: new LegacyVariable('b'), fileOffset: TreeNode.noOffset, ), fileOffset: TreeNode.noOffset, @@ -468,7 +487,10 @@ for (var (void a, var b) in null) {}''', testStatement( new InternalForInStatement( new ExistingVariableForInElement( - variable: new VariableDeclarationImpl('a', fileOffset: -1), + variable: new InternalLegacyVariable( + astVariable: new LegacyVariable('a'), + fileOffset: -1, + ), nameOffset: -1, inOffset: -1, ), @@ -557,10 +579,18 @@ for (null in null) {}''', new MultiVariableDeclarationForInElement( variableDeclarations: [ new InternalVariableDeclaration( - new VariableDeclarationImpl('a', fileOffset: -1), + new InternalLegacyVariable( + astVariable: new LegacyVariable('a'), + isImplicitlyTyped: true, + fileOffset: -1, + ), ), new InternalVariableDeclaration( - new VariableDeclarationImpl('b', fileOffset: -1), + new InternalLegacyVariable( + astVariable: new LegacyVariable('b'), + isImplicitlyTyped: true, + fileOffset: -1, + ), ), ], error: new InvalidExpression('error'), @@ -580,14 +610,16 @@ for (var a, b in null) {}''', new MultiVariableDeclarationForInElement( variableDeclarations: [ new InternalVariableDeclaration( - new VariableDeclarationImpl( - 'a', - type: const VoidType(), + new InternalLegacyVariable( + astVariable: new LegacyVariable('a', type: const VoidType()), fileOffset: -1, ), ), new InternalVariableDeclaration( - new VariableDeclarationImpl('b', fileOffset: -1), + new InternalLegacyVariable( + astVariable: new LegacyVariable('b'), + fileOffset: -1, + ), ), ], error: new InvalidExpression('error'), @@ -882,9 +914,10 @@ continue label0;''', void _testCascade() { // TODO(johnniwinther): Add better text representation support for internal // synthetic variables. - InternalVariable variable = new VariableDeclarationImpl.forValue( - new IntLiteral(0), - )..name = '#0'; + InternalVariable variable = new InternalLegacyVariable( + astVariable: new LegacyVariable.forValue(new IntLiteral(0))..name = '#0', + fileOffset: TreeNode.noOffset, + ); Cascade cascade = new Cascade(variable, isNullAware: false); testExpression(cascade, ''' let final dynamic #0 = 0 in cascade {} => #0'''); @@ -933,8 +966,11 @@ void _testDeferredCheck() { library, 'pre', ); - InternalVariable check = new VariableDeclarationImpl.forValue( - new CheckLibraryIsLoaded(dependency), + InternalVariable check = new InternalLegacyVariable( + astVariable: new LegacyVariable.forValue( + new CheckLibraryIsLoaded(dependency), + ), + fileOffset: TreeNode.noOffset, ); testExpression( new DeferredCheck(check, new IntLiteral(0), fileOffset: TreeNode.noOffset), @@ -1267,8 +1303,8 @@ const library test:dummy::Typedef.foo(0, bar: 1)''', void _testFunctionDeclarationImpl() { testStatement( new InternalFunctionDeclaration( - variable: new VariableDeclarationImpl( - 'foo', + variable: new InternalLegacyVariable( + astVariable: new LegacyVariable('foo'), fileOffset: TreeNode.noOffset, ), fileOffset: TreeNode.noOffset, @@ -1504,65 +1540,75 @@ return 0;'''); void _testVariableDeclarationImpl() { testVariableDeclaration( - new VariableDeclarationImpl('foo', fileOffset: TreeNode.noOffset), + new InternalLegacyVariable( + astVariable: new LegacyVariable('foo'), + fileOffset: TreeNode.noOffset, + ), ''' dynamic foo''', ); testVariableDeclaration( - new VariableDeclarationImpl( - 'foo', - initializer: new IntLiteral(0), + new InternalLegacyVariable( + astVariable: new LegacyVariable('foo', initializer: new IntLiteral(0)), fileOffset: TreeNode.noOffset, ), ''' dynamic foo = 0''', ); testVariableDeclaration( - new VariableDeclarationImpl( - 'foo', - type: const VoidType(), - initializer: new IntLiteral(0), - isFinal: true, - isRequired: true, + new InternalLegacyVariable( + astVariable: new LegacyVariable( + 'foo', + type: const VoidType(), + initializer: new IntLiteral(0), + isFinal: true, + isRequired: true, + ), fileOffset: TreeNode.noOffset, ), ''' required final void foo''', ); testVariableDeclaration( - new VariableDeclarationImpl( - 'foo', - type: const VoidType(), - initializer: new IntLiteral(0), - isLate: true, + new InternalLegacyVariable( + astVariable: new LegacyVariable( + 'foo', + type: const VoidType(), + initializer: new IntLiteral(0), + isLate: true, + ), fileOffset: TreeNode.noOffset, ), ''' late void foo = 0''', ); testVariableDeclaration( - new VariableDeclarationImpl( - 'foo', - type: const VoidType(), - initializer: new IntLiteral(0), + new InternalLegacyVariable( + astVariable: new LegacyVariable( + 'foo', + type: const VoidType(), + initializer: new IntLiteral(0), + ), fileOffset: TreeNode.noOffset, ) - ..lateGetter = new VariableDeclarationImpl( - 'foo#getter', + ..lateGetter = new InternalLegacyVariable( + astVariable: new LegacyVariable('foo#getter'), fileOffset: TreeNode.noOffset, ), ''' late void foo = 0''', ); testVariableDeclaration( - new VariableDeclarationImpl( - 'foo', - type: const VoidType(), - initializer: new IntLiteral(0), + new InternalLegacyVariable( + astVariable: new LegacyVariable( + 'foo', + type: const VoidType(), + initializer: new IntLiteral(0), + ), fileOffset: TreeNode.noOffset, ) - ..lateGetter = new VariableDeclarationImpl( - 'foo#getter', + ..lateGetter = new InternalLegacyVariable( + astVariable: new LegacyVariable('foo#getter'), fileOffset: TreeNode.noOffset, ) ..lateType = const DynamicType(), @@ -1981,8 +2027,8 @@ void _testPropertyIncDec() { } void _testLocalIncDec() { - VariableDeclarationImpl variable = new VariableDeclarationImpl( - 'foo', + InternalLegacyVariable variable = new InternalLegacyVariable( + astVariable: new LegacyVariable('foo'), fileOffset: TreeNode.noOffset, ); diff --git a/pkg/front_end/testcases/nnbd/why_not_promoted.dart b/pkg/front_end/testcases/nnbd/why_not_promoted.dart new file mode 100644 index 00000000000..728650d2548 --- /dev/null +++ b/pkg/front_end/testcases/nnbd/why_not_promoted.dart @@ -0,0 +1,61 @@ +// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// Derived from tests/language/why_not_promoted/assignment_error_test.dart + +abstract class C { + C? operator +(int i); + int get cProperty => 0; +} + +direct_assignment(int? i, int? j) { + if (i == null) return; + i = j; + i.isEven; +} + +compound_assignment(C? c, int i) { + if (c == null) return; + c += i; + c.cProperty; +} + +via_postfix_op(C? c) { + if (c == null) return; + c++; + c.cProperty; +} + +via_prefix_op(C? c) { + if (c == null) return; + ++c; + c.cProperty; +} + +via_for_each_statement(int? i, List list) { + if (i == null) return; + for (i in list) { + i.isEven; + } +} + +via_for_each_list_element(int? i, List list) { + if (i == null) return; + [for (i in list) i.isEven]; +} + +via_for_each_set_element(int? i, List list) { + if (i == null) return; + ({for (i in list) i.isEven}); +} + +via_for_each_map_key(int? i, List list) { + if (i == null) return; + ({for (i in list) i.isEven: null}); +} + +via_for_each_map_value(int? i, List list) { + if (i == null) return; + ({for (i in list) null: i.isEven}); +} diff --git a/pkg/front_end/testcases/nnbd/why_not_promoted.dart.strong.expect b/pkg/front_end/testcases/nnbd/why_not_promoted.dart.strong.expect new file mode 100644 index 00000000000..241ea3aa869 --- /dev/null +++ b/pkg/front_end/testcases/nnbd/why_not_promoted.dart.strong.expect @@ -0,0 +1,206 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:15:5: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +// Try accessing using ?. instead. +// i.isEven; +// ^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:14:3: Context: Variable 'i' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// i = j; +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:21:5: Error: Property 'cProperty' cannot be accessed on 'C?' because it is potentially null. +// - 'C' is from 'pkg/front_end/testcases/nnbd/why_not_promoted.dart'. +// Try accessing using ?. instead. +// c.cProperty; +// ^^^^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:20:3: Context: Variable 'c' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// c += i; +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:27:5: Error: Property 'cProperty' cannot be accessed on 'C?' because it is potentially null. +// - 'C' is from 'pkg/front_end/testcases/nnbd/why_not_promoted.dart'. +// Try accessing using ?. instead. +// c.cProperty; +// ^^^^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:26:3: Context: Variable 'c' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// c++; +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:33:5: Error: Property 'cProperty' cannot be accessed on 'C?' because it is potentially null. +// - 'C' is from 'pkg/front_end/testcases/nnbd/why_not_promoted.dart'. +// Try accessing using ?. instead. +// c.cProperty; +// ^^^^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:32:5: Context: Variable 'c' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// ++c; +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:39:7: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +// Try accessing using ?. instead. +// i.isEven; +// ^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:38:8: Context: Variable 'i' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// for (i in list) { +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:45:22: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +// Try accessing using ?. instead. +// [for (i in list) i.isEven]; +// ^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:45:9: Context: Variable 'i' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// [for (i in list) i.isEven]; +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:50:23: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +// Try accessing using ?. instead. +// ({for (i in list) i.isEven}); +// ^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:50:10: Context: Variable 'i' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// ({for (i in list) i.isEven}); +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:55:23: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +// Try accessing using ?. instead. +// ({for (i in list) i.isEven: null}); +// ^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:55:10: Context: Variable 'i' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// ({for (i in list) i.isEven: null}); +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:60:29: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +// Try accessing using ?. instead. +// ({for (i in list) null: i.isEven}); +// ^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:60:10: Context: Variable 'i' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// ({for (i in list) null: i.isEven}); +// ^ +// +import self as self; +import "dart:core" as core; +import "dart:collection" as col; + +abstract class C extends core::Object { + synthetic constructor •() → self::C + : super core::Object::•() + ; + abstract operator +(core::int i) → self::C?; + get cProperty() → core::int + return 0; +} +static method direct_assignment(core::int? i, core::int? j) → dynamic { + if(i == null) + return; + i = j; + invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:15:5: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +Try accessing using ?. instead. + i.isEven; + ^^^^^^" in i.{core::int::isEven}{}.{core::bool}; +} +static method compound_assignment(self::C? c, core::int i) → dynamic { + if(c == null) + return; + c = c{self::C}.{self::C::+}(i){(core::int) → self::C?}; + invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:21:5: Error: Property 'cProperty' cannot be accessed on 'C?' because it is potentially null. + - 'C' is from 'pkg/front_end/testcases/nnbd/why_not_promoted.dart'. +Try accessing using ?. instead. + c.cProperty; + ^^^^^^^^^" in c.{self::C::cProperty}{}.{core::int}; +} +static method via_postfix_op(self::C? c) → dynamic { + if(c == null) + return; + c = c{self::C}.{self::C::+}(1){(core::int) → self::C?}; + invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:27:5: Error: Property 'cProperty' cannot be accessed on 'C?' because it is potentially null. + - 'C' is from 'pkg/front_end/testcases/nnbd/why_not_promoted.dart'. +Try accessing using ?. instead. + c.cProperty; + ^^^^^^^^^" in c.{self::C::cProperty}{}.{core::int}; +} +static method via_prefix_op(self::C? c) → dynamic { + if(c == null) + return; + c = c{self::C}.{self::C::+}(1){(core::int) → self::C?}; + invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:33:5: Error: Property 'cProperty' cannot be accessed on 'C?' because it is potentially null. + - 'C' is from 'pkg/front_end/testcases/nnbd/why_not_promoted.dart'. +Try accessing using ?. instead. + c.cProperty; + ^^^^^^^^^" in c.{self::C::cProperty}{}.{core::int}; +} +static method via_for_each_statement(core::int? i, core::List list) → dynamic { + if(i == null) + return; + for (final core::int? #t1 in list) { + i = #t1; + invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:39:7: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +Try accessing using ?. instead. + i.isEven; + ^^^^^^" in i.{core::int::isEven}{}.{core::bool}; + } +} +static method via_for_each_list_element(core::int? i, core::List list) → dynamic { + if(i == null) + return; + { + final core::List #t2 = []; + for (final core::int? #t3 in list) { + i = #t3; + #t2.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:45:22: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +Try accessing using ?. instead. + [for (i in list) i.isEven]; + ^^^^^^" in i.{core::int::isEven}{}.{core::bool}){(core::bool) → void}; + } + } +} +static method via_for_each_set_element(core::int? i, core::List list) → dynamic { + if(i == null) + return; + { + final core::Set #t4 = col::LinkedHashSet::•(); + for (final core::int? #t5 in list) { + i = #t5; + #t4.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:50:23: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +Try accessing using ?. instead. + ({for (i in list) i.isEven}); + ^^^^^^" in i.{core::int::isEven}{}.{core::bool}){(core::bool) → core::bool}; + } + } +} +static method via_for_each_map_key(core::int? i, core::List list) → dynamic { + if(i == null) + return; + { + final core::Map #t6 = {}; + for (final core::int? #t7 in list) { + i = #t7; + #t6.{core::Map::[]=}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:55:23: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +Try accessing using ?. instead. + ({for (i in list) i.isEven: null}); + ^^^^^^" in i.{core::int::isEven}{}.{core::bool}, null){(core::bool, Null) → void}; + } + } +} +static method via_for_each_map_value(core::int? i, core::List list) → dynamic { + if(i == null) + return; + { + final core::Map #t8 = {}; + for (final core::int? #t9 in list) { + i = #t9; + #t8.{core::Map::[]=}{Invariant}(null, invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:60:29: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +Try accessing using ?. instead. + ({for (i in list) null: i.isEven}); + ^^^^^^" in i.{core::int::isEven}{}.{core::bool}){(Null, core::bool) → void}; + } + } +} diff --git a/pkg/front_end/testcases/nnbd/why_not_promoted.dart.strong.modular.expect b/pkg/front_end/testcases/nnbd/why_not_promoted.dart.strong.modular.expect new file mode 100644 index 00000000000..241ea3aa869 --- /dev/null +++ b/pkg/front_end/testcases/nnbd/why_not_promoted.dart.strong.modular.expect @@ -0,0 +1,206 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:15:5: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +// Try accessing using ?. instead. +// i.isEven; +// ^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:14:3: Context: Variable 'i' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// i = j; +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:21:5: Error: Property 'cProperty' cannot be accessed on 'C?' because it is potentially null. +// - 'C' is from 'pkg/front_end/testcases/nnbd/why_not_promoted.dart'. +// Try accessing using ?. instead. +// c.cProperty; +// ^^^^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:20:3: Context: Variable 'c' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// c += i; +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:27:5: Error: Property 'cProperty' cannot be accessed on 'C?' because it is potentially null. +// - 'C' is from 'pkg/front_end/testcases/nnbd/why_not_promoted.dart'. +// Try accessing using ?. instead. +// c.cProperty; +// ^^^^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:26:3: Context: Variable 'c' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// c++; +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:33:5: Error: Property 'cProperty' cannot be accessed on 'C?' because it is potentially null. +// - 'C' is from 'pkg/front_end/testcases/nnbd/why_not_promoted.dart'. +// Try accessing using ?. instead. +// c.cProperty; +// ^^^^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:32:5: Context: Variable 'c' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// ++c; +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:39:7: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +// Try accessing using ?. instead. +// i.isEven; +// ^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:38:8: Context: Variable 'i' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// for (i in list) { +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:45:22: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +// Try accessing using ?. instead. +// [for (i in list) i.isEven]; +// ^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:45:9: Context: Variable 'i' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// [for (i in list) i.isEven]; +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:50:23: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +// Try accessing using ?. instead. +// ({for (i in list) i.isEven}); +// ^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:50:10: Context: Variable 'i' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// ({for (i in list) i.isEven}); +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:55:23: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +// Try accessing using ?. instead. +// ({for (i in list) i.isEven: null}); +// ^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:55:10: Context: Variable 'i' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// ({for (i in list) i.isEven: null}); +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:60:29: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +// Try accessing using ?. instead. +// ({for (i in list) null: i.isEven}); +// ^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:60:10: Context: Variable 'i' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// ({for (i in list) null: i.isEven}); +// ^ +// +import self as self; +import "dart:core" as core; +import "dart:collection" as col; + +abstract class C extends core::Object { + synthetic constructor •() → self::C + : super core::Object::•() + ; + abstract operator +(core::int i) → self::C?; + get cProperty() → core::int + return 0; +} +static method direct_assignment(core::int? i, core::int? j) → dynamic { + if(i == null) + return; + i = j; + invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:15:5: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +Try accessing using ?. instead. + i.isEven; + ^^^^^^" in i.{core::int::isEven}{}.{core::bool}; +} +static method compound_assignment(self::C? c, core::int i) → dynamic { + if(c == null) + return; + c = c{self::C}.{self::C::+}(i){(core::int) → self::C?}; + invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:21:5: Error: Property 'cProperty' cannot be accessed on 'C?' because it is potentially null. + - 'C' is from 'pkg/front_end/testcases/nnbd/why_not_promoted.dart'. +Try accessing using ?. instead. + c.cProperty; + ^^^^^^^^^" in c.{self::C::cProperty}{}.{core::int}; +} +static method via_postfix_op(self::C? c) → dynamic { + if(c == null) + return; + c = c{self::C}.{self::C::+}(1){(core::int) → self::C?}; + invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:27:5: Error: Property 'cProperty' cannot be accessed on 'C?' because it is potentially null. + - 'C' is from 'pkg/front_end/testcases/nnbd/why_not_promoted.dart'. +Try accessing using ?. instead. + c.cProperty; + ^^^^^^^^^" in c.{self::C::cProperty}{}.{core::int}; +} +static method via_prefix_op(self::C? c) → dynamic { + if(c == null) + return; + c = c{self::C}.{self::C::+}(1){(core::int) → self::C?}; + invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:33:5: Error: Property 'cProperty' cannot be accessed on 'C?' because it is potentially null. + - 'C' is from 'pkg/front_end/testcases/nnbd/why_not_promoted.dart'. +Try accessing using ?. instead. + c.cProperty; + ^^^^^^^^^" in c.{self::C::cProperty}{}.{core::int}; +} +static method via_for_each_statement(core::int? i, core::List list) → dynamic { + if(i == null) + return; + for (final core::int? #t1 in list) { + i = #t1; + invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:39:7: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +Try accessing using ?. instead. + i.isEven; + ^^^^^^" in i.{core::int::isEven}{}.{core::bool}; + } +} +static method via_for_each_list_element(core::int? i, core::List list) → dynamic { + if(i == null) + return; + { + final core::List #t2 = []; + for (final core::int? #t3 in list) { + i = #t3; + #t2.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:45:22: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +Try accessing using ?. instead. + [for (i in list) i.isEven]; + ^^^^^^" in i.{core::int::isEven}{}.{core::bool}){(core::bool) → void}; + } + } +} +static method via_for_each_set_element(core::int? i, core::List list) → dynamic { + if(i == null) + return; + { + final core::Set #t4 = col::LinkedHashSet::•(); + for (final core::int? #t5 in list) { + i = #t5; + #t4.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:50:23: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +Try accessing using ?. instead. + ({for (i in list) i.isEven}); + ^^^^^^" in i.{core::int::isEven}{}.{core::bool}){(core::bool) → core::bool}; + } + } +} +static method via_for_each_map_key(core::int? i, core::List list) → dynamic { + if(i == null) + return; + { + final core::Map #t6 = {}; + for (final core::int? #t7 in list) { + i = #t7; + #t6.{core::Map::[]=}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:55:23: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +Try accessing using ?. instead. + ({for (i in list) i.isEven: null}); + ^^^^^^" in i.{core::int::isEven}{}.{core::bool}, null){(core::bool, Null) → void}; + } + } +} +static method via_for_each_map_value(core::int? i, core::List list) → dynamic { + if(i == null) + return; + { + final core::Map #t8 = {}; + for (final core::int? #t9 in list) { + i = #t9; + #t8.{core::Map::[]=}{Invariant}(null, invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:60:29: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +Try accessing using ?. instead. + ({for (i in list) null: i.isEven}); + ^^^^^^" in i.{core::int::isEven}{}.{core::bool}){(Null, core::bool) → void}; + } + } +} diff --git a/pkg/front_end/testcases/nnbd/why_not_promoted.dart.strong.outline.expect b/pkg/front_end/testcases/nnbd/why_not_promoted.dart.strong.outline.expect new file mode 100644 index 00000000000..ac396abc016 --- /dev/null +++ b/pkg/front_end/testcases/nnbd/why_not_promoted.dart.strong.outline.expect @@ -0,0 +1,29 @@ +library; +import self as self; +import "dart:core" as core; + +abstract class C extends core::Object { + synthetic constructor •() → self::C + ; + abstract operator +(core::int i) → self::C?; + get cProperty() → core::int + ; +} +static method direct_assignment(core::int? i, core::int? j) → dynamic + ; +static method compound_assignment(self::C? c, core::int i) → dynamic + ; +static method via_postfix_op(self::C? c) → dynamic + ; +static method via_prefix_op(self::C? c) → dynamic + ; +static method via_for_each_statement(core::int? i, core::List list) → dynamic + ; +static method via_for_each_list_element(core::int? i, core::List list) → dynamic + ; +static method via_for_each_set_element(core::int? i, core::List list) → dynamic + ; +static method via_for_each_map_key(core::int? i, core::List list) → dynamic + ; +static method via_for_each_map_value(core::int? i, core::List list) → dynamic + ; diff --git a/pkg/front_end/testcases/nnbd/why_not_promoted.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/why_not_promoted.dart.strong.transformed.expect new file mode 100644 index 00000000000..0f16aa128b1 --- /dev/null +++ b/pkg/front_end/testcases/nnbd/why_not_promoted.dart.strong.transformed.expect @@ -0,0 +1,236 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:15:5: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +// Try accessing using ?. instead. +// i.isEven; +// ^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:14:3: Context: Variable 'i' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// i = j; +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:21:5: Error: Property 'cProperty' cannot be accessed on 'C?' because it is potentially null. +// - 'C' is from 'pkg/front_end/testcases/nnbd/why_not_promoted.dart'. +// Try accessing using ?. instead. +// c.cProperty; +// ^^^^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:20:3: Context: Variable 'c' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// c += i; +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:27:5: Error: Property 'cProperty' cannot be accessed on 'C?' because it is potentially null. +// - 'C' is from 'pkg/front_end/testcases/nnbd/why_not_promoted.dart'. +// Try accessing using ?. instead. +// c.cProperty; +// ^^^^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:26:3: Context: Variable 'c' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// c++; +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:33:5: Error: Property 'cProperty' cannot be accessed on 'C?' because it is potentially null. +// - 'C' is from 'pkg/front_end/testcases/nnbd/why_not_promoted.dart'. +// Try accessing using ?. instead. +// c.cProperty; +// ^^^^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:32:5: Context: Variable 'c' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// ++c; +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:39:7: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +// Try accessing using ?. instead. +// i.isEven; +// ^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:38:8: Context: Variable 'i' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// for (i in list) { +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:45:22: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +// Try accessing using ?. instead. +// [for (i in list) i.isEven]; +// ^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:45:9: Context: Variable 'i' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// [for (i in list) i.isEven]; +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:50:23: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +// Try accessing using ?. instead. +// ({for (i in list) i.isEven}); +// ^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:50:10: Context: Variable 'i' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// ({for (i in list) i.isEven}); +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:55:23: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +// Try accessing using ?. instead. +// ({for (i in list) i.isEven: null}); +// ^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:55:10: Context: Variable 'i' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// ({for (i in list) i.isEven: null}); +// ^ +// +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:60:29: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +// Try accessing using ?. instead. +// ({for (i in list) null: i.isEven}); +// ^^^^^^ +// pkg/front_end/testcases/nnbd/why_not_promoted.dart:60:10: Context: Variable 'i' could not be promoted due to an assignment. +// Try null checking the variable after the assignment. See http://dart.dev/go/non-promo-write +// ({for (i in list) null: i.isEven}); +// ^ +// +import self as self; +import "dart:core" as core; +import "dart:_compact_hash" as _co; + +abstract class C extends core::Object { + synthetic constructor •() → self::C + : super core::Object::•() + ; + abstract operator +(core::int i) → self::C?; + get cProperty() → core::int + return 0; +} +static method direct_assignment(core::int? i, core::int? j) → dynamic { + if(i == null) + return; + i = j; + invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:15:5: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +Try accessing using ?. instead. + i.isEven; + ^^^^^^" in i.{core::int::isEven}{}.{core::bool}; +} +static method compound_assignment(self::C? c, core::int i) → dynamic { + if(c == null) + return; + c = c{self::C}.{self::C::+}(i){(core::int) → self::C?}; + invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:21:5: Error: Property 'cProperty' cannot be accessed on 'C?' because it is potentially null. + - 'C' is from 'pkg/front_end/testcases/nnbd/why_not_promoted.dart'. +Try accessing using ?. instead. + c.cProperty; + ^^^^^^^^^" in c.{self::C::cProperty}{}.{core::int}; +} +static method via_postfix_op(self::C? c) → dynamic { + if(c == null) + return; + c = c{self::C}.{self::C::+}(1){(core::int) → self::C?}; + invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:27:5: Error: Property 'cProperty' cannot be accessed on 'C?' because it is potentially null. + - 'C' is from 'pkg/front_end/testcases/nnbd/why_not_promoted.dart'. +Try accessing using ?. instead. + c.cProperty; + ^^^^^^^^^" in c.{self::C::cProperty}{}.{core::int}; +} +static method via_prefix_op(self::C? c) → dynamic { + if(c == null) + return; + c = c{self::C}.{self::C::+}(1){(core::int) → self::C?}; + invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:33:5: Error: Property 'cProperty' cannot be accessed on 'C?' because it is potentially null. + - 'C' is from 'pkg/front_end/testcases/nnbd/why_not_promoted.dart'. +Try accessing using ?. instead. + c.cProperty; + ^^^^^^^^^" in c.{self::C::cProperty}{}.{core::int}; +} +static method via_for_each_statement(core::int? i, core::List list) → dynamic { + if(i == null) + return; + { + synthesized core::Iterator :sync-for-iterator = list.{core::Iterable::iterator}{core::Iterator}; + for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) { + final core::int? #t1 = :sync-for-iterator.{core::Iterator::current}{core::int?}; + { + i = #t1; + invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:39:7: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +Try accessing using ?. instead. + i.isEven; + ^^^^^^" in i.{core::int::isEven}{}.{core::bool}; + } + } + } +} +static method via_for_each_list_element(core::int? i, core::List list) → dynamic { + if(i == null) + return; + { + final core::List #t2 = core::_GrowableList::•(0); + { + synthesized core::Iterator :sync-for-iterator = list.{core::Iterable::iterator}{core::Iterator}; + for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) { + final core::int? #t3 = :sync-for-iterator.{core::Iterator::current}{core::int?}; + { + i = #t3; + #t2.{core::List::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:45:22: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +Try accessing using ?. instead. + [for (i in list) i.isEven]; + ^^^^^^" in i.{core::int::isEven}{}.{core::bool}){(core::bool) → void}; + } + } + } + } +} +static method via_for_each_set_element(core::int? i, core::List list) → dynamic { + if(i == null) + return; + { + final core::Set #t4 = new _co::_Set::•(); + { + synthesized core::Iterator :sync-for-iterator = list.{core::Iterable::iterator}{core::Iterator}; + for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) { + final core::int? #t5 = :sync-for-iterator.{core::Iterator::current}{core::int?}; + { + i = #t5; + #t4.{core::Set::add}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:50:23: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +Try accessing using ?. instead. + ({for (i in list) i.isEven}); + ^^^^^^" in i.{core::int::isEven}{}.{core::bool}){(core::bool) → core::bool}; + } + } + } + } +} +static method via_for_each_map_key(core::int? i, core::List list) → dynamic { + if(i == null) + return; + { + final core::Map #t6 = {}; + { + synthesized core::Iterator :sync-for-iterator = list.{core::Iterable::iterator}{core::Iterator}; + for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) { + final core::int? #t7 = :sync-for-iterator.{core::Iterator::current}{core::int?}; + { + i = #t7; + #t6.{core::Map::[]=}{Invariant}(invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:55:23: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +Try accessing using ?. instead. + ({for (i in list) i.isEven: null}); + ^^^^^^" in i.{core::int::isEven}{}.{core::bool}, null){(core::bool, Null) → void}; + } + } + } + } +} +static method via_for_each_map_value(core::int? i, core::List list) → dynamic { + if(i == null) + return; + { + final core::Map #t8 = {}; + { + synthesized core::Iterator :sync-for-iterator = list.{core::Iterable::iterator}{core::Iterator}; + for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) { + final core::int? #t9 = :sync-for-iterator.{core::Iterator::current}{core::int?}; + { + i = #t9; + #t8.{core::Map::[]=}{Invariant}(null, invalid-expression "pkg/front_end/testcases/nnbd/why_not_promoted.dart:60:29: Error: Property 'isEven' cannot be accessed on 'int?' because it is potentially null. +Try accessing using ?. instead. + ({for (i in list) null: i.isEven}); + ^^^^^^" in i.{core::int::isEven}{}.{core::bool}){(Null, core::bool) → void}; + } + } + } + } +} diff --git a/pkg/front_end/testcases/nnbd/why_not_promoted.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/why_not_promoted.dart.textual_outline.expect new file mode 100644 index 00000000000..e0d0f81a7f4 --- /dev/null +++ b/pkg/front_end/testcases/nnbd/why_not_promoted.dart.textual_outline.expect @@ -0,0 +1,22 @@ +abstract class C { + C? operator +(int i); + int get cProperty => 0; +} + +direct_assignment(int? i, int? j) {} + +compound_assignment(C? c, int i) {} + +via_postfix_op(C? c) {} + +via_prefix_op(C? c) {} + +via_for_each_statement(int? i, List list) {} + +via_for_each_list_element(int? i, List list) {} + +via_for_each_set_element(int? i, List list) {} + +via_for_each_map_key(int? i, List list) {} + +via_for_each_map_value(int? i, List list) {} diff --git a/pkg/front_end/testcases/nnbd/why_not_promoted.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/why_not_promoted.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..0eb08cacbe2 --- /dev/null +++ b/pkg/front_end/testcases/nnbd/why_not_promoted.dart.textual_outline_modelled.expect @@ -0,0 +1,22 @@ +abstract class C { + C? operator +(int i); + int get cProperty => 0; +} + +compound_assignment(C? c, int i) {} + +direct_assignment(int? i, int? j) {} + +via_for_each_list_element(int? i, List list) {} + +via_for_each_map_key(int? i, List list) {} + +via_for_each_map_value(int? i, List list) {} + +via_for_each_set_element(int? i, List list) {} + +via_for_each_statement(int? i, List list) {} + +via_postfix_op(C? c) {} + +via_prefix_op(C? c) {} diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md index 7787fb722e1..ea049591981 100644 --- a/pkg/kernel/binary.md +++ b/pkg/kernel/binary.md @@ -147,7 +147,7 @@ type CanonicalName { type ComponentFile { UInt32 magic = 0x90ABCDEF; - UInt32 formatVersion = 131; + UInt32 formatVersion = 132; Byte[10] shortSdkHash; List problemsAsJson; // Described in problems.md. Library[] libraries; @@ -1743,6 +1743,7 @@ type AssignedVariablePattern extends Pattern { Byte tag = 129; FileOffset fileOffset; VariableReference variable; + Option setter; Option matchedType; Byte needsCast; } diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart index 9521e184da5..d93ad34d87b 100644 --- a/pkg/kernel/lib/binary/ast_from_binary.dart +++ b/pkg/kernel/lib/binary/ast_from_binary.dart @@ -2237,6 +2237,10 @@ class BinaryBuilder { variableStack.addAll(variables); } + Variable? readVariableReferenceOption() { + return readAndCheckOptionTag() ? readVariableReference() : null; + } + Variable readVariableReference() { readUInt30(); // offset of the variable declaration in the binary. return _readVariableReferenceInternal(); @@ -3311,12 +3315,14 @@ class BinaryBuilder { AssignedVariablePattern _readAssignedVariablePattern() { int fileOffset = readOffset(); Variable variable = readVariableReference(); + Variable? setter = readVariableReferenceOption(); DartType? matchedType = readDartTypeOption(); bool needsCheck = readByte() == 1; return AssignedVariablePattern(variable) ..fileOffset = fileOffset ..matchedValueType = matchedType - ..needsCast = needsCheck; + ..needsCast = needsCheck + ..setter = setter; } CastPattern _readCastPattern() { diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart index 744c43d7637..eb9c1aea24d 100644 --- a/pkg/kernel/lib/binary/ast_to_binary.dart +++ b/pkg/kernel/lib/binary/ast_to_binary.dart @@ -2864,6 +2864,15 @@ class BinaryPrinter writeNode(node.receiver); } + void _writeVariableReferenceOption(Variable? variable) { + if (variable == null) { + writeByte(Tag.Nothing); + } else { + writeByte(Tag.Something); + _writeVariableReference(variable); + } + } + void _writeVariableReference(Variable variable) { int index = _getVariableIndex(variable); writeUInt30(variable.binaryOffsetNoTag); @@ -2883,6 +2892,7 @@ class BinaryPrinter writeByte(Tag.AssignedVariablePattern); writeOffset(node.fileOffset); _writeVariableReference(node.variable); + _writeVariableReferenceOption(node.setter); writeOptionalNode(node.matchedValueType); writeByte(node.needsCast ? 1 : 0); } diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart index 0d6fb1b1c4d..161a00b114c 100644 --- a/pkg/kernel/lib/binary/tag.dart +++ b/pkg/kernel/lib/binary/tag.dart @@ -237,7 +237,7 @@ class Tag { /// Internal version of kernel binary format. /// Bump it when making incompatible changes in kernel binaries. /// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md. - static const int BinaryFormatVersion = 131; + static const int BinaryFormatVersion = 132; } abstract class ConstantTag { diff --git a/pkg/kernel/lib/src/ast/patterns.dart b/pkg/kernel/lib/src/ast/patterns.dart index 9a0800c5a9c..9ab740fbb5a 100644 --- a/pkg/kernel/lib/src/ast/patterns.dart +++ b/pkg/kernel/lib/src/ast/patterns.dart @@ -871,6 +871,10 @@ class WildcardPattern extends Pattern { class AssignedVariablePattern extends Pattern { final Variable variable; + /// If [variable] is a lowered late variable, [setter] holds the variable of + /// the local function that should be used for assignment. + Variable? setter; + /// The type of the expression against which this pattern is matched. /// /// This is set during inference. diff --git a/pkg/kernel/lib/src/equivalence.dart b/pkg/kernel/lib/src/equivalence.dart index 1f6b87c9469..18172d0d1ab 100644 --- a/pkg/kernel/lib/src/equivalence.dart +++ b/pkg/kernel/lib/src/equivalence.dart @@ -4996,6 +4996,9 @@ class EquivalenceStrategy { if (!checkAssignedVariablePattern_variable(visitor, node, other)) { result = visitor.resultOnInequivalence; } + if (!checkAssignedVariablePattern_setter(visitor, node, other)) { + result = visitor.resultOnInequivalence; + } if (!checkAssignedVariablePattern_matchedValueType(visitor, node, other)) { result = visitor.resultOnInequivalence; } @@ -11972,6 +11975,14 @@ class EquivalenceStrategy { return visitor.checkNodes(node.variable, other.variable, 'variable'); } + bool checkAssignedVariablePattern_setter( + EquivalenceVisitor visitor, + AssignedVariablePattern node, + AssignedVariablePattern other, + ) { + return visitor.checkNodes(node.setter, other.setter, 'setter'); + } + bool checkAssignedVariablePattern_matchedValueType( EquivalenceVisitor visitor, AssignedVariablePattern node, diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_basic.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_basic.dart.expect index 7014027f5ab..53f1c940c57 100644 --- a/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_basic.dart.expect +++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_basic.dart.expect @@ -12,13 +12,13 @@ RESULT: t3 %this = _Parameter #0 [_T (#lib::C)+] %x = _Parameter #1 t2 = _Extract (%this[#lib::C/0]) -t3 = _TypeCheck (%x against t2) (for #lib::C.T% x) +t3 = _TypeCheck (%x against t2) (for #lib::C.T% x;) RESULT: t3 ------------ C.id2 ------------ %this = _Parameter #0 [_T (#lib::C)+] %x = _Parameter #1 t2 = _Extract (%this[#lib::C/0]) -t3 = _TypeCheck (%x against t2) (for #lib::C.T% x) +t3 = _TypeCheck (%x against t2) (for #lib::C.T% x;) RESULT: t3 ------------ D. ------------ %this = _Parameter #0 [_T (#lib::D)+] @@ -77,7 +77,7 @@ RESULT: _T {} %x = _Parameter #1 t2 = _Extract (%this[#lib::C2/0]) t3 = _CreateRuntimeType (dart.core::Comparable @ (t2)) -t4 = _TypeCheck (%x against t3) (for dart.core::Comparable<#lib::C2.T%> x) +t4 = _TypeCheck (%x against t3) (for dart.core::Comparable<#lib::C2.T%> x;) RESULT: t4 ------------ C2.id4 ------------ %this = _Parameter #0 [_T (#lib::C2)+] @@ -85,7 +85,7 @@ RESULT: t4 t2 = _Extract (%this[#lib::C2/0]) t3 = _CreateRuntimeType (#lib::I @ (t2)) t4 = _CreateRuntimeType (#lib::K @ (t3)) -t5 = _TypeCheck (%x against t4) (for #lib::K<#lib::I<#lib::C2.T%>> x) +t5 = _TypeCheck (%x against t4) (for #lib::K<#lib::I<#lib::C2.T%>> x;) RESULT: t5 ------------ main ------------ t0* = _Call direct [#lib::C.] (_T (#lib::C)) diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart.expect index eb3653813e3..f15002efc11 100644 --- a/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart.expect +++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/class_generics_case1.dart.expect @@ -17,9 +17,9 @@ RESULT: _T {} %key = _Parameter #1 %value = _Parameter #2 t3 = _Extract (%this[#lib::_NotRealHashMap/0]) -t4 = _TypeCheck (%key against t3) (for #lib::_NotRealHashMap.K% key) +t4 = _TypeCheck (%key against t3) (for #lib::_NotRealHashMap.K% key;) t5 = _Extract (%this[#lib::_NotRealHashMap/1]) -t6 = _TypeCheck (%value against t5) (for #lib::_NotRealHashMap.V% value) +t6 = _TypeCheck (%value against t5) (for #lib::_NotRealHashMap.V% value;) RESULT: _T {}? ------------ InheritedElement. ------------ %this = _Parameter #0 [_T (#lib::InheritedElement)+] diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h index ec7276c0466..018690f15e5 100644 --- a/runtime/vm/kernel_binary.h +++ b/runtime/vm/kernel_binary.h @@ -18,7 +18,7 @@ namespace kernel { // package:kernel/binary.md. static const uint32_t kMagicProgramFile = 0x90ABCDEFu; -static const uint32_t kSupportedKernelFormatVersion = 131; +static const uint32_t kSupportedKernelFormatVersion = 132; // Keep in sync with package:kernel/lib/binary/tag.dart #define KERNEL_TAG_LIST(V) \