From bfda964ab805d6901b518b77d5440aea7a1d12cc Mon Sep 17 00:00:00 2001 From: Johnni Winther Date: Thu, 27 Apr 2023 09:40:39 +0000 Subject: [PATCH] [cfe] Add BodyBuilderContext This adds a BodyBuilderContext to separate the BodyBuilder from its [member], [declarationBuilder] and [sourceClassBuilder] fields. The latter two are fully removes and trivial uses of [member] have been removed. This is a step towards a more clean implementation of inline class members. The plan is to have the members create their own BodyBuilderContext to use in the BodyBuilder which should the be agnostic about the builders of its context. Change-Id: Ic3b29693dd26aa8c57a9ac175b4a07ce4b0a15d7 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/298860 Reviewed-by: Chloe Stefantsova Commit-Queue: Johnni Winther --- .../lib/src/fasta/kernel/body_builder.dart | 362 ++++++++++++------ .../fasta/kernel/expression_generator.dart | 10 +- pkg/front_end/lib/src/fasta/scope.dart | 2 +- .../lib/src/fasta/source/diet_listener.dart | 11 +- .../source/source_constructor_builder.dart | 3 +- .../type_inference/inference_helper.dart | 5 +- .../test/explicit_creation_git_test.dart | 11 +- .../test/fasta/generator_to_string_test.dart | 6 +- .../testcases/extensions/shadowing.dart | 16 + .../extensions/shadowing.dart.strong.expect | 36 ++ .../shadowing.dart.strong.transformed.expect | 36 ++ .../shadowing.dart.textual_outline.expect | 8 + ...owing.dart.textual_outline_modelled.expect | 8 + .../extensions/shadowing.dart.weak.expect | 36 ++ .../shadowing.dart.weak.modular.expect | 36 ++ .../shadowing.dart.weak.outline.expect | 20 + .../shadowing.dart.weak.transformed.expect | 36 ++ .../missing_super_mixin_constructor.dart | 13 + ...super_mixin_constructor.dart.strong.expect | 30 ++ ...constructor.dart.strong.transformed.expect | 30 ++ ...in_constructor.dart.textual_outline.expect | 9 + ...uctor.dart.textual_outline_modelled.expect | 9 + ...g_super_mixin_constructor.dart.weak.expect | 30 ++ ...mixin_constructor.dart.weak.modular.expect | 30 ++ ...mixin_constructor.dart.weak.outline.expect | 19 + ...n_constructor.dart.weak.transformed.expect | 30 ++ 26 files changed, 695 insertions(+), 147 deletions(-) create mode 100644 pkg/front_end/testcases/extensions/shadowing.dart create mode 100644 pkg/front_end/testcases/extensions/shadowing.dart.strong.expect create mode 100644 pkg/front_end/testcases/extensions/shadowing.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/extensions/shadowing.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/extensions/shadowing.dart.textual_outline_modelled.expect create mode 100644 pkg/front_end/testcases/extensions/shadowing.dart.weak.expect create mode 100644 pkg/front_end/testcases/extensions/shadowing.dart.weak.modular.expect create mode 100644 pkg/front_end/testcases/extensions/shadowing.dart.weak.outline.expect create mode 100644 pkg/front_end/testcases/extensions/shadowing.dart.weak.transformed.expect create mode 100644 pkg/front_end/testcases/general/missing_super_mixin_constructor.dart create mode 100644 pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.strong.expect create mode 100644 pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.strong.transformed.expect create mode 100644 pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.textual_outline.expect create mode 100644 pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.textual_outline_modelled.expect create mode 100644 pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.weak.expect create mode 100644 pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.weak.modular.expect create mode 100644 pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.weak.outline.expect create mode 100644 pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.weak.transformed.expect diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart index 323e0502aa9..b429c0c6458 100644 --- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart +++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart @@ -136,35 +136,197 @@ enum JumpTargetKind { Goto, // Continue label in switch. } +class BodyBuilderContext { + final LibraryBuilder _libraryBuilder; + + /// The source class or mixin declaration in which [_member] is declared, if + /// any. + /// + /// If [_member] is a synthesized member for expression evaluation the + /// enclosing declaration might be a [DillClassBuilder]. This can be accessed + /// through [_declarationBuilder]. + final SourceClassBuilder? _sourceClassBuilder; + + /// The class, mixin or extension declaration in which [_member] is declared, + /// if any. + final DeclarationBuilder? _declarationBuilder; + + final ModifierBuilder _member; + + final bool isDeclarationInstanceMember; + + BodyBuilderContext( + this._libraryBuilder, this._declarationBuilder, this._member, + {required this.isDeclarationInstanceMember}) + : _sourceClassBuilder = _declarationBuilder is SourceClassBuilder + ? _declarationBuilder + : null; + + Member? lookupSuperMember(ClassHierarchy hierarchy, Name name, + {bool isSetter = false}) { + return (_declarationBuilder as ClassBuilder).lookupInstanceMember( + hierarchy, name, + isSetter: isSetter, isSuper: true); + } + + Constructor? lookupConstructor(Name name) { + return _sourceClassBuilder!.lookupConstructor(name, isSuper: false); + } + + Constructor? lookupSuperConstructor(Name name) { + return _sourceClassBuilder!.lookupConstructor(name, isSuper: true); + } + + Builder? lookupLocalMember(String name, {bool required = false}) { + if (_declarationBuilder != null) { + return _declarationBuilder!.lookupLocalMember(name, required: required); + } else { + return _libraryBuilder.lookupLocalMember(name, required: required); + } + } + + bool get isPatchClass => _sourceClassBuilder?.isPatch ?? false; + + Builder? lookupStaticOriginMember(String name, int charOffset, Uri uri) { + // The scope of a patched method includes the origin class. + return _sourceClassBuilder!.origin + .findStaticBuilder(name, charOffset, uri, _libraryBuilder); + } + + FormalParameterBuilder? getFormalParameterByName(Identifier name) { + SourceFunctionBuilder member = this._member as SourceFunctionBuilder; + return member.getFormal(name); + } + + bool get isConstructor { + return _member is ConstructorDeclaration; + } + + bool get isExternalConstructor { + return _member.isExternal; + } + + bool get isConstConstructor { + return _member.isConst; + } + + bool get isNativeMethod { + return _member.isNative; + } + + bool get isDeclarationInstanceContext { + return isDeclarationInstanceMember || isConstructor; + } + + bool get isRedirectingFactory { + return _member is RedirectingFactoryBuilder; + } + + String get redirectingFactoryTargetName { + RedirectingFactoryBuilder factory = _member as RedirectingFactoryBuilder; + return factory.redirectionTarget.fullNameForErrors; + } + + InstanceTypeVariableAccessState get instanceTypeVariableAccessState { + if (_member.isExtensionMember && _member.isField && !_member.isExternal) { + return InstanceTypeVariableAccessState.Invalid; + } else if (isDeclarationInstanceContext || _member is DeclarationBuilder) { + return InstanceTypeVariableAccessState.Allowed; + } else { + return InstanceTypeVariableAccessState.Disallowed; + } + } + + bool needsImplicitSuperInitializer(CoreTypes coreTypes) { + return _declarationBuilder is SourceClassBuilder && + coreTypes.objectClass != + (_declarationBuilder as SourceClassBuilder).cls && + !_member.isExternal; + } + + void registerSuperCall() { + MemberBuilder memberBuilder = _member as MemberBuilder; + memberBuilder.member.transformerFlags |= TransformerFlag.superCalls; + } + + bool isConstructorCyclic(String name) { + return _sourceClassBuilder!.checkConstructorCyclic(_member.name!, name); + } + + ConstantContext get constantContext { + return _member.isConst + ? ConstantContext.inferred + : !_member.isStatic && + _sourceClassBuilder != null && + _sourceClassBuilder!.declaresConstConstructor + ? ConstantContext.required + : ConstantContext.none; + } + + bool get isLateField => + _member is SourceFieldBuilder && (_member as SourceFieldBuilder).isLate; + + bool get isAbstractField => + _member is SourceFieldBuilder && + (_member as SourceFieldBuilder).isAbstract; + + bool get isExternalField => + _member is SourceFieldBuilder && + (_member as SourceFieldBuilder).isExternal; + + bool get isMixinClass { + return _sourceClassBuilder != null && _sourceClassBuilder!.isMixinClass; + } + + bool get isEnumClass { + return _sourceClassBuilder is SourceEnumBuilder; + } + + String get className { + return _sourceClassBuilder!.fullNameForErrors; + } + + String get superClassName { + if (_sourceClassBuilder!.supertypeBuilder?.declaration + is InvalidTypeDeclarationBuilder) { + // TODO(johnniwinther): Avoid reporting errors on missing constructors + // on invalid super types. + return _sourceClassBuilder!.supertypeBuilder!.fullNameForErrors; + } + Class cls = _sourceClassBuilder!.cls; + cls = cls.superclass!; + while (cls.isMixinApplication) { + cls = cls.superclass!; + } + return cls.name; + } + + DartType substituteFieldType(DartType fieldType) { + return (_member as ConstructorDeclaration).substituteFieldType(fieldType); + } + + void registerInitializedField(SourceFieldBuilder builder) { + (_member as ConstructorDeclaration).registerInitializedField(builder); + } +} + class BodyBuilder extends StackListenerImpl implements ExpressionGeneratorHelper, EnsureLoaded, DelayedActionPerformer { @override final Forest forest; - // TODO(ahe): Rename [library] to 'part'. @override final SourceLibraryBuilder libraryBuilder; + final BodyBuilderContext _context; + + // TODO(johnniwinther): Remove this in favor of [_context]. final ModifierBuilder member; - /// The class, mixin or extension declaration in which [member] is declared, - /// if any. - final DeclarationBuilder? declarationBuilder; - - /// The source class or mixin declaration in which [member] is declared, if - /// any. - /// - /// If [member] is a synthesized member for expression evaluation the - /// enclosing declaration might be a [DillClassBuilder]. This can be accessed - /// through [declarationBuilder]. - final SourceClassBuilder? sourceClassBuilder; - final ClassHierarchy hierarchy; final CoreTypes coreTypes; - final bool isDeclarationInstanceMember; - final Scope enclosingScope; final bool enableNative; @@ -349,21 +511,18 @@ class BodyBuilder extends StackListenerImpl BodyBuilder( {required this.libraryBuilder, + required BodyBuilderContext context, required this.member, required this.enclosingScope, this.formalParameterScope, required this.hierarchy, required this.coreTypes, - this.declarationBuilder, - required this.isDeclarationInstanceMember, this.thisVariable, this.thisTypeParameters, required this.uri, required this.typeInferrer}) - : forest = const Forest(), - sourceClassBuilder = declarationBuilder is SourceClassBuilder - ? declarationBuilder - : null, + : _context = context, + forest = const Forest(), enableNative = libraryBuilder.loader.target.backendTarget .enableNative(libraryBuilder.importUri), stringExpectedAfterNative = libraryBuilder @@ -373,9 +532,7 @@ class BodyBuilder extends StackListenerImpl (libraryBuilder.importUri.path == "_builtin" || libraryBuilder.importUri.path == "ui"), needsImplicitSuperInitializer = - declarationBuilder is SourceClassBuilder && - coreTypes.objectClass != declarationBuilder.cls && - !member.isExternal, + context.needsImplicitSuperInitializer(coreTypes), benchmarker = libraryBuilder.loader.target.benchmarker, this.scope = enclosingScope { Iterator? iterator = @@ -392,14 +549,14 @@ class BodyBuilder extends StackListenerImpl DeclarationBuilder? declarationBuilder, TypeInferrer typeInferrer) : this( libraryBuilder: part, + context: new BodyBuilderContext(part, declarationBuilder, field, + isDeclarationInstanceMember: field.isDeclarationInstanceMember), member: field, enclosingScope: declarationBuilder?.scope ?? field.libraryBuilder.scope, formalParameterScope: null, hierarchy: part.loader.hierarchy, coreTypes: part.loader.coreTypes, - declarationBuilder: declarationBuilder, - isDeclarationInstanceMember: field.isDeclarationInstanceMember, thisVariable: null, uri: field.fileUri!, typeInferrer: typeInferrer); @@ -424,13 +581,14 @@ class BodyBuilder extends StackListenerImpl {Scope? formalParameterScope}) : this( libraryBuilder: library, + context: new BodyBuilderContext(library, declarationBuilder, member, + isDeclarationInstanceMember: + member.isDeclarationInstanceMember), member: member, enclosingScope: scope, formalParameterScope: formalParameterScope, hierarchy: library.loader.hierarchy, coreTypes: library.loader.coreTypes, - declarationBuilder: declarationBuilder, - isDeclarationInstanceMember: member.isDeclarationInstanceMember, thisVariable: null, uri: fileUri, typeInferrer: library.loader.typeInferenceEngine @@ -612,23 +770,17 @@ class BodyBuilder extends StackListenerImpl } bool get inConstructor { - return functionNestingLevel == 0 && member is ConstructorDeclaration; + return functionNestingLevel == 0 && _context.isConstructor; } @override bool get isDeclarationInstanceContext { - return isDeclarationInstanceMember || member is ConstructorDeclaration; + return _context.isDeclarationInstanceContext; } @override InstanceTypeVariableAccessState get instanceTypeVariableAccessState { - if (member.isExtensionMember && member.isField && !member.isExternal) { - return InstanceTypeVariableAccessState.Invalid; - } else if (isDeclarationInstanceContext || member is DeclarationBuilder) { - return InstanceTypeVariableAccessState.Allowed; - } else { - return InstanceTypeVariableAccessState.Disallowed; - } + return _context.instanceTypeVariableAccessState; } @override @@ -999,14 +1151,8 @@ class BodyBuilder extends StackListenerImpl Expression? initializer = pop() as Expression?; Identifier identifier = pop() as Identifier; String name = identifier.name; - Builder declaration; + Builder declaration = _context.lookupLocalMember(name, required: true)!; int fileOffset = identifier.charOffset; - if (declarationBuilder != null) { - declaration = - declarationBuilder!.lookupLocalMember(name, required: true)!; - } else { - declaration = libraryBuilder.lookupLocalMember(name, required: true)!; - } while (declaration.next != null) { // If we have duplicates, we try to find the right declaration. if (declaration.fileUri == uri && @@ -1214,8 +1360,7 @@ class BodyBuilder extends StackListenerImpl Object? node = pop(); List initializers; - final ModifierBuilder member = this.member; - if (!(member is ConstructorDeclaration && !member.isExternal)) { + if (!(_context.isConstructor && !_context.isExternalConstructor)) { // An error has been reported by the parser. initializers = []; } else if (node is Initializer) { @@ -1830,7 +1975,7 @@ class BodyBuilder extends StackListenerImpl ..variable = formal; }, growable: false); enterLocalScope(new FormalParameters(formals, fileOffset, noLength, uri) - .computeFormalParameterScope(scope, member, this)); + .computeFormalParameterScope(scope, this)); Token endToken = parser.parseExpression(parser.syntheticPreviousToken(token)); @@ -2041,12 +2186,12 @@ class BodyBuilder extends StackListenerImpl List? initializers = _initializers; if (initializers != null && initializers.isNotEmpty) { - if (sourceClassBuilder != null && sourceClassBuilder!.isMixinClass) { + if (_context.isMixinClass) { // Report an error if a mixin class has a constructor with an // initializer. buildProblem( fasta.templateIllegalMixinDueToConstructors - .withArguments(sourceClassBuilder!.fullNameForErrors), + .withArguments(_context.className), constructorDeclaration.charOffset, noLength); } @@ -2094,8 +2239,7 @@ class BodyBuilder extends StackListenerImpl } else if (initializers.last is RedirectingInitializer) { RedirectingInitializer redirectingInitializer = initializers.last as RedirectingInitializer; - if (sourceClassBuilder is SourceEnumBuilder && - libraryFeatures.enhancedEnums.isEnabled) { + if (_context.isEnumClass && libraryFeatures.enhancedEnums.isEnabled) { ArgumentsImpl arguments = redirectingInitializer.arguments as ArgumentsImpl; List enumSyntheticArguments = [ @@ -2145,7 +2289,7 @@ class BodyBuilder extends StackListenerImpl positionalArguments = positionalSuperParametersAsArguments; namedArguments = namedSuperParametersAsArguments; } - if (sourceClassBuilder is SourceEnumBuilder) { + if (_context.isEnumClass) { assert(function.positionalParameters.length >= 2 && function.positionalParameters[0].name == "#index" && function.positionalParameters[1].name == "#name"); @@ -2173,11 +2317,10 @@ class BodyBuilder extends StackListenerImpl checkArgumentsForFunction(superTarget.function, arguments, constructorDeclaration.charOffset, const []) != null) { - String superclass = - sourceClassBuilder!.supertypeBuilder!.fullNameForErrors; + String superclass = _context.superClassName; int length = constructorDeclaration.name.length; if (length == 0) { - length = sourceClassBuilder!.cls.name.length; + length = _context.className.length; } initializer = buildInvalidInitializer( buildProblem( @@ -2206,14 +2349,13 @@ class BodyBuilder extends StackListenerImpl /// We use an empty statement instead. function.body = new EmptyStatement()..parent = function; } else if (body != null && - sourceClassBuilder != null && - sourceClassBuilder!.isMixinClass && + _context.isMixinClass && !constructorDeclaration.isFactory) { // Report an error if a mixin class has a non-factory constructor with a // body. buildProblem( fasta.templateIllegalMixinDueToConstructors - .withArguments(sourceClassBuilder!.fullNameForErrors), + .withArguments(_context.className), constructorDeclaration.charOffset, noLength); } @@ -3231,14 +3373,14 @@ class BodyBuilder extends StackListenerImpl @override Member? lookupSuperMember(Name name, {bool isSetter = false}) { - return (declarationBuilder as ClassBuilder).lookupInstanceMember( - hierarchy, name, - isSetter: isSetter, isSuper: true); + return _context.lookupSuperMember(hierarchy, name, isSetter: isSetter); } @override Constructor? lookupConstructor(Name name, {bool isSuper = false}) { - return sourceClassBuilder!.lookupConstructor(name, isSuper: isSuper); + return isSuper + ? _context.lookupSuperConstructor(name) + : _context.lookupConstructor(name); } @override @@ -3323,12 +3465,9 @@ class BodyBuilder extends StackListenerImpl return new ParserErrorGenerator(this, token, fasta.messageSyntheticToken); } Builder? declaration = scope.lookup(name, charOffset, uri); - if (declaration == null && - prefix == null && - (sourceClassBuilder?.isPatch ?? false)) { + if (declaration == null && prefix == null && _context.isPatchClass) { // The scope of a patched method includes the origin class. - declaration = sourceClassBuilder!.origin - .findStaticBuilder(name, charOffset, uri, libraryBuilder); + declaration = _context.lookupStaticOriginMember(name, charOffset, uri); } if (declaration != null && declaration.isDeclarationInstanceMember && @@ -3426,7 +3565,7 @@ class BodyBuilder extends StackListenerImpl thisVariable: inConstructorInitializer ? null : thisVariable); } else if (declaration.isExtensionInstanceMember) { ExtensionBuilder extensionBuilder = - declarationBuilder as ExtensionBuilder; + declaration.parent as ExtensionBuilder; MemberBuilder? setterBuilder = _getCorrespondingSetterBuilder(scope, declaration, name, charOffset); // TODO(johnniwinther): Check for constantContext like below? @@ -3862,25 +4001,14 @@ class BodyBuilder extends StackListenerImpl @override void beginFieldInitializer(Token token) { inFieldInitializer = true; - constantContext = member.isConst - ? ConstantContext.inferred - : !member.isStatic && - sourceClassBuilder != null && - sourceClassBuilder!.declaresConstConstructor - ? ConstantContext.required - : ConstantContext.none; - if (member is SourceFieldBuilder) { - SourceFieldBuilder fieldBuilder = member as SourceFieldBuilder; - inLateFieldInitializer = fieldBuilder.isLate; - if (fieldBuilder.isAbstract) { - addProblem( - fasta.messageAbstractFieldInitializer, token.charOffset, noLength); - } else if (fieldBuilder.isExternal) { - addProblem( - fasta.messageExternalFieldInitializer, token.charOffset, noLength); - } - } else { - inLateFieldInitializer = false; + constantContext = _context.constantContext; + inLateFieldInitializer = _context.isLateField; + if (_context.isAbstractField) { + addProblem( + fasta.messageAbstractFieldInitializer, token.charOffset, noLength); + } else if (_context.isExternalField) { + addProblem( + fasta.messageExternalFieldInitializer, token.charOffset, noLength); } } @@ -3897,13 +4025,7 @@ class BodyBuilder extends StackListenerImpl @override void handleNoFieldInitializer(Token token) { debugEvent("NoFieldInitializer"); - constantContext = member.isConst - ? ConstantContext.inferred - : !member.isStatic && - sourceClassBuilder != null && - sourceClassBuilder!.declaresConstConstructor - ? ConstantContext.required - : ConstantContext.none; + constantContext = _context.constantContext; if (constantContext == ConstantContext.inferred) { // Creating a null value to prevent the Dart VM from crashing. push(forest.createNullLiteral(offsetForToken(token))); @@ -5443,8 +5565,8 @@ class BodyBuilder extends StackListenerImpl if (!inCatchClause && functionNestingLevel == 0 && memberKind != MemberKind.GeneralizedFunctionType) { - SourceFunctionBuilder member = this.member as SourceFunctionBuilder; - parameter = member.getFormal(name!); + parameter = _context.getFormalParameterByName(name!); + if (parameter == null) { // This happens when the list of formals (originally) contains a // ParserRecovery - then the popped list becomes null. @@ -5466,11 +5588,10 @@ class BodyBuilder extends StackListenerImpl VariableDeclaration variable = parameter.build(libraryBuilder); Expression? initializer = name?.initializer; if (initializer != null) { - if (member is RedirectingFactoryBuilder) { - RedirectingFactoryBuilder factory = member as RedirectingFactoryBuilder; + if (_context.isRedirectingFactory) { addProblem( fasta.templateDefaultValueInRedirectingFactoryConstructor - .withArguments(factory.redirectionTarget.fullNameForErrors), + .withArguments(_context.redirectingFactoryTargetName), initializer.fileOffset, noLength); } else { @@ -5612,7 +5733,7 @@ class BodyBuilder extends StackListenerImpl push(formals); if ((inCatchClause || functionNestingLevel != 0) && kind != MemberKind.GeneralizedFunctionType) { - enterLocalScope(formals.computeFormalParameterScope(scope, member, this)); + enterLocalScope(formals.computeFormalParameterScope(scope, this)); } } @@ -7005,8 +7126,7 @@ class BodyBuilder extends StackListenerImpl if (context.isScopeReference && isDeclarationInstanceContext && thisVariable == null) { - MemberBuilder memberBuilder = member as MemberBuilder; - memberBuilder.member.transformerFlags |= TransformerFlag.superCalls; + _context.registerSuperCall(); push(new ThisAccessGenerator(this, token, inInitializerLeftHandSide, inFieldInitializer, inLateFieldInitializer, isSuper: true)); @@ -8850,7 +8970,7 @@ class BodyBuilder extends StackListenerImpl List buildFieldInitializer(String name, int fieldNameOffset, int assignmentOffset, Expression expression, {FormalParameterBuilder? formal}) { - Builder? builder = declarationBuilder!.lookupLocalMember(name); + Builder? builder = _context.lookupLocalMember(name); if (builder?.next != null) { // Duplicated name, already reported. return [ @@ -8915,12 +9035,9 @@ class BodyBuilder extends StackListenerImpl ..fileOffset = assignmentOffset ]; } else { - ConstructorDeclaration constructorBuilder = - member as ConstructorDeclaration; if (formal != null && formal.type is! OmittedTypeBuilder) { DartType formalType = formal.variable!.type; - DartType fieldType = - constructorBuilder.substituteFieldType(builder.fieldType); + DartType fieldType = _context.substituteFieldType(builder.fieldType); if (!typeEnvironment.isSubtypeOf( formalType, fieldType, SubtypeCheckMode.withNullabilities)) { libraryBuilder.addProblem( @@ -8938,7 +9055,7 @@ class BodyBuilder extends StackListenerImpl ]); } } - constructorBuilder.registerInitializedField(builder); + _context.registerInitializedField(builder); return builder.buildInitializer(assignmentOffset, expression, isSynthetic: formal != null); } @@ -8958,7 +9075,7 @@ class BodyBuilder extends StackListenerImpl Initializer buildSuperInitializer( bool isSynthetic, Constructor constructor, Arguments arguments, [int charOffset = -1]) { - if (member.isConst && !constructor.isConst) { + if (_context.isConstConstructor && !constructor.isConst) { addProblem(fasta.messageConstConstructorWithNonConstSuper, charOffset, constructor.name.text.length); } @@ -8972,8 +9089,7 @@ class BodyBuilder extends StackListenerImpl Initializer buildRedirectingInitializer( Constructor constructor, Arguments arguments, [int charOffset = -1]) { - if (sourceClassBuilder! - .checkConstructorCyclic(member.name!, constructor.name.text)) { + if (_context.isConstructorCyclic(constructor.name.text)) { int length = constructor.name.text.length; if (length == 0) length = "this".length; addProblem(fasta.messageConstructorCyclic, charOffset, length); @@ -8998,7 +9114,7 @@ class BodyBuilder extends StackListenerImpl @override void handleInvalidFunctionBody(Token token) { - if (member.isNative) { + if (_context.isNativeMethod) { push(NullValues.FunctionBody); } else { push(forest.createBlock(offsetForToken(token), noLocation, [ @@ -9282,18 +9398,14 @@ class BodyBuilder extends StackListenerImpl } @override - String constructorNameForDiagnostics(String name, - {String? className, bool isSuper = false}) { - if (className == null) { - Class cls = sourceClassBuilder!.cls; - if (isSuper) { - cls = cls.superclass!; - while (cls.isMixinApplication) { - cls = cls.superclass!; - } - } - className = cls.name; - } + String constructorNameForDiagnostics(String name, {String? className}) { + className ??= _context.className; + return name.isEmpty ? className : "$className.$name"; + } + + @override + String superConstructorNameForDiagnostics(String name) { + String className = _context.superClassName; return name.isEmpty ? className : "$className.$name"; } @@ -9898,7 +10010,7 @@ class FormalParameters { } Scope computeFormalParameterScope( - Scope parent, Builder declaration, ExpressionGeneratorHelper helper) { + Scope parent, ExpressionGeneratorHelper helper) { if (parameters == null) return parent; assert(parameters!.isNotEmpty); Map local = {}; diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart index f1787858c69..644cd77b690 100644 --- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart +++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart @@ -4600,8 +4600,9 @@ class ThisAccessGenerator extends Generator { Constructor? constructor = _helper.lookupConstructor(name, isSuper: isSuper); if (constructor == null) { - String fullName = - _helper.constructorNameForDiagnostics(name.text, isSuper: isSuper); + String fullName = isSuper + ? _helper.superConstructorNameForDiagnostics(name.text) + : _helper.constructorNameForDiagnostics(name.text); LocatedMessage message = (isSuper ? templateSuperclassHasNoConstructor : templateConstructorNotFound) @@ -4609,8 +4610,9 @@ class ThisAccessGenerator extends Generator { .withLocation(_uri, fileOffset, lengthForToken(token)); return _helper.buildInvalidInitializer( _helper.buildUnresolvedError( - _helper.constructorNameForDiagnostics(name.text, - isSuper: isSuper), + isSuper + ? _helper.superConstructorNameForDiagnostics(name.text) + : _helper.constructorNameForDiagnostics(name.text), offset, arguments: arguments, isSuper: isSuper, diff --git a/pkg/front_end/lib/src/fasta/scope.dart b/pkg/front_end/lib/src/fasta/scope.dart index cba96357222..cbe9f0c3021 100644 --- a/pkg/front_end/lib/src/fasta/scope.dart +++ b/pkg/front_end/lib/src/fasta/scope.dart @@ -855,7 +855,7 @@ class AccessErrorBuilder extends ProblemBuilder { : super(name, builder, charOffset, fileUri); @override - Builder get parent => builder; + Builder? get parent => builder.parent; @override bool get isFinal => builder.isFinal; diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart index b844993e360..689f0ad17b8 100644 --- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart +++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart @@ -17,8 +17,6 @@ import 'package:_fe_analyzer_shared/src/parser/stack_listener.dart' show FixedNullableList, NullValues, ParserRecovery; import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token; import 'package:_fe_analyzer_shared/src/util/value_kind.dart'; -import 'package:front_end/src/fasta/kernel/benchmarker.dart' - show BenchmarkSubdivides, Benchmarker; import 'package:kernel/ast.dart'; import 'package:kernel/class_hierarchy.dart' show ClassHierarchy; import 'package:kernel/core_types.dart' show CoreTypes; @@ -44,7 +42,9 @@ import '../fasta_codes.dart' templateInternalProblemNotFound; import '../identifiers.dart' show QualifiedName; import '../ignored_parser_errors.dart' show isIgnoredParserError; -import '../kernel/body_builder.dart' show BodyBuilder, FormalParameters; +import '../kernel/benchmarker.dart' show BenchmarkSubdivides, Benchmarker; +import '../kernel/body_builder.dart' + show BodyBuilder, BodyBuilderContext, FormalParameters; import '../problems.dart' show DebugAbort, internalProblem, unexpected, unhandled; import '../scope.dart'; @@ -810,13 +810,14 @@ class DietListener extends StackListenerImpl { ConstantContext constantContext) { return new BodyBuilder( libraryBuilder: libraryBuilder, + context: new BodyBuilderContext( + libraryBuilder, currentDeclaration, builder, + isDeclarationInstanceMember: isDeclarationInstanceMember), member: builder, enclosingScope: memberScope, formalParameterScope: formalParameterScope, hierarchy: hierarchy, coreTypes: coreTypes, - declarationBuilder: currentDeclaration, - isDeclarationInstanceMember: isDeclarationInstanceMember, thisVariable: thisVariable, thisTypeParameters: thisTypeParameters, uri: uri, diff --git a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart index 6056754a183..ad64b26d015 100644 --- a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart +++ b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart @@ -284,8 +284,7 @@ abstract class AbstractSourceConstructorBuilder initializers.add(helper.buildInvalidInitializer( helper.buildUnresolvedError( helper.constructorNameForDiagnostics( - initializer.target.name.text, - isSuper: false), + initializer.target.name.text), initializer.fileOffset, arguments: initializer.arguments, isSuper: false, diff --git a/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart b/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart index 20333f2ded3..0ca9724e2ab 100644 --- a/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart +++ b/pkg/front_end/lib/src/fasta/type_inference/inference_helper.dart @@ -25,6 +25,7 @@ abstract class InferenceHelper { Expression expression, Message message, int fileOffset, int length, {List? context}); - String constructorNameForDiagnostics(String name, - {String? className, bool isSuper = false}); + String superConstructorNameForDiagnostics(String name); + + String constructorNameForDiagnostics(String name, {String? className}); } diff --git a/pkg/front_end/test/explicit_creation_git_test.dart b/pkg/front_end/test/explicit_creation_git_test.dart index 3bc277206c9..ecdbca5f76a 100644 --- a/pkg/front_end/test/explicit_creation_git_test.dart +++ b/pkg/front_end/test/explicit_creation_git_test.dart @@ -170,13 +170,14 @@ class DietListenerTest extends DietListener { ConstantContext constantContext) { return new BodyBuilderTest( libraryBuilder: libraryBuilder, + context: new BodyBuilderContext( + libraryBuilder, currentDeclaration, builder, + isDeclarationInstanceMember: isDeclarationInstanceMember), member: builder, enclosingScope: memberScope, formalParameterScope: formalParameterScope, hierarchy: hierarchy, coreTypes: coreTypes, - declarationBuilder: currentDeclaration, - isDeclarationInstanceMember: isDeclarationInstanceMember, thisVariable: extensionThis, thisTypeParameters: extensionTypeParameters, uri: uri, @@ -190,25 +191,23 @@ class BodyBuilderTest extends BodyBuilder { BodyBuilderTest( {libraryBuilder, member, + context, enclosingScope, formalParameterScope, hierarchy, coreTypes, - declarationBuilder, - isDeclarationInstanceMember, thisVariable, thisTypeParameters, uri, typeInferrer}) : super( libraryBuilder: libraryBuilder, + context: context, member: member, enclosingScope: enclosingScope, formalParameterScope: formalParameterScope, hierarchy: hierarchy, coreTypes: coreTypes, - declarationBuilder: declarationBuilder, - isDeclarationInstanceMember: isDeclarationInstanceMember, thisVariable: thisVariable, thisTypeParameters: thisTypeParameters, uri: uri, diff --git a/pkg/front_end/test/fasta/generator_to_string_test.dart b/pkg/front_end/test/fasta/generator_to_string_test.dart index 9ccc9fdb249..7991f9bd49a 100644 --- a/pkg/front_end/test/fasta/generator_to_string_test.dart +++ b/pkg/front_end/test/fasta/generator_to_string_test.dart @@ -53,7 +53,8 @@ import 'package:front_end/src/fasta/fasta_codes.dart' import 'package:front_end/src/fasta/kernel/expression_generator.dart'; -import 'package:front_end/src/fasta/kernel/body_builder.dart' show BodyBuilder; +import 'package:front_end/src/fasta/kernel/body_builder.dart' + show BodyBuilder, BodyBuilderContext; import 'package:front_end/src/fasta/source/source_library_builder.dart' show ImplicitLanguageVersion, SourceLibraryBuilder; @@ -122,7 +123,8 @@ Future main() async { BodyBuilder helper = new BodyBuilder( libraryBuilder: libraryBuilder, - isDeclarationInstanceMember: false, + context: new BodyBuilderContext(libraryBuilder, null, libraryBuilder, + isDeclarationInstanceMember: false), uri: uri, enclosingScope: new Scope.immutable(kind: ScopeKind.functionBody), member: libraryBuilder, diff --git a/pkg/front_end/testcases/extensions/shadowing.dart b/pkg/front_end/testcases/extensions/shadowing.dart new file mode 100644 index 00000000000..d9545152c59 --- /dev/null +++ b/pkg/front_end/testcases/extensions/shadowing.dart @@ -0,0 +1,16 @@ +// Copyright (c) 2023, 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. + +int getter = 42; +int setter = 42; + +extension on int { + get getter => 42; + set setter(_) {} + + method() { + getter = getter; + setter = setter; + } +} diff --git a/pkg/front_end/testcases/extensions/shadowing.dart.strong.expect b/pkg/front_end/testcases/extensions/shadowing.dart.strong.expect new file mode 100644 index 00000000000..a0201d1ac40 --- /dev/null +++ b/pkg/front_end/testcases/extensions/shadowing.dart.strong.expect @@ -0,0 +1,36 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/extensions/shadowing.dart:13:5: Error: Setter not found: 'getter'. +// getter = getter; +// ^^^^^^ +// +// pkg/front_end/testcases/extensions/shadowing.dart:14:14: Error: Getter not found: 'setter'. +// setter = setter; +// ^^^^^^ +// +import self as self; +import "dart:core" as core; + +extension /* unnamed */ _extension#0 on core::int { + get getter = self::_extension#0|get#getter; + method method = self::_extension#0|method; + tearoff method = self::_extension#0|get#method; + set setter = self::_extension#0|set#setter; +} +static field core::int getter = 42; +static field core::int setter = 42; +static method _extension#0|get#getter(lowered final core::int #this) → dynamic + return 42; +static method _extension#0|set#setter(lowered final core::int #this, dynamic _) → void {} +static method _extension#0|method(lowered final core::int #this) → dynamic { + invalid-expression "pkg/front_end/testcases/extensions/shadowing.dart:13:5: Error: Setter not found: 'getter'. + getter = getter; + ^^^^^^"; + self::_extension#0|set#setter(#this, invalid-expression "pkg/front_end/testcases/extensions/shadowing.dart:14:14: Error: Getter not found: 'setter'. + setter = setter; + ^^^^^^"); +} +static method _extension#0|get#method(lowered final core::int #this) → () → dynamic + return () → dynamic => self::_extension#0|method(#this); diff --git a/pkg/front_end/testcases/extensions/shadowing.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/shadowing.dart.strong.transformed.expect new file mode 100644 index 00000000000..a0201d1ac40 --- /dev/null +++ b/pkg/front_end/testcases/extensions/shadowing.dart.strong.transformed.expect @@ -0,0 +1,36 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/extensions/shadowing.dart:13:5: Error: Setter not found: 'getter'. +// getter = getter; +// ^^^^^^ +// +// pkg/front_end/testcases/extensions/shadowing.dart:14:14: Error: Getter not found: 'setter'. +// setter = setter; +// ^^^^^^ +// +import self as self; +import "dart:core" as core; + +extension /* unnamed */ _extension#0 on core::int { + get getter = self::_extension#0|get#getter; + method method = self::_extension#0|method; + tearoff method = self::_extension#0|get#method; + set setter = self::_extension#0|set#setter; +} +static field core::int getter = 42; +static field core::int setter = 42; +static method _extension#0|get#getter(lowered final core::int #this) → dynamic + return 42; +static method _extension#0|set#setter(lowered final core::int #this, dynamic _) → void {} +static method _extension#0|method(lowered final core::int #this) → dynamic { + invalid-expression "pkg/front_end/testcases/extensions/shadowing.dart:13:5: Error: Setter not found: 'getter'. + getter = getter; + ^^^^^^"; + self::_extension#0|set#setter(#this, invalid-expression "pkg/front_end/testcases/extensions/shadowing.dart:14:14: Error: Getter not found: 'setter'. + setter = setter; + ^^^^^^"); +} +static method _extension#0|get#method(lowered final core::int #this) → () → dynamic + return () → dynamic => self::_extension#0|method(#this); diff --git a/pkg/front_end/testcases/extensions/shadowing.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/shadowing.dart.textual_outline.expect new file mode 100644 index 00000000000..8c5b39ab8c6 --- /dev/null +++ b/pkg/front_end/testcases/extensions/shadowing.dart.textual_outline.expect @@ -0,0 +1,8 @@ +int getter = 42; +int setter = 42; + +extension on int { + get getter => 42; + set setter(_) {} + method() {} +} diff --git a/pkg/front_end/testcases/extensions/shadowing.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/extensions/shadowing.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..91cc1f6a0bb --- /dev/null +++ b/pkg/front_end/testcases/extensions/shadowing.dart.textual_outline_modelled.expect @@ -0,0 +1,8 @@ +extension on int { + get getter => 42; + method() {} + set setter(_) {} +} + +int getter = 42; +int setter = 42; diff --git a/pkg/front_end/testcases/extensions/shadowing.dart.weak.expect b/pkg/front_end/testcases/extensions/shadowing.dart.weak.expect new file mode 100644 index 00000000000..a0201d1ac40 --- /dev/null +++ b/pkg/front_end/testcases/extensions/shadowing.dart.weak.expect @@ -0,0 +1,36 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/extensions/shadowing.dart:13:5: Error: Setter not found: 'getter'. +// getter = getter; +// ^^^^^^ +// +// pkg/front_end/testcases/extensions/shadowing.dart:14:14: Error: Getter not found: 'setter'. +// setter = setter; +// ^^^^^^ +// +import self as self; +import "dart:core" as core; + +extension /* unnamed */ _extension#0 on core::int { + get getter = self::_extension#0|get#getter; + method method = self::_extension#0|method; + tearoff method = self::_extension#0|get#method; + set setter = self::_extension#0|set#setter; +} +static field core::int getter = 42; +static field core::int setter = 42; +static method _extension#0|get#getter(lowered final core::int #this) → dynamic + return 42; +static method _extension#0|set#setter(lowered final core::int #this, dynamic _) → void {} +static method _extension#0|method(lowered final core::int #this) → dynamic { + invalid-expression "pkg/front_end/testcases/extensions/shadowing.dart:13:5: Error: Setter not found: 'getter'. + getter = getter; + ^^^^^^"; + self::_extension#0|set#setter(#this, invalid-expression "pkg/front_end/testcases/extensions/shadowing.dart:14:14: Error: Getter not found: 'setter'. + setter = setter; + ^^^^^^"); +} +static method _extension#0|get#method(lowered final core::int #this) → () → dynamic + return () → dynamic => self::_extension#0|method(#this); diff --git a/pkg/front_end/testcases/extensions/shadowing.dart.weak.modular.expect b/pkg/front_end/testcases/extensions/shadowing.dart.weak.modular.expect new file mode 100644 index 00000000000..a0201d1ac40 --- /dev/null +++ b/pkg/front_end/testcases/extensions/shadowing.dart.weak.modular.expect @@ -0,0 +1,36 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/extensions/shadowing.dart:13:5: Error: Setter not found: 'getter'. +// getter = getter; +// ^^^^^^ +// +// pkg/front_end/testcases/extensions/shadowing.dart:14:14: Error: Getter not found: 'setter'. +// setter = setter; +// ^^^^^^ +// +import self as self; +import "dart:core" as core; + +extension /* unnamed */ _extension#0 on core::int { + get getter = self::_extension#0|get#getter; + method method = self::_extension#0|method; + tearoff method = self::_extension#0|get#method; + set setter = self::_extension#0|set#setter; +} +static field core::int getter = 42; +static field core::int setter = 42; +static method _extension#0|get#getter(lowered final core::int #this) → dynamic + return 42; +static method _extension#0|set#setter(lowered final core::int #this, dynamic _) → void {} +static method _extension#0|method(lowered final core::int #this) → dynamic { + invalid-expression "pkg/front_end/testcases/extensions/shadowing.dart:13:5: Error: Setter not found: 'getter'. + getter = getter; + ^^^^^^"; + self::_extension#0|set#setter(#this, invalid-expression "pkg/front_end/testcases/extensions/shadowing.dart:14:14: Error: Getter not found: 'setter'. + setter = setter; + ^^^^^^"); +} +static method _extension#0|get#method(lowered final core::int #this) → () → dynamic + return () → dynamic => self::_extension#0|method(#this); diff --git a/pkg/front_end/testcases/extensions/shadowing.dart.weak.outline.expect b/pkg/front_end/testcases/extensions/shadowing.dart.weak.outline.expect new file mode 100644 index 00000000000..5e06b62c186 --- /dev/null +++ b/pkg/front_end/testcases/extensions/shadowing.dart.weak.outline.expect @@ -0,0 +1,20 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +extension /* unnamed */ _extension#0 on core::int { + get getter = self::_extension#0|get#getter; + method method = self::_extension#0|method; + tearoff method = self::_extension#0|get#method; + set setter = self::_extension#0|set#setter; +} +static field core::int getter; +static field core::int setter; +static method _extension#0|get#getter(lowered final core::int #this) → dynamic + ; +static method _extension#0|set#setter(lowered final core::int #this, dynamic _) → void + ; +static method _extension#0|method(lowered final core::int #this) → dynamic + ; +static method _extension#0|get#method(lowered final core::int #this) → () → dynamic + return () → dynamic => self::_extension#0|method(#this); diff --git a/pkg/front_end/testcases/extensions/shadowing.dart.weak.transformed.expect b/pkg/front_end/testcases/extensions/shadowing.dart.weak.transformed.expect new file mode 100644 index 00000000000..a0201d1ac40 --- /dev/null +++ b/pkg/front_end/testcases/extensions/shadowing.dart.weak.transformed.expect @@ -0,0 +1,36 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/extensions/shadowing.dart:13:5: Error: Setter not found: 'getter'. +// getter = getter; +// ^^^^^^ +// +// pkg/front_end/testcases/extensions/shadowing.dart:14:14: Error: Getter not found: 'setter'. +// setter = setter; +// ^^^^^^ +// +import self as self; +import "dart:core" as core; + +extension /* unnamed */ _extension#0 on core::int { + get getter = self::_extension#0|get#getter; + method method = self::_extension#0|method; + tearoff method = self::_extension#0|get#method; + set setter = self::_extension#0|set#setter; +} +static field core::int getter = 42; +static field core::int setter = 42; +static method _extension#0|get#getter(lowered final core::int #this) → dynamic + return 42; +static method _extension#0|set#setter(lowered final core::int #this, dynamic _) → void {} +static method _extension#0|method(lowered final core::int #this) → dynamic { + invalid-expression "pkg/front_end/testcases/extensions/shadowing.dart:13:5: Error: Setter not found: 'getter'. + getter = getter; + ^^^^^^"; + self::_extension#0|set#setter(#this, invalid-expression "pkg/front_end/testcases/extensions/shadowing.dart:14:14: Error: Getter not found: 'setter'. + setter = setter; + ^^^^^^"); +} +static method _extension#0|get#method(lowered final core::int #this) → () → dynamic + return () → dynamic => self::_extension#0|method(#this); diff --git a/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart b/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart new file mode 100644 index 00000000000..8f45af695a2 --- /dev/null +++ b/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart @@ -0,0 +1,13 @@ +// Copyright (c) 2023, 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. + +class Super { + Super.named(); +} + +mixin Mixin {} + +class Class extends Super with Mixin { + Class(); +} diff --git a/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.strong.expect b/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.strong.expect new file mode 100644 index 00000000000..ed613df630b --- /dev/null +++ b/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.strong.expect @@ -0,0 +1,30 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/general/missing_super_mixin_constructor.dart:12:3: Error: The superclass, 'Super', has no unnamed constructor that takes no arguments. +// Class(); +// ^^^^^ +// +import self as self; +import "dart:core" as core; + +class Super extends core::Object { + constructor named() → self::Super + : super core::Object::•() + ; +} +abstract class Mixin extends core::Object /*isMixinDeclaration*/ { +} +abstract class _Class&Super&Mixin = self::Super with self::Mixin /*isAnonymousMixin*/ { + synthetic constructor named() → self::_Class&Super&Mixin + : super self::Super::named() + ; +} +class Class extends self::_Class&Super&Mixin { + constructor •() → self::Class + : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/missing_super_mixin_constructor.dart:12:3: Error: The superclass, 'Super', has no unnamed constructor that takes no arguments. + Class(); + ^^^^^" + ; +} diff --git a/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.strong.transformed.expect b/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.strong.transformed.expect new file mode 100644 index 00000000000..1a93b6a0a1f --- /dev/null +++ b/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.strong.transformed.expect @@ -0,0 +1,30 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/general/missing_super_mixin_constructor.dart:12:3: Error: The superclass, 'Super', has no unnamed constructor that takes no arguments. +// Class(); +// ^^^^^ +// +import self as self; +import "dart:core" as core; + +class Super extends core::Object { + constructor named() → self::Super + : super core::Object::•() + ; +} +abstract class Mixin extends core::Object /*isMixinDeclaration*/ { +} +abstract class _Class&Super&Mixin extends self::Super implements self::Mixin /*isAnonymousMixin,isEliminatedMixin*/ { + synthetic constructor named() → self::_Class&Super&Mixin + : super self::Super::named() + ; +} +class Class extends self::_Class&Super&Mixin { + constructor •() → self::Class + : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/missing_super_mixin_constructor.dart:12:3: Error: The superclass, 'Super', has no unnamed constructor that takes no arguments. + Class(); + ^^^^^" + ; +} diff --git a/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.textual_outline.expect b/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.textual_outline.expect new file mode 100644 index 00000000000..5d956aa30c9 --- /dev/null +++ b/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.textual_outline.expect @@ -0,0 +1,9 @@ +class Super { + Super.named(); +} + +mixin Mixin {} + +class Class extends Super with Mixin { + Class(); +} diff --git a/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.textual_outline_modelled.expect new file mode 100644 index 00000000000..6e5ac47dc4f --- /dev/null +++ b/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.textual_outline_modelled.expect @@ -0,0 +1,9 @@ +class Class extends Super with Mixin { + Class(); +} + +class Super { + Super.named(); +} + +mixin Mixin {} diff --git a/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.weak.expect b/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.weak.expect new file mode 100644 index 00000000000..ed613df630b --- /dev/null +++ b/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.weak.expect @@ -0,0 +1,30 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/general/missing_super_mixin_constructor.dart:12:3: Error: The superclass, 'Super', has no unnamed constructor that takes no arguments. +// Class(); +// ^^^^^ +// +import self as self; +import "dart:core" as core; + +class Super extends core::Object { + constructor named() → self::Super + : super core::Object::•() + ; +} +abstract class Mixin extends core::Object /*isMixinDeclaration*/ { +} +abstract class _Class&Super&Mixin = self::Super with self::Mixin /*isAnonymousMixin*/ { + synthetic constructor named() → self::_Class&Super&Mixin + : super self::Super::named() + ; +} +class Class extends self::_Class&Super&Mixin { + constructor •() → self::Class + : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/missing_super_mixin_constructor.dart:12:3: Error: The superclass, 'Super', has no unnamed constructor that takes no arguments. + Class(); + ^^^^^" + ; +} diff --git a/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.weak.modular.expect b/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.weak.modular.expect new file mode 100644 index 00000000000..ed613df630b --- /dev/null +++ b/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.weak.modular.expect @@ -0,0 +1,30 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/general/missing_super_mixin_constructor.dart:12:3: Error: The superclass, 'Super', has no unnamed constructor that takes no arguments. +// Class(); +// ^^^^^ +// +import self as self; +import "dart:core" as core; + +class Super extends core::Object { + constructor named() → self::Super + : super core::Object::•() + ; +} +abstract class Mixin extends core::Object /*isMixinDeclaration*/ { +} +abstract class _Class&Super&Mixin = self::Super with self::Mixin /*isAnonymousMixin*/ { + synthetic constructor named() → self::_Class&Super&Mixin + : super self::Super::named() + ; +} +class Class extends self::_Class&Super&Mixin { + constructor •() → self::Class + : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/missing_super_mixin_constructor.dart:12:3: Error: The superclass, 'Super', has no unnamed constructor that takes no arguments. + Class(); + ^^^^^" + ; +} diff --git a/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.weak.outline.expect b/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.weak.outline.expect new file mode 100644 index 00000000000..4509a921616 --- /dev/null +++ b/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.weak.outline.expect @@ -0,0 +1,19 @@ +library /*isNonNullableByDefault*/; +import self as self; +import "dart:core" as core; + +class Super extends core::Object { + constructor named() → self::Super + ; +} +abstract class Mixin extends core::Object /*isMixinDeclaration*/ { +} +abstract class _Class&Super&Mixin = self::Super with self::Mixin /*isAnonymousMixin*/ { + synthetic constructor named() → self::_Class&Super&Mixin + : super self::Super::named() + ; +} +class Class extends self::_Class&Super&Mixin { + constructor •() → self::Class + ; +} diff --git a/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.weak.transformed.expect b/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.weak.transformed.expect new file mode 100644 index 00000000000..1a93b6a0a1f --- /dev/null +++ b/pkg/front_end/testcases/general/missing_super_mixin_constructor.dart.weak.transformed.expect @@ -0,0 +1,30 @@ +library /*isNonNullableByDefault*/; +// +// Problems in library: +// +// pkg/front_end/testcases/general/missing_super_mixin_constructor.dart:12:3: Error: The superclass, 'Super', has no unnamed constructor that takes no arguments. +// Class(); +// ^^^^^ +// +import self as self; +import "dart:core" as core; + +class Super extends core::Object { + constructor named() → self::Super + : super core::Object::•() + ; +} +abstract class Mixin extends core::Object /*isMixinDeclaration*/ { +} +abstract class _Class&Super&Mixin extends self::Super implements self::Mixin /*isAnonymousMixin,isEliminatedMixin*/ { + synthetic constructor named() → self::_Class&Super&Mixin + : super self::Super::named() + ; +} +class Class extends self::_Class&Super&Mixin { + constructor •() → self::Class + : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/general/missing_super_mixin_constructor.dart:12:3: Error: The superclass, 'Super', has no unnamed constructor that takes no arguments. + Class(); + ^^^^^" + ; +}