diff --git a/pkg/front_end/lib/src/fragment/primary_constructor_field.dart b/pkg/front_end/lib/src/fragment/primary_constructor_field.dart index d02021f80be..58f98b0c2b4 100644 --- a/pkg/front_end/lib/src/fragment/primary_constructor_field.dart +++ b/pkg/front_end/lib/src/fragment/primary_constructor_field.dart @@ -436,7 +436,6 @@ class PrimaryConstructorFieldDeclaration } @override - // Coverage-ignore(suite): Not run. void setCovariantByClassInternal() { _encoding.setCovariantByClass(); } diff --git a/pkg/front_end/lib/src/kernel/body_builder.dart b/pkg/front_end/lib/src/kernel/body_builder.dart index 9a6235e7ccc..da0956b2c72 100644 --- a/pkg/front_end/lib/src/kernel/body_builder.dart +++ b/pkg/front_end/lib/src/kernel/body_builder.dart @@ -5813,12 +5813,47 @@ class BodyBuilderImpl extends StackListenerImpl // Coverage-ignore(suite): Not run. stackTrace.kind == FormalParameterKind.optionalPositional, ); + + CatchVariable? exceptionVariable; + if (exception?.variable + case VariableDeclaration exceptionVariableDeclaration) { + if (isClosureContextLoweringEnabled) { + // Coverage-ignore-block(suite): Not run. + // TODO(62743): Avoid the conversion when [FormalParameterBuilder] + // produces [CatchVariable]s directly. + exceptionVariable = new CatchVariable( + name: exceptionVariableDeclaration.name!, + type: exceptionVariableDeclaration.type, + isWildcard: exceptionVariableDeclaration.isWildcard, + ); + } else { + exceptionVariable = exceptionVariableDeclaration; + } + } + + CatchVariable? stackTraceVariable; + if (stackTrace?.variable + case VariableDeclaration stackTraceVariableDeclaration) { + if (isClosureContextLoweringEnabled) { + // Coverage-ignore-block(suite): Not run. + // TODO(62743): Avoid the conversion when [FormalParameterBuilder] + // produces [CatchVariable]s directly. + stackTraceVariable = new CatchVariable( + name: stackTraceVariableDeclaration.name!, + type: stackTraceVariableDeclaration.type, + isWildcard: stackTraceVariableDeclaration.isWildcard, + ); + } else { + stackTraceVariable = stackTraceVariableDeclaration; + } + } + push( forest.createCatch( offsetForToken(onKeyword ?? catchKeyword), exceptionType, - exception?.variable, - stackTrace?.variable, + exceptionVariable, + stackTraceVariable, coreTypes.stackTraceRawType(Nullability.nonNullable), body, ), diff --git a/pkg/front_end/lib/src/kernel/forest.dart b/pkg/front_end/lib/src/kernel/forest.dart index 890795ff41b..b169e0155a6 100644 --- a/pkg/front_end/lib/src/kernel/forest.dart +++ b/pkg/front_end/lib/src/kernel/forest.dart @@ -450,8 +450,8 @@ class Forest { Catch createCatch( int fileOffset, DartType exceptionType, - VariableDeclaration? exceptionParameter, - VariableDeclaration? stackTraceParameter, + CatchVariable? exceptionParameter, + CatchVariable? stackTraceParameter, DartType stackTraceType, Statement body, ) { diff --git a/pkg/front_end/lib/src/kernel/internal_ast.dart b/pkg/front_end/lib/src/kernel/internal_ast.dart index bf44a070631..17663257565 100644 --- a/pkg/front_end/lib/src/kernel/internal_ast.dart +++ b/pkg/front_end/lib/src/kernel/internal_ast.dart @@ -1075,10 +1075,6 @@ class InternalPositionalParameter extends TreeNode @override final bool isLocalFunction; - @override - // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. - List? contexts; - InternalPositionalParameter({ required this.astVariable, required this.isImplicitlyTyped, @@ -1086,6 +1082,30 @@ class InternalPositionalParameter extends TreeNode this.isLocalFunction = false, }); + @override + // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. + List? get contexts { + throw new UnsupportedError("${this.runtimeType}.contexts"); + } + + @override + // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. + void set contexts(List? value) { + throw new UnsupportedError("${this.runtimeType}.contexts="); + } + + @override + // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. + String get catchVariableName { + throw new UnsupportedError("${this.runtimeType}.catchVariableName"); + } + + @override + // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. + void set catchVariableName(String value) { + throw new UnsupportedError("${this.runtimeType}.catchVariableName="); + } + @override R accept(StatementVisitor v) => v.visitPositionalParameter(astVariable); @@ -1170,10 +1190,6 @@ class InternalNamedParameter extends TreeNode @override final bool isLocalFunction; - @override - // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. - List? contexts; - InternalNamedParameter({ required this.astVariable, required this.isImplicitlyTyped, @@ -1181,6 +1197,30 @@ class InternalNamedParameter extends TreeNode this.isLocalFunction = false, }); + @override + // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. + List? get contexts { + throw new UnsupportedError("${this.runtimeType}.contexts"); + } + + @override + // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. + void set contexts(List? value) { + throw new UnsupportedError("${this.runtimeType}.contexts="); + } + + @override + // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. + String get catchVariableName { + throw new UnsupportedError("${this.runtimeType}.catchVariableName"); + } + + @override + // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. + void set catchVariableName(String value) { + throw new UnsupportedError("${this.runtimeType}.catchVariableName="); + } + @override R accept(StatementVisitor v) => v.visitNamedParameter(astVariable); diff --git a/pkg/front_end/lib/src/source/check_helper.dart b/pkg/front_end/lib/src/source/check_helper.dart index 22941cf20a1..c8a2f6cb938 100644 --- a/pkg/front_end/lib/src/source/check_helper.dart +++ b/pkg/front_end/lib/src/source/check_helper.dart @@ -1112,7 +1112,6 @@ extension CheckHelper on ProblemReporting { nameToken.length, ); } else { - // Coverage-ignore-block(suite): Not run. addProblem( diag.privateNamedParameter, nameToken.charOffset, 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 edea04a859c..bc5cc7036d3 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 @@ -3269,7 +3269,6 @@ abstract class InferenceVisitorBase implements InferenceVisitor { case ObjectAccessTargetKind.nullableInstanceMember: kind = InstanceAccessKind.Nullable; break; - // Coverage-ignore(suite): Not run. case ObjectAccessTargetKind.objectMember: kind = InstanceAccessKind.Object; break; @@ -3392,9 +3391,7 @@ abstract class InferenceVisitorBase implements InferenceVisitor { )..fileOffset = nullAwareAction.fileOffset, ); } else if (nullAwareAction is DynamicInvocation && - // Coverage-ignore(suite): Not run. nullAwareAction.receiver == originalPropertyGet) { - // Coverage-ignore-block(suite): Not run. invocationResult = new ExpressionInferenceResult( invocationResult.inferredType, new InstanceGetterInvocation( diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt index 92d869f58da..4c05e9f202e 100644 --- a/pkg/front_end/test/spell_checking_list_common.txt +++ b/pkg/front_end/test/spell_checking_list_common.txt @@ -2346,6 +2346,7 @@ popping pops populate populated +populating port portion position diff --git a/pkg/front_end/tool/ast_model.dart b/pkg/front_end/tool/ast_model.dart index 3a2a30739e6..ddbbf4606b6 100644 --- a/pkg/front_end/tool/ast_model.dart +++ b/pkg/front_end/tool/ast_model.dart @@ -134,8 +134,8 @@ const Map> _fieldRuleMap = { 'SwitchStatement': {'cases': FieldRule(isDeclaration: true)}, 'ContinueSwitchStatement': {'target': FieldRule(isDeclaration: false)}, 'Catch': { - 'exception': FieldRule(isDeclaration: true), - 'stackTrace': FieldRule(isDeclaration: true), + 'exceptionCatchVariable': FieldRule(isDeclaration: true), + 'stackTraceCatchVariable': FieldRule(isDeclaration: true), }, 'FunctionDeclaration': {'variable': FieldRule(isDeclaration: true)}, 'FunctionType': {'typeParameters': FieldRule(isDeclaration: true)}, diff --git a/pkg/kernel/lib/src/ast/dummies.dart b/pkg/kernel/lib/src/ast/dummies.dart index d3dfd2ca14c..dabfcb5908c 100644 --- a/pkg/kernel/lib/src/ast/dummies.dart +++ b/pkg/kernel/lib/src/ast/dummies.dart @@ -374,6 +374,14 @@ final List emptyListOfMapPatternEntry = final VariableDeclaration dummyVariableDeclaration = new VariableDeclaration(null, isSynthesized: true); +/// Non-nullable [CatchVariable] dummy value. +/// +/// This is used as the removal sentinel in [RemovingTransformer] and can be +/// used for instance as a dummy initial value for the `List.filled` +/// constructor. +final CatchVariable dummyCatchVariable = + new CatchVariable(name: "#dummy-catch-variable", type: const DynamicType()); + /// Non-nullable [PositionalParameter] dummy value. /// /// This is used as the removal sentinel in [RemovingTransformer] and can be diff --git a/pkg/kernel/lib/src/ast/expressions.dart b/pkg/kernel/lib/src/ast/expressions.dart index 0750278e700..4da41265239 100644 --- a/pkg/kernel/lib/src/ast/expressions.dart +++ b/pkg/kernel/lib/src/ast/expressions.dart @@ -188,9 +188,6 @@ class InvalidExpression extends Expression { } class VariableGet extends Expression { - /// The target variable as [VariableDeclaration]. - VariableDeclaration get variable => expressionVariable as VariableDeclaration; - /// The target variable. ExpressionVariable expressionVariable; @@ -199,6 +196,9 @@ class VariableGet extends Expression { VariableGet(this.expressionVariable, [this.promotedType]); + /// The target variable as [VariableDeclaration]. + VariableDeclaration get variable => expressionVariable as VariableDeclaration; + @override DartType getStaticType(StaticTypeContext context) => getStaticTypeInternal(context); diff --git a/pkg/kernel/lib/src/ast/statements.dart b/pkg/kernel/lib/src/ast/statements.dart index 1e2ca865c3e..725765ebfaf 100644 --- a/pkg/kernel/lib/src/ast/statements.dart +++ b/pkg/kernel/lib/src/ast/statements.dart @@ -1195,20 +1195,35 @@ class TryCatch extends Statement { class Catch extends TreeNode implements ScopeProvider { DartType guard; // Not null, defaults to dynamic. - VariableDeclaration? exception; - VariableDeclaration? stackTrace; + CatchVariable? exceptionCatchVariable; + CatchVariable? stackTraceCatchVariable; Statement body; @override Scope? scope; - Catch(this.exception, this.body, - {this.guard = const DynamicType(), this.stackTrace}) { - exception?.parent = this; - stackTrace?.parent = this; + Catch(this.exceptionCatchVariable, this.body, + {this.guard = const DynamicType(), CatchVariable? stackTrace}) + : stackTraceCatchVariable = stackTrace { + exceptionCatchVariable?.parent = this; + stackTraceCatchVariable?.parent = this; body.parent = this; } + VariableDeclaration? get exception => + exceptionCatchVariable as VariableDeclaration?; + + void set exception(VariableDeclaration? value) { + exceptionCatchVariable = value; + } + + VariableDeclaration? get stackTrace => + stackTraceCatchVariable as VariableDeclaration?; + + void set stackTrace(VariableDeclaration? value) { + stackTraceCatchVariable = value; + } + @override R accept(TreeVisitor v) => v.visitCatch(this); @@ -1218,21 +1233,21 @@ class Catch extends TreeNode implements ScopeProvider { @override void visitChildren(Visitor v) { guard.accept(v); - exception?.accept(v); - stackTrace?.accept(v); + exceptionCatchVariable?.accept(v); + stackTraceCatchVariable?.accept(v); body.accept(v); } @override void transformChildren(Transformer v) { guard = v.visitDartType(guard); - if (exception != null) { - exception = v.transform(exception!); - exception?.parent = this; + if (exceptionCatchVariable != null) { + exceptionCatchVariable = v.transform(exceptionCatchVariable!); + exceptionCatchVariable?.parent = this; } - if (stackTrace != null) { - stackTrace = v.transform(stackTrace!); - stackTrace?.parent = this; + if (stackTraceCatchVariable != null) { + stackTraceCatchVariable = v.transform(stackTraceCatchVariable!); + stackTraceCatchVariable?.parent = this; } body = v.transform(body); body.parent = this; @@ -1241,13 +1256,15 @@ class Catch extends TreeNode implements ScopeProvider { @override void transformOrRemoveChildren(RemovingTransformer v) { guard = v.visitDartType(guard, cannotRemoveSentinel); - if (exception != null) { - exception = v.transformOrRemoveVariableDeclaration(exception!); - exception?.parent = this; + if (exceptionCatchVariable != null) { + exceptionCatchVariable = + v.transformOrRemoveCatchVariable(exceptionCatchVariable!); + exceptionCatchVariable?.parent = this; } - if (stackTrace != null) { - stackTrace = v.transformOrRemoveVariableDeclaration(stackTrace!); - stackTrace?.parent = this; + if (stackTraceCatchVariable != null) { + stackTraceCatchVariable = + v.transformOrRemoveCatchVariable(stackTraceCatchVariable!); + stackTraceCatchVariable?.parent = this; } body = v.transform(body); body.parent = this; @@ -1425,7 +1442,8 @@ abstract interface class VariableDeclaration Annotatable, Statement, ExpressionVariable, - VariableInitialization { + VariableInitialization, + CatchVariable { /// The name of the variable as provided in the source code. /// /// The name of a variable can only be omitted if the variable is synthesized. @@ -1634,10 +1652,6 @@ class VariableStatement extends Statement implements VariableDeclaration { @override Expression? initializer; // May be null. - @override - // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. - List? contexts; - VariableStatement(this._name, {this.initializer, this.type = const DynamicType(), @@ -1707,6 +1721,30 @@ class VariableStatement extends Statement implements VariableDeclaration { _name = value; } + @override + // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. + List? get contexts { + throw new UnsupportedError("${this.runtimeType}.contexts"); + } + + @override + // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. + void set contexts(List? value) { + throw new UnsupportedError("${this.runtimeType}.contexts="); + } + + @override + // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. + String get catchVariableName { + throw new UnsupportedError("${this.runtimeType}.catchVariableName"); + } + + @override + // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. + void set catchVariableName(String value) { + throw new UnsupportedError("${this.runtimeType}.catchVariableName="); + } + static const int FlagFinal = 1 << 0; // Must match serialized bit positions. static const int FlagConst = 1 << 1; static const int FlagHasDeclaredInitializer = 1 << 2; diff --git a/pkg/kernel/lib/src/ast/variables.dart b/pkg/kernel/lib/src/ast/variables.dart index a2b1aecfb7e..efe54a82794 100644 --- a/pkg/kernel/lib/src/ast/variables.dart +++ b/pkg/kernel/lib/src/ast/variables.dart @@ -411,6 +411,282 @@ class LocalVariable extends ExpressionVariable { bool get hasIsErroneouslyInitialized => false; } +/// Since the `catch` block isn't invoked by the user code, but is redirected to +/// by the runtime, its parameters, the exception and the stack trace, +/// represented by `e` and `s` in the example below, are filled in by the +/// runtime too. The semantics of populating the variables makes them distinct +/// from function parameters, and they have a separate representation from them. +/// +/// try { +/// foo(); +/// } catch (e, s) { +/// bar(); +/// } +class CatchVariable extends ExpressionVariable { + String catchVariableName; + + @override + DartType type; + + @override + List annotations = const []; + + CatchVariable({ + required String name, + required DartType? type, + bool isWildcard = false, + }) : catchVariableName = name, + type = type ?? const DynamicType() { + this.isWildcard = isWildcard; + } + + @override + String? get cosmeticName => catchVariableName; + + @override + void set cosmeticName(String? value) { + catchVariableName = value!; + } + + @override + VariableInitialization? get variableInitialization { + throw new UnsupportedError("${this.runtimeType}.variableInitialization"); + } + + @override + void set variableInitialization(VariableInitialization? value) { + throw new UnsupportedError("${this.runtimeType}.variableInitialization="); + } + + @override + void addAnnotation(Expression annotation) { + if (annotations.isEmpty) { + annotations = []; + } + annotations.add(annotation..parent = this); + } + + static const int FlagWildcard = 1 << 0; + + @override + bool get isFinal => true; + + @override + void set isFinal(bool value) { + throw new UnsupportedError("${this.runtimeType}.isFinal="); + } + + @override + bool get isWildcard => flags & FlagWildcard != 0; + + @override + void set isWildcard(bool value) { + flags = value ? (flags | FlagWildcard) : (flags & ~FlagWildcard); + } + + @override + bool get isConst { + throw new UnsupportedError("${this.runtimeType}.isConst"); + } + + @override + void set isConst(bool value) { + throw new UnsupportedError("${this.runtimeType}.isConst="); + } + + @override + bool get isLate { + throw new UnsupportedError("${this.runtimeType}.isLate"); + } + + @override + void set isLate(bool value) { + throw new UnsupportedError("${this.runtimeType}.isLate="); + } + + @override + bool get isLowered { + throw new UnsupportedError("${this.runtimeType}.isLowered"); + } + + @override + void set isLowered(bool value) { + throw new UnsupportedError("${this.runtimeType}.isLowered="); + } + + @override + bool get isHoisted { + throw new UnsupportedError("${this.runtimeType}.isHoisted"); + } + + @override + void set isHoisted(bool value) { + throw new UnsupportedError("${this.runtimeType}.isHoisted="); + } + + @override + bool get isCovariantByClass { + throw new UnsupportedError("${this.runtimeType}.isCovariantByClass"); + } + + @override + void set isCovariantByClass(bool value) { + throw new UnsupportedError("${this.runtimeType}.isCovariantByClass="); + } + + @override + bool get isCovariantByDeclaration { + throw new UnsupportedError("${this.runtimeType}.isCovariantByDeclaration"); + } + + @override + void set isCovariantByDeclaration(bool value) { + throw new UnsupportedError("${this.runtimeType}.isCovariantByDeclaration="); + } + + @override + bool get isErroneouslyInitialized { + throw new UnsupportedError("${this.runtimeType}.isErroneouslyInitialized"); + } + + @override + void set isErroneouslyInitialized(bool value) { + throw new UnsupportedError("${this.runtimeType}.isErroneouslyInitialized="); + } + + @override + bool get hasDeclaredInitializer { + throw new UnsupportedError("${this.runtimeType}.hasDeclaredInitializer"); + } + + @override + void set hasDeclaredInitializer(bool value) { + throw new UnsupportedError("${this.runtimeType}.hasDeclaredInitializer="); + } + + @override + bool get isInitializingFormal { + throw new UnsupportedError("${this.runtimeType}.isInitializingFormal"); + } + + @override + void set isInitializingFormal(bool value) { + throw new UnsupportedError("${this.runtimeType}.isInitializingFormal="); + } + + @override + bool get isRequired { + throw new UnsupportedError("${this.runtimeType}.isRequired"); + } + + @override + void set isRequired(bool value) { + throw new UnsupportedError("${this.runtimeType}.isRequired="); + } + + @override + bool get isSuperInitializingFormal { + throw new UnsupportedError("${this.runtimeType}.isSuperInitializingFormal"); + } + + @override + void set isSuperInitializingFormal(bool value) { + throw new UnsupportedError( + "${this.runtimeType}.isSuperInitializingFormal="); + } + + @override + bool get isSynthesized { + throw new UnsupportedError("${this.runtimeType}.isSynthesized"); + } + + @override + void set isSynthesized(bool value) { + throw new UnsupportedError("${this.runtimeType}.isSynthesized="); + } + + @override + bool get isAssignable => false; + + @override + R accept(TreeVisitor v) => v.visitCatchVariable(this); + + @override + R accept1(TreeVisitor1 v, A arg) => + v.visitCatchVariable(this, arg); + + @override + void transformChildren(Transformer v) {} + + @override + void transformOrRemoveChildren(RemovingTransformer v) {} + + @override + void visitChildren(Visitor v) {} + + @override + String toString() { + return "CatchVariable(${toStringInternal()})"; + } + + @override + void toTextInternal(AstPrinter printer) { + printer.writeExpressionVariable(this); + } + + @override + Expression? get initializer { + throw new UnsupportedError("${this.runtimeType}.initializer"); + } + + @override + void set initializer(Expression? value) { + throw new UnsupportedError("${this.runtimeType}.initializer="); + } + + @override + bool get hasIsFinal => false; + + @override + bool get hasIsConst => false; + + @override + bool get hasIsLate => false; + + @override + bool get hasIsInitializingFormal => false; + + @override + bool get hasIsSynthesized => false; + + @override + bool get hasIsHoisted => false; + + @override + bool get hasHasDeclaredInitializer => false; + + @override + bool get hasIsCovariantByClass => false; + + @override + bool get hasIsRequired => false; + + @override + bool get hasIsCovariantByDeclaration => false; + + @override + bool get hasIsLowered => false; + + @override + bool get hasIsWildcard => false; + + @override + bool get hasIsSuperInitializingFormal => false; + + @override + bool get hasIsErroneouslyInitialized => false; +} + /// Abstract parameter class, the parent for positional and named parameters. sealed class FunctionParameter extends ExpressionVariable implements VariableDeclaration { @@ -621,10 +897,6 @@ class PositionalParameter extends FunctionParameter { @override List annotations = const []; - @override - // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. - List? contexts; - PositionalParameter({ this.cosmeticName, required this.type, @@ -640,6 +912,30 @@ class PositionalParameter extends FunctionParameter { super.isWildcard = false, }); + @override + // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. + List? get contexts { + throw new UnsupportedError("${this.runtimeType}.contexts"); + } + + @override + // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. + void set contexts(List? value) { + throw new UnsupportedError("${this.runtimeType}.contexts="); + } + + @override + // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. + String get catchVariableName { + throw new UnsupportedError("${this.runtimeType}.catchVariableName"); + } + + @override + // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. + void set catchVariableName(String value) { + throw new UnsupportedError("${this.runtimeType}.catchVariableName="); + } + @override void addAnnotation(Expression annotation) { if (annotations.isEmpty) { @@ -757,10 +1053,6 @@ class NamedParameter extends FunctionParameter { @override List annotations = const []; - @override - // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. - List? contexts; - NamedParameter( {required this.parameterName, required this.type, @@ -775,6 +1067,30 @@ class NamedParameter extends FunctionParameter { super.isSynthesized = false, super.isWildcard = false}); + @override + // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. + List? get contexts { + throw new UnsupportedError("${this.runtimeType}.contexts"); + } + + @override + // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. + void set contexts(List? value) { + throw new UnsupportedError("${this.runtimeType}.contexts="); + } + + @override + // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. + String get catchVariableName { + throw new UnsupportedError("${this.runtimeType}.catchVariableName"); + } + + @override + // TODO(62620): Conforming to [VariableDeclaration] interface. Remove this. + void set catchVariableName(String value) { + throw new UnsupportedError("${this.runtimeType}.catchVariableName="); + } + @override void addAnnotation(Expression annotation) { if (annotations.isEmpty) { diff --git a/pkg/kernel/lib/src/coverage.dart b/pkg/kernel/lib/src/coverage.dart index d8b66a27d77..4f6a6623333 100644 --- a/pkg/kernel/lib/src/coverage.dart +++ b/pkg/kernel/lib/src/coverage.dart @@ -992,6 +992,12 @@ class CoverageVisitor implements Visitor { node.visitChildren(this); } + @override + void visitCatchVariable(CatchVariable node) { + visited.add(NodeKind.CatchVariable); + node.visitChildren(this); + } + @override void visitLocalVariable(LocalVariable node) { visited.add(NodeKind.LocalVariable); @@ -1327,6 +1333,7 @@ enum ConstantKind { enum NodeKind { Arguments, Catch, + CatchVariable, Class, Combinator, Component, diff --git a/pkg/kernel/lib/src/equivalence.dart b/pkg/kernel/lib/src/equivalence.dart index 95e62b76bee..481476693fa 100644 --- a/pkg/kernel/lib/src/equivalence.dart +++ b/pkg/kernel/lib/src/equivalence.dart @@ -850,6 +850,11 @@ class EquivalenceVisitor implements Visitor1 { return strategy.checkCatch(this, node, other); } + @override + bool visitCatchVariable(CatchVariable node, Node other) { + return strategy.checkCatchVariable(this, node, other); + } + @override bool visitLocalVariable(LocalVariable node, Node other) { return strategy.checkLocalVariable(this, node, other); @@ -5392,9 +5397,6 @@ class EquivalenceStrategy { if (!checkVariableStatement_initializer(visitor, node, other)) { result = visitor.resultOnInequivalence; } - if (!checkVariableStatement_contexts(visitor, node, other)) { - result = visitor.resultOnInequivalence; - } if (!checkVariableStatement_fileOffset(visitor, node, other)) { result = visitor.resultOnInequivalence; } @@ -5451,10 +5453,10 @@ class EquivalenceStrategy { if (!checkCatch_guard(visitor, node, other)) { result = visitor.resultOnInequivalence; } - if (!checkCatch_exception(visitor, node, other)) { + if (!checkCatch_exceptionCatchVariable(visitor, node, other)) { result = visitor.resultOnInequivalence; } - if (!checkCatch_stackTrace(visitor, node, other)) { + if (!checkCatch_stackTraceCatchVariable(visitor, node, other)) { result = visitor.resultOnInequivalence; } if (!checkCatch_body(visitor, node, other)) { @@ -5470,6 +5472,32 @@ class EquivalenceStrategy { return result; } + bool checkCatchVariable( + EquivalenceVisitor visitor, CatchVariable? node, Object? other) { + if (identical(node, other)) return true; + if (node is! CatchVariable) return false; + if (other is! CatchVariable) return false; + visitor.pushNodeState(node, other); + bool result = true; + if (!checkCatchVariable_catchVariableName(visitor, node, other)) { + result = visitor.resultOnInequivalence; + } + if (!checkCatchVariable_type(visitor, node, other)) { + result = visitor.resultOnInequivalence; + } + if (!checkCatchVariable_annotations(visitor, node, other)) { + result = visitor.resultOnInequivalence; + } + if (!checkCatchVariable_flags(visitor, node, other)) { + result = visitor.resultOnInequivalence; + } + if (!checkCatchVariable_fileOffset(visitor, node, other)) { + result = visitor.resultOnInequivalence; + } + visitor.popState(); + return result; + } + bool checkLocalVariable( EquivalenceVisitor visitor, LocalVariable? node, Object? other) { if (identical(node, other)) return true; @@ -5515,9 +5543,6 @@ class EquivalenceStrategy { if (!checkPositionalParameter_annotations(visitor, node, other)) { result = visitor.resultOnInequivalence; } - if (!checkPositionalParameter_contexts(visitor, node, other)) { - result = visitor.resultOnInequivalence; - } if (!checkPositionalParameter_binaryOffsetNoTag(visitor, node, other)) { result = visitor.resultOnInequivalence; } @@ -5553,9 +5578,6 @@ class EquivalenceStrategy { if (!checkNamedParameter_annotations(visitor, node, other)) { result = visitor.resultOnInequivalence; } - if (!checkNamedParameter_contexts(visitor, node, other)) { - result = visitor.resultOnInequivalence; - } if (!checkNamedParameter_binaryOffsetNoTag(visitor, node, other)) { result = visitor.resultOnInequivalence; } @@ -9902,12 +9924,6 @@ class EquivalenceStrategy { node.initializer, other.initializer, 'initializer'); } - bool checkVariableStatement_contexts(EquivalenceVisitor visitor, - VariableStatement node, VariableStatement other) { - return visitor.checkLists( - node.contexts, other.contexts, visitor.checkNodes, 'contexts'); - } - bool checkVariableStatement_fileOffset(EquivalenceVisitor visitor, VariableStatement node, VariableStatement other) { return checkStatement_fileOffset(visitor, node, other); @@ -9948,14 +9964,16 @@ class EquivalenceStrategy { return visitor.checkNodes(node.guard, other.guard, 'guard'); } - bool checkCatch_exception( + bool checkCatch_exceptionCatchVariable( EquivalenceVisitor visitor, Catch node, Catch other) { - return visitor.checkNodes(node.exception, other.exception, 'exception'); + return visitor.checkNodes(node.exceptionCatchVariable, + other.exceptionCatchVariable, 'exceptionCatchVariable'); } - bool checkCatch_stackTrace( + bool checkCatch_stackTraceCatchVariable( EquivalenceVisitor visitor, Catch node, Catch other) { - return visitor.checkNodes(node.stackTrace, other.stackTrace, 'stackTrace'); + return visitor.checkNodes(node.stackTraceCatchVariable, + other.stackTraceCatchVariable, 'stackTraceCatchVariable'); } bool checkCatch_body(EquivalenceVisitor visitor, Catch node, Catch other) { @@ -9971,6 +9989,53 @@ class EquivalenceStrategy { return checkTreeNode_fileOffset(visitor, node, other); } + bool checkCatchVariable_catchVariableName( + EquivalenceVisitor visitor, CatchVariable node, CatchVariable other) { + return visitor.checkValues( + node.catchVariableName, other.catchVariableName, 'catchVariableName'); + } + + bool checkCatchVariable_type( + EquivalenceVisitor visitor, CatchVariable node, CatchVariable other) { + return visitor.checkNodes(node.type, other.type, 'type'); + } + + bool checkCatchVariable_annotations( + EquivalenceVisitor visitor, CatchVariable node, CatchVariable other) { + return visitor.checkLists( + node.annotations, other.annotations, visitor.checkNodes, 'annotations'); + } + + bool checkVariable_flags( + EquivalenceVisitor visitor, Variable node, Variable other) { + return visitor.checkValues(node.flags, other.flags, 'flags'); + } + + bool checkExpressionVariable_flags(EquivalenceVisitor visitor, + ExpressionVariable node, ExpressionVariable other) { + return checkVariable_flags(visitor, node, other); + } + + bool checkCatchVariable_flags( + EquivalenceVisitor visitor, CatchVariable node, CatchVariable other) { + return checkExpressionVariable_flags(visitor, node, other); + } + + bool checkVariable_fileOffset( + EquivalenceVisitor visitor, Variable node, Variable other) { + return checkTreeNode_fileOffset(visitor, node, other); + } + + bool checkExpressionVariable_fileOffset(EquivalenceVisitor visitor, + ExpressionVariable node, ExpressionVariable other) { + return checkVariable_fileOffset(visitor, node, other); + } + + bool checkCatchVariable_fileOffset( + EquivalenceVisitor visitor, CatchVariable node, CatchVariable other) { + return checkExpressionVariable_fileOffset(visitor, node, other); + } + bool checkLocalVariable_cosmeticName( EquivalenceVisitor visitor, LocalVariable node, LocalVariable other) { return visitor.checkValues( @@ -9994,31 +10059,11 @@ class EquivalenceStrategy { node.annotations, other.annotations, visitor.checkNodes, 'annotations'); } - bool checkVariable_flags( - EquivalenceVisitor visitor, Variable node, Variable other) { - return visitor.checkValues(node.flags, other.flags, 'flags'); - } - - bool checkExpressionVariable_flags(EquivalenceVisitor visitor, - ExpressionVariable node, ExpressionVariable other) { - return checkVariable_flags(visitor, node, other); - } - bool checkLocalVariable_flags( EquivalenceVisitor visitor, LocalVariable node, LocalVariable other) { return checkExpressionVariable_flags(visitor, node, other); } - bool checkVariable_fileOffset( - EquivalenceVisitor visitor, Variable node, Variable other) { - return checkTreeNode_fileOffset(visitor, node, other); - } - - bool checkExpressionVariable_fileOffset(EquivalenceVisitor visitor, - ExpressionVariable node, ExpressionVariable other) { - return checkVariable_fileOffset(visitor, node, other); - } - bool checkLocalVariable_fileOffset( EquivalenceVisitor visitor, LocalVariable node, LocalVariable other) { return checkExpressionVariable_fileOffset(visitor, node, other); @@ -10041,12 +10086,6 @@ class EquivalenceStrategy { node.annotations, other.annotations, visitor.checkNodes, 'annotations'); } - bool checkPositionalParameter_contexts(EquivalenceVisitor visitor, - PositionalParameter node, PositionalParameter other) { - return visitor.checkLists( - node.contexts, other.contexts, visitor.checkNodes, 'contexts'); - } - bool checkPositionalParameter_binaryOffsetNoTag(EquivalenceVisitor visitor, PositionalParameter node, PositionalParameter other) { return visitor.checkValues( @@ -10107,12 +10146,6 @@ class EquivalenceStrategy { node.annotations, other.annotations, visitor.checkNodes, 'annotations'); } - bool checkNamedParameter_contexts( - EquivalenceVisitor visitor, NamedParameter node, NamedParameter other) { - return visitor.checkLists( - node.contexts, other.contexts, visitor.checkNodes, 'contexts'); - } - bool checkNamedParameter_binaryOffsetNoTag( EquivalenceVisitor visitor, NamedParameter node, NamedParameter other) { return visitor.checkValues( diff --git a/pkg/kernel/lib/src/node_creator.dart b/pkg/kernel/lib/src/node_creator.dart index 82cb186e487..c130d4d9a4c 100644 --- a/pkg/kernel/lib/src/node_creator.dart +++ b/pkg/kernel/lib/src/node_creator.dart @@ -329,6 +329,7 @@ class NodeCreator { case NodeKind.PatternSwitchCase: case NodeKind.SwitchExpressionCase: case NodeKind.LocalVariable: + case NodeKind.CatchVariable: case NodeKind.PositionalParameter: case NodeKind.NamedParameter: case NodeKind.SyntheticVariable: @@ -1855,6 +1856,7 @@ class NodeCreator { _createExpression()) ..fileOffset = _needFileOffset(); case NodeKind.LocalVariable: + case NodeKind.CatchVariable: case NodeKind.PositionalParameter: case NodeKind.NamedParameter: case NodeKind.SyntheticVariable: diff --git a/pkg/kernel/lib/src/printer.dart b/pkg/kernel/lib/src/printer.dart index 845d40372bc..328ad82e7e6 100644 --- a/pkg/kernel/lib/src/printer.dart +++ b/pkg/kernel/lib/src/printer.dart @@ -224,6 +224,8 @@ class AstPrinter { } return _variableDeclarationNames[node] ??= '#${_variableDeclarationNames.length}'; + case CatchVariable(catchVariableName: var name): + return name; } } diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart index 571ddafa322..4dd440523f3 100644 --- a/pkg/kernel/lib/text/ast_to_text.dart +++ b/pkg/kernel/lib/text/ast_to_text.dart @@ -1193,6 +1193,8 @@ class Printer extends VisitorDefault with VisitorVoidMixin { writeWord('synthetic-variable'); case VariableDeclaration(): writeWord('variable-declaration'); + case CatchVariable(): + writeWord('catch-variable'); } // TODO(cstefantsova): Should [Variable]s have annotations? diff --git a/pkg/kernel/lib/visitor.dart b/pkg/kernel/lib/visitor.dart index eb4c560c0c2..837d3578b65 100644 --- a/pkg/kernel/lib/visitor.dart +++ b/pkg/kernel/lib/visitor.dart @@ -824,6 +824,7 @@ abstract class TreeVisitor R visitComponent(Component node); R visitTypeVariable(TypeVariable node); R visitLocalVariable(LocalVariable node); + R visitCatchVariable(CatchVariable node); R visitThisVariable(ThisVariable node); R visitSyntheticVariable(SyntheticVariable node); R visitVariableContext(VariableContext node); @@ -887,6 +888,8 @@ mixin TreeVisitorDefaultMixin implements TreeVisitor { @override R visitLocalVariable(LocalVariable node) => defaultTreeNode(node); @override + R visitCatchVariable(CatchVariable node) => defaultTreeNode(node); + @override R visitThisVariable(ThisVariable node) => defaultTreeNode(node); @override R visitSyntheticVariable(SyntheticVariable node) => defaultTreeNode(node); @@ -958,6 +961,7 @@ abstract class TreeVisitor1 R visitComponent(Component node, A arg); R visitTypeVariable(TypeVariable node, A arg); R visitLocalVariable(LocalVariable node, A arg); + R visitCatchVariable(CatchVariable node, A arg); R visitThisVariable(ThisVariable node, A arg); R visitSyntheticVariable(SyntheticVariable node, A arg); R visitVariableContext(VariableContext node, A arg); @@ -1027,6 +1031,8 @@ mixin TreeVisitor1DefaultMixin implements TreeVisitor1 { @override R visitLocalVariable(LocalVariable node, A arg) => defaultTreeNode(node, arg); @override + R visitCatchVariable(CatchVariable node, A arg) => defaultTreeNode(node, arg); + @override R visitThisVariable(ThisVariable node, A arg) => defaultTreeNode(node, arg); @override R visitSyntheticVariable(SyntheticVariable node, A arg) => @@ -2245,6 +2251,19 @@ class RemovingTransformer extends TreeVisitor1Default { return transformOrRemove(node, dummyVariableDeclaration); } + /// Visits [node], returning the transformation result. Removal of [node] is + /// supported with `null` as the result. + /// + /// This is convenience method for calling [transformOrRemove] with removal + /// sentinel for [VariableDeclaration] nodes. + CatchVariable? transformOrRemoveCatchVariable(CatchVariable node) { + if (node is VariableDeclaration) { + return transformOrRemoveVariableDeclaration(node); + } else { + return transformOrRemove(node, dummyCatchVariable); + } + } + /// Visits [node] using [removalSentinel] as the removal sentinel. /// /// If [removalSentinel] is the result of visiting [node], `null` is returned. @@ -3432,6 +3451,13 @@ mixin TreeVisitorExperimentExclusionMixin implements TreeVisitor { ); } + @override + R visitCatchVariable(CatchVariable node) { + throw StateError( + "${runtimeType}.visitCatchVariable isn't supported.", + ); + } + @override R visitThisVariable(ThisVariable node) { throw StateError( @@ -3497,6 +3523,13 @@ mixin TreeVisitor1ExperimentExclusionMixin implements TreeVisitor1 { ); } + @override + R visitCatchVariable(CatchVariable node, A arg) { + throw StateError( + "${runtimeType}.visitCatchVariable isn't supported.", + ); + } + @override R visitThisVariable(ThisVariable node, A arg) { throw StateError(