[cfe] Use SourceCompilationUnit in SourceLoader.tokenize
This moves a lot of the methods needed for tokenization and
outline parsing from SourceLibraryBuilder to SourceCompilationUnitImpl.
Parts that are still used elsewhere remains in SourceLibraryBuilder
but accessed through SourceCompilationUnitImpl.
Change-Id: I0df431eee4c187e5447850961d2c27be14cb0ba3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/371682
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/front_end/lib/src/fasta/builder/library_builder.dart b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
index 92eb566..5ec9469d 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -5,10 +5,17 @@
library fasta.library_builder;
import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
-import 'package:kernel/ast.dart' show Class, Library;
+import 'package:_fe_analyzer_shared/src/parser/parser.dart'
+ show FormalParameterKind;
+import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
+import 'package:kernel/ast.dart'
+ show AsyncMarker, Class, Library, ProcedureKind;
+import '../../api_prototype/experimental_flags.dart';
import '../combinator.dart' show CombinatorBuilder;
+import '../configuration.dart';
import '../export.dart' show Export;
+import '../identifiers.dart';
import '../loader.dart' show Loader;
import '../messages.dart'
show
@@ -23,15 +30,23 @@
import '../source/name_scheme.dart';
import '../source/offset_map.dart';
import '../source/source_class_builder.dart';
+import '../source/source_enum_builder.dart';
import '../source/source_function_builder.dart';
import '../source/source_library_builder.dart';
+import '../source/source_loader.dart';
import 'builder.dart';
import 'constructor_reference_builder.dart';
import 'declaration_builders.dart';
+import 'formal_parameter_builder.dart';
import 'inferable_type_builder.dart';
import 'member_builder.dart';
+import 'metadata_builder.dart';
+import 'mixin_application_builder.dart';
import 'modifier_builder.dart';
import 'name_iterator.dart';
+import 'named_type_builder.dart';
+import 'nullability_builder.dart';
+import 'omitted_type_builder.dart';
import 'prefix_builder.dart';
import 'type_builder.dart';
@@ -97,10 +112,50 @@
abstract class SourceCompilationUnit implements CompilationUnit {
SourceLibraryBuilder createLibrary();
+ @override
+ SourceLoader get loader;
+
// TODO(johnniwinther): Remove this.
SourceLibraryBuilder get sourceLibraryBuilder;
- OffsetMap get offsetMap;
+ abstract OffsetMap offsetMap;
+
+ LibraryFeatures get libraryFeatures;
+
+ /// The current declaration that is being built. When we start parsing a
+ /// declaration (class, method, and so on), we don't have enough information
+ /// to create a builder and this object records its members and types until,
+ /// for example, [addClass] is called.
+ TypeParameterScopeBuilder get currentTypeParameterScopeBuilder;
+
+ void beginNestedDeclaration(TypeParameterScopeKind kind, String name,
+ {bool hasMembers = true});
+
+ TypeParameterScopeBuilder endNestedDeclaration(
+ TypeParameterScopeKind kind, String? name);
+
+ /// Call this when entering a class, mixin, enum, or extension type
+ /// declaration.
+ ///
+ /// This is done to set up the current [_indexedContainer] used to lookup
+ /// references of members from a previous incremental compilation.
+ ///
+ /// Called in `OutlineBuilder.beginClassDeclaration`,
+ /// `OutlineBuilder.beginEnum`, `OutlineBuilder.beginMixinDeclaration` and
+ /// `OutlineBuilder.beginExtensionTypeDeclaration`.
+ void beginIndexedContainer(String name,
+ {required bool isExtensionTypeDeclaration});
+
+ /// Call this when leaving a class, mixin, enum, or extension type
+ /// declaration.
+ ///
+ /// Called in `OutlineBuilder.endClassDeclaration`,
+ /// `OutlineBuilder.endEnum`, `OutlineBuilder.endMixinDeclaration` and
+ /// `OutlineBuilder.endExtensionTypeDeclaration`.
+ void endIndexedContainer();
+
+ String? computeAndValidateConstructorName(Identifier identifier,
+ {isFactory = false});
List<ConstructorReferenceBuilder> get constructorReferences;
@@ -111,6 +166,8 @@
// TODO(johnniwinther): Remove this.
Library get library;
+ abstract String? name;
+
// TODO(johnniwinther): Remove this?
LibraryName get libraryName;
@@ -126,6 +183,8 @@
Scope get scope;
+ abstract List<MetadataBuilder>? metadata;
+
List<NominalVariableBuilder> get unboundNominalVariables;
List<StructuralVariableBuilder> get unboundStructuralVariables;
@@ -138,6 +197,275 @@
void addDependencies(Library library, Set<SourceLibraryBuilder> seen);
void validatePart(SourceLibraryBuilder? library, Set<Uri>? usedParts);
+
+ void addScriptToken(int charOffset);
+
+ void addPart(OffsetMap offsetMap, Token partKeyword,
+ List<MetadataBuilder>? metadata, String uri, int charOffset);
+
+ void addPartOf(List<MetadataBuilder>? metadata, String? name, String? uri,
+ int uriOffset);
+
+ void addImport(
+ {OffsetMap? offsetMap,
+ Token? importKeyword,
+ required List<MetadataBuilder>? metadata,
+ required bool isAugmentationImport,
+ required String uri,
+ required List<Configuration>? configurations,
+ required String? prefix,
+ required List<CombinatorBuilder>? combinators,
+ required bool deferred,
+ required int charOffset,
+ required int prefixCharOffset,
+ required int uriOffset,
+ required int importIndex});
+
+ void addExport(
+ OffsetMap offsetMap,
+ Token exportKeyword,
+ List<MetadataBuilder>? metadata,
+ String uri,
+ List<Configuration>? configurations,
+ List<CombinatorBuilder>? combinators,
+ int charOffset,
+ int uriOffset);
+
+ void addClass(
+ OffsetMap offsetMap,
+ List<MetadataBuilder>? metadata,
+ int modifiers,
+ Identifier identifier,
+ List<NominalVariableBuilder>? typeVariables,
+ TypeBuilder? supertype,
+ MixinApplicationBuilder? mixins,
+ List<TypeBuilder>? interfaces,
+ int startOffset,
+ int nameOffset,
+ int endOffset,
+ int supertypeOffset,
+ {required bool isMacro,
+ required bool isSealed,
+ required bool isBase,
+ required bool isInterface,
+ required bool isFinal,
+ required bool isAugmentation,
+ required bool isMixinClass});
+
+ void addEnum(
+ OffsetMap offsetMap,
+ List<MetadataBuilder>? metadata,
+ Identifier identifier,
+ List<NominalVariableBuilder>? typeVariables,
+ MixinApplicationBuilder? supertypeBuilder,
+ List<TypeBuilder>? interfaceBuilders,
+ List<EnumConstantInfo?>? enumConstantInfos,
+ int startCharOffset,
+ int charEndOffset);
+
+ void addExtensionDeclaration(
+ OffsetMap offsetMap,
+ Token beginToken,
+ List<MetadataBuilder>? metadata,
+ int modifiers,
+ Identifier? identifier,
+ List<NominalVariableBuilder>? typeVariables,
+ TypeBuilder type,
+ int startOffset,
+ int nameOffset,
+ int endOffset);
+
+ void addExtensionTypeDeclaration(
+ OffsetMap offsetMap,
+ List<MetadataBuilder>? metadata,
+ int modifiers,
+ Identifier identifier,
+ List<NominalVariableBuilder>? typeVariables,
+ List<TypeBuilder>? interfaces,
+ int startOffset,
+ int endOffset);
+
+ void addMixinDeclaration(
+ OffsetMap offsetMap,
+ List<MetadataBuilder>? metadata,
+ int modifiers,
+ Identifier identifier,
+ List<NominalVariableBuilder>? typeVariables,
+ List<TypeBuilder>? supertypeConstraints,
+ List<TypeBuilder>? interfaces,
+ int startOffset,
+ int nameOffset,
+ int endOffset,
+ int supertypeOffset,
+ {required bool isBase,
+ required bool isAugmentation});
+
+ void addNamedMixinApplication(
+ List<MetadataBuilder>? metadata,
+ String name,
+ List<NominalVariableBuilder>? typeVariables,
+ int modifiers,
+ TypeBuilder? supertype,
+ MixinApplicationBuilder mixinApplication,
+ List<TypeBuilder>? interfaces,
+ int startCharOffset,
+ int charOffset,
+ int charEndOffset,
+ {required bool isMacro,
+ required bool isSealed,
+ required bool isBase,
+ required bool isInterface,
+ required bool isFinal,
+ required bool isAugmentation,
+ required bool isMixinClass});
+
+ MixinApplicationBuilder addMixinApplication(
+ List<TypeBuilder> mixins, int charOffset);
+
+ void addFunctionTypeAlias(
+ List<MetadataBuilder>? metadata,
+ String name,
+ List<NominalVariableBuilder>? typeVariables,
+ TypeBuilder type,
+ int charOffset);
+
+ void addConstructor(
+ OffsetMap offsetMap,
+ List<MetadataBuilder>? metadata,
+ int modifiers,
+ Identifier identifier,
+ String constructorName,
+ List<NominalVariableBuilder>? typeVariables,
+ List<FormalParameterBuilder>? formals,
+ int startCharOffset,
+ int charOffset,
+ int charOpenParenOffset,
+ int charEndOffset,
+ String? nativeMethodName,
+ {Token? beginInitializers,
+ required bool forAbstractClassOrMixin});
+
+ void addPrimaryConstructor(
+ {required OffsetMap offsetMap,
+ required Token beginToken,
+ required String constructorName,
+ required List<NominalVariableBuilder>? typeVariables,
+ required List<FormalParameterBuilder>? formals,
+ required int charOffset,
+ required bool isConst});
+
+ void addPrimaryConstructorField(
+ {required List<MetadataBuilder>? metadata,
+ required TypeBuilder type,
+ required String name,
+ required int charOffset});
+
+ void addFactoryMethod(
+ OffsetMap offsetMap,
+ List<MetadataBuilder>? metadata,
+ int modifiers,
+ Identifier identifier,
+ List<FormalParameterBuilder>? formals,
+ ConstructorReferenceBuilder? redirectionTarget,
+ int startCharOffset,
+ int charOffset,
+ int charOpenParenOffset,
+ int charEndOffset,
+ String? nativeMethodName,
+ AsyncMarker asyncModifier);
+
+ void addProcedure(
+ OffsetMap offsetMap,
+ List<MetadataBuilder>? metadata,
+ int modifiers,
+ TypeBuilder? returnType,
+ Identifier identifier,
+ String name,
+ List<NominalVariableBuilder>? typeVariables,
+ List<FormalParameterBuilder>? formals,
+ ProcedureKind kind,
+ int startCharOffset,
+ int charOffset,
+ int charOpenParenOffset,
+ int charEndOffset,
+ String? nativeMethodName,
+ AsyncMarker asyncModifier,
+ {required bool isInstanceMember,
+ required bool isExtensionMember,
+ required bool isExtensionTypeMember});
+
+ void addFields(
+ OffsetMap offsetMap,
+ List<MetadataBuilder>? metadata,
+ int modifiers,
+ bool isTopLevel,
+ TypeBuilder? type,
+ List<FieldInfo> fieldInfos);
+
+ FormalParameterBuilder addFormalParameter(
+ List<MetadataBuilder>? metadata,
+ FormalParameterKind kind,
+ int modifiers,
+ TypeBuilder type,
+ String name,
+ bool hasThis,
+ bool hasSuper,
+ int charOffset,
+ Token? initializerToken);
+
+ ConstructorReferenceBuilder addConstructorReference(TypeName name,
+ List<TypeBuilder>? typeArguments, String? suffix, int charOffset);
+
+ TypeBuilder addNamedType(
+ TypeName typeName,
+ NullabilityBuilder nullabilityBuilder,
+ List<TypeBuilder>? arguments,
+ int charOffset,
+ {required InstanceTypeVariableAccessState instanceTypeVariableAccess});
+
+ FunctionTypeBuilder addFunctionType(
+ TypeBuilder returnType,
+ List<StructuralVariableBuilder>? structuralVariableBuilders,
+ List<FormalParameterBuilder>? formals,
+ NullabilityBuilder nullabilityBuilder,
+ Uri fileUri,
+ int charOffset,
+ {required bool hasFunctionFormalParameterSyntax});
+
+ TypeBuilder addVoidType(int charOffset);
+
+ InferableTypeBuilder addInferableType();
+
+ NominalVariableBuilder addNominalTypeVariable(List<MetadataBuilder>? metadata,
+ String name, TypeBuilder? bound, int charOffset, Uri fileUri,
+ {required TypeVariableKind kind});
+
+ StructuralVariableBuilder addStructuralTypeVariable(
+ List<MetadataBuilder>? metadata,
+ String name,
+ TypeBuilder? bound,
+ int charOffset,
+ Uri fileUri);
+
+ /// Creates a copy of [original] into the scope of [declaration].
+ ///
+ /// This is used for adding copies of class type parameters to factory
+ /// methods and unnamed mixin applications, and for adding copies of
+ /// extension type parameters to extension instance methods.
+ ///
+ /// If [synthesizeTypeParameterNames] is `true` the names of the
+ /// [TypeParameter] are prefix with '#' to indicate that their synthesized.
+ List<NominalVariableBuilder> copyTypeVariables(
+ List<NominalVariableBuilder> original,
+ TypeParameterScopeBuilder declaration,
+ {required TypeVariableKind kind});
+
+ /// Reports that [feature] is not enabled, using [charOffset] and
+ /// [length] for the location of the message.
+ ///
+ /// Return the primary message.
+ Message reportFeatureNotEnabled(
+ LibraryFeature feature, Uri fileUri, int charOffset, int length);
}
abstract class LibraryBuilder implements Builder {
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index a9e1e4d..b6f0b24 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -1912,7 +1912,7 @@
combinator.fileOffset, libraryBuilder.fileUri));
}
- debugLibrary.addImport(
+ debugLibrary.compilationUnit.addImport(
metadata: null,
isAugmentationImport: false,
uri: dependency.importedLibraryReference.canonicalName!.name,
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index afae919..f587152 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -33,6 +33,7 @@
import '../builder/fixed_type_builder.dart';
import '../builder/formal_parameter_builder.dart';
import '../builder/invalid_type_builder.dart';
+import '../builder/library_builder.dart';
import '../builder/metadata_builder.dart';
import '../builder/mixin_application_builder.dart';
import '../builder/named_type_builder.dart';
@@ -504,6 +505,8 @@
@override
final SourceLibraryBuilder libraryBuilder;
+ final SourceCompilationUnit compilationUnit;
+
final bool enableNative;
bool inAbstractOrSealedClass = false;
bool inConstructor = false;
@@ -540,9 +543,10 @@
OffsetMap _offsetMap;
- OutlineBuilder(this.libraryBuilder, this._offsetMap)
- : enableNative = libraryBuilder.loader.target.backendTarget
- .enableNative(libraryBuilder.importUri);
+ OutlineBuilder(this.compilationUnit, this._offsetMap)
+ : enableNative = compilationUnit.loader.target.backendTarget
+ .enableNative(compilationUnit.importUri),
+ libraryBuilder = compilationUnit.sourceLibraryBuilder;
DeclarationContext get declarationContext => _declarationContext.head;
@@ -559,7 +563,7 @@
}
@override
- Uri get uri => libraryBuilder.fileUri;
+ Uri get uri => compilationUnit.fileUri;
int popCharOffset() => pop() as int;
@@ -638,7 +642,7 @@
push(names);
} else {
push(new CombinatorBuilder.hide(names as Iterable<String>,
- hideKeyword.charOffset, libraryBuilder.fileUri));
+ hideKeyword.charOffset, compilationUnit.fileUri));
}
}
@@ -650,7 +654,7 @@
push(names);
} else {
push(new CombinatorBuilder.show(names as Iterable<String>,
- showKeyword.charOffset, libraryBuilder.fileUri));
+ showKeyword.charOffset, compilationUnit.fileUri));
}
}
@@ -680,7 +684,7 @@
int uriOffset = popCharOffset();
String uri = pop() as String;
List<MetadataBuilder>? metadata = pop() as List<MetadataBuilder>?;
- libraryBuilder.addExport(_offsetMap, exportKeyword, metadata, uri,
+ compilationUnit.addExport(_offsetMap, exportKeyword, metadata, uri,
configurations, combinators, exportKeyword.charOffset, uriOffset);
checkEmpty(exportKeyword.charOffset);
}
@@ -734,7 +738,7 @@
}
}
bool isAugmentationImport = augmentToken != null;
- libraryBuilder.addImport(
+ compilationUnit.addImport(
offsetMap: _offsetMap,
importKeyword: importKeyword,
metadata: metadata,
@@ -815,7 +819,7 @@
int charOffset = popCharOffset();
String uri = pop() as String;
List<MetadataBuilder>? metadata = pop() as List<MetadataBuilder>?;
- libraryBuilder.addPart(_offsetMap, partKeyword, metadata, uri, charOffset);
+ compilationUnit.addPart(_offsetMap, partKeyword, metadata, uri, charOffset);
checkEmpty(partKeyword.charOffset);
}
@@ -955,13 +959,13 @@
}
List<MetadataBuilder>? metadata = pop() as List<MetadataBuilder>?;
if (name != null && name is! ParserRecovery) {
- libraryBuilder.name =
+ compilationUnit.name =
flattenName(name, offsetForToken(libraryKeyword), uri);
} else {
reportIfNotEnabled(
libraryFeatures.unnamedLibraries, semicolon.charOffset, noLength);
}
- libraryBuilder.metadata = metadata;
+ compilationUnit.metadata = metadata;
}
@override
@@ -977,7 +981,7 @@
pop() as int;
pop() as String;
List<MetadataBuilder>? metadata = pop() as List<MetadataBuilder>?;
- libraryBuilder.metadata = metadata;
+ compilationUnit.metadata = metadata;
}
@override
@@ -985,7 +989,7 @@
debugEvent("beginClassOrNamedMixinApplicationPrelude");
pushDeclarationContext(
DeclarationContext.ClassOrMixinOrNamedMixinApplication);
- libraryBuilder.beginNestedDeclaration(
+ compilationUnit.beginNestedDeclaration(
TypeParameterScopeKind.classOrNamedMixinApplication,
"class or mixin application");
}
@@ -1045,9 +1049,9 @@
mixinToken = null;
}
}
- libraryBuilder.currentTypeParameterScopeBuilder
+ compilationUnit.currentTypeParameterScopeBuilder
.markAsClassDeclaration(name.lexeme, name.charOffset, typeVariables);
- libraryBuilder.beginIndexedContainer(name.lexeme,
+ compilationUnit.beginIndexedContainer(name.lexeme,
isExtensionTypeDeclaration: false);
inAbstractOrSealedClass = abstractToken != null || sealedToken != null;
push(abstractToken != null ? abstractMask : 0);
@@ -1078,9 +1082,9 @@
push(augmentToken ?? NullValues.Token);
push(baseToken ?? NullValues.Token);
push(typeVariables ?? NullValues.NominalVariables);
- libraryBuilder.currentTypeParameterScopeBuilder
+ compilationUnit.currentTypeParameterScopeBuilder
.markAsMixinDeclaration(name.lexeme, name.charOffset, typeVariables);
- libraryBuilder.beginIndexedContainer(name.lexeme,
+ compilationUnit.beginIndexedContainer(name.lexeme,
isExtensionTypeDeclaration: false);
}
@@ -1115,7 +1119,7 @@
Object? extensionThisType = peek();
if (extensionThisType is TypeBuilder) {
- libraryBuilder.currentTypeParameterScopeBuilder
+ compilationUnit.currentTypeParameterScopeBuilder
.registerExtensionThisType(extensionThisType);
} else {
// TODO(johnniwinther): Supply an invalid type as the extension on type.
@@ -1125,8 +1129,8 @@
// Resolve unresolved types from the class header (i.e., superclass, mixins,
// and implemented types) before adding members from the class body which
// should not shadow these unresolved types.
- libraryBuilder.currentTypeParameterScopeBuilder.resolveNamedTypes(
- libraryBuilder.currentTypeParameterScopeBuilder.typeVariables,
+ compilationUnit.currentTypeParameterScopeBuilder.resolveNamedTypes(
+ compilationUnit.currentTypeParameterScopeBuilder.typeVariables,
libraryBuilder);
}
@@ -1149,8 +1153,9 @@
List<NominalVariableBuilder>? typeVariables =
pop() as List<NominalVariableBuilder>?;
push(typeVariables ?? NullValues.NominalVariables);
- libraryBuilder.currentTypeParameterScopeBuilder.markAsNamedMixinApplication(
- name.lexeme, name.charOffset, typeVariables);
+ compilationUnit.currentTypeParameterScopeBuilder
+ .markAsNamedMixinApplication(
+ name.lexeme, name.charOffset, typeVariables);
push(abstractToken != null ? abstractMask : 0);
if (macroToken != null) {
if (reportIfNotEnabled(
@@ -1316,7 +1321,7 @@
inAbstractOrSealedClass = false;
checkEmpty(beginToken.charOffset);
if (name is ParserRecovery) {
- libraryBuilder
+ compilationUnit
.endNestedDeclaration(
TypeParameterScopeKind.classDeclaration, "<syntax-error>")
.resolveNamedTypes(typeVariables, libraryBuilder);
@@ -1328,7 +1333,7 @@
String classNameForErrors = identifier.name;
if (supertype != null) {
if (supertype.nullabilityBuilder.build() == Nullability.nullable) {
- libraryBuilder.addProblem(
+ compilationUnit.addProblem(
templateNullableSuperclassError
.withArguments(supertype.fullNameForErrors),
identifier.nameOffset,
@@ -1340,7 +1345,7 @@
List<TypeBuilder>? mixins = mixinApplication.mixins;
for (TypeBuilder mixin in mixins) {
if (mixin.nullabilityBuilder.build() == Nullability.nullable) {
- libraryBuilder.addProblem(
+ compilationUnit.addProblem(
templateNullableMixinError
.withArguments(mixin.fullNameForErrors),
identifier.nameOffset,
@@ -1352,7 +1357,7 @@
if (interfaces != null) {
for (TypeBuilder interface in interfaces) {
if (interface.nullabilityBuilder.build() == Nullability.nullable) {
- libraryBuilder.addProblem(
+ compilationUnit.addProblem(
templateNullableInterfaceError
.withArguments(interface.fullNameForErrors),
identifier.nameOffset,
@@ -1365,7 +1370,7 @@
if (sealedToken != null) {
modifiers |= abstractMask;
}
- libraryBuilder.addClass(
+ compilationUnit.addClass(
_offsetMap,
metadata,
modifiers,
@@ -1386,7 +1391,7 @@
isAugmentation: augmentToken != null,
isMixinClass: mixinToken != null);
}
- libraryBuilder.endIndexedContainer();
+ compilationUnit.endIndexedContainer();
popDeclarationContext(DeclarationContext.Class);
}
@@ -1423,7 +1428,7 @@
pop(NullValues.Metadata) as List<MetadataBuilder>?;
checkEmpty(beginToken.charOffset);
if (name is ParserRecovery) {
- libraryBuilder
+ compilationUnit
.endNestedDeclaration(
TypeParameterScopeKind.mixinDeclaration, "<syntax-error>")
.resolveNamedTypes(typeVariables, libraryBuilder);
@@ -1435,7 +1440,7 @@
if (supertypeConstraints != null) {
for (TypeBuilder supertype in supertypeConstraints) {
if (supertype.nullabilityBuilder.build() == Nullability.nullable) {
- libraryBuilder.addProblem(
+ compilationUnit.addProblem(
templateNullableSuperclassError
.withArguments(supertype.fullNameForErrors),
identifier.nameOffset,
@@ -1447,7 +1452,7 @@
if (interfaces != null) {
for (TypeBuilder interface in interfaces) {
if (interface.nullabilityBuilder.build() == Nullability.nullable) {
- libraryBuilder.addProblem(
+ compilationUnit.addProblem(
templateNullableInterfaceError
.withArguments(interface.fullNameForErrors),
identifier.nameOffset,
@@ -1457,7 +1462,7 @@
}
}
- libraryBuilder.addMixinDeclaration(
+ compilationUnit.addMixinDeclaration(
_offsetMap,
metadata,
mixinDeclarationMask,
@@ -1472,7 +1477,7 @@
isBase: baseToken != null,
isAugmentation: augmentToken != null);
}
- libraryBuilder.endIndexedContainer();
+ compilationUnit.endIndexedContainer();
popDeclarationContext(DeclarationContext.Mixin);
}
@@ -1481,7 +1486,7 @@
assert(checkState(extensionKeyword, [ValueKinds.MetadataListOrNull]));
debugEvent("beginExtensionDeclaration");
pushDeclarationContext(DeclarationContext.ExtensionOrExtensionType);
- libraryBuilder.beginNestedDeclaration(
+ compilationUnit.beginNestedDeclaration(
TypeParameterScopeKind.extensionOrExtensionTypeDeclaration,
"extension");
}
@@ -1501,7 +1506,7 @@
? new SimpleIdentifier(nameToken)
: NullValues.Identifier);
push(typeVariables ?? NullValues.NominalVariables);
- libraryBuilder.currentTypeParameterScopeBuilder
+ compilationUnit.currentTypeParameterScopeBuilder
.markAsExtensionDeclaration(nameToken?.lexeme, offset, typeVariables);
}
@@ -1532,7 +1537,7 @@
int startOffset = metadata == null
? extensionKeyword.charOffset
: metadata.first.charOffset;
- libraryBuilder.addExtensionDeclaration(
+ compilationUnit.addExtensionDeclaration(
_offsetMap,
beginToken,
metadata,
@@ -1561,9 +1566,9 @@
int offset = nameToken.charOffset;
push(new SimpleIdentifier(nameToken));
push(typeVariables ?? NullValues.NominalVariables);
- libraryBuilder.currentTypeParameterScopeBuilder
+ compilationUnit.currentTypeParameterScopeBuilder
.markAsExtensionTypeDeclaration(name, offset, typeVariables);
- libraryBuilder.beginIndexedContainer(name,
+ compilationUnit.beginIndexedContainer(name,
isExtensionTypeDeclaration: true);
}
@@ -1593,7 +1598,7 @@
int startOffset = metadata == null
? extensionKeyword.charOffset
: metadata.first.charOffset;
- libraryBuilder.addExtensionTypeDeclaration(
+ compilationUnit.addExtensionTypeDeclaration(
_offsetMap,
metadata,
// TODO(johnniwinther): Support modifiers on extension types?
@@ -1604,7 +1609,7 @@
startOffset,
endToken.charOffset);
- libraryBuilder.endIndexedContainer();
+ compilationUnit.endIndexedContainer();
popDeclarationContext(DeclarationContext.ExtensionType);
}
@@ -1641,7 +1646,7 @@
TypeBuilder type = formal.type;
if (type is FunctionTypeBuilder &&
type.hasFunctionFormalParameterSyntax) {
- libraryBuilder.addProblem(
+ compilationUnit.addProblem(
// ignore: lines_longer_than_80_chars
messageExtensionTypePrimaryConstructorFunctionFormalParameterSyntax,
formal.charOffset,
@@ -1649,7 +1654,7 @@
formal.fileUri);
}
if (type is ImplicitTypeBuilder) {
- libraryBuilder.addProblem(messageExpectedRepresentationType,
+ compilationUnit.addProblem(messageExpectedRepresentationType,
formal.charOffset, formal.name.length, formal.fileUri);
formal.type =
new InvalidTypeBuilderImpl(formal.fileUri, formal.charOffset);
@@ -1659,11 +1664,11 @@
Modifier.removeCovariantMask(
// 'required' is reported in the parser.
Modifier.removeRequiredMask(formal.modifiers)))) {
- libraryBuilder.addProblem(messageRepresentationFieldModifier,
+ compilationUnit.addProblem(messageRepresentationFieldModifier,
formal.charOffset, formal.name.length, formal.fileUri);
}
if (formal.isInitializingFormal) {
- libraryBuilder.addProblem(
+ compilationUnit.addProblem(
messageExtensionTypePrimaryConstructorWithInitializingFormal,
formal.charOffset,
formal.name.length,
@@ -1681,7 +1686,7 @@
if (formal.isNamed) {
firstNamedParameterOffset = formal.charOffset;
}
- libraryBuilder.addPrimaryConstructorField(
+ compilationUnit.addPrimaryConstructorField(
// TODO(johnniwinther): Support annotations on annotations on fields
// defined through a primary constructor. This is not needed for
// extension types where the field is not part of the AST but will
@@ -1694,40 +1699,40 @@
}
if (inExtensionType) {
if (firstOptionalPositionalParameterOffset != null) {
- libraryBuilder.addProblem(
+ compilationUnit.addProblem(
messageOptionalParametersInExtensionTypeDeclaration,
firstOptionalPositionalParameterOffset,
1,
uri);
} else if (firstNamedParameterOffset != null) {
- libraryBuilder.addProblem(
+ compilationUnit.addProblem(
messageNamedParametersInExtensionTypeDeclaration,
firstNamedParameterOffset,
1,
uri);
} else if (requiredPositionalCount == 0) {
- libraryBuilder.addProblem(
+ compilationUnit.addProblem(
messageExpectedRepresentationField, charOffset, 1, uri);
} else if (formals.length > 1) {
- libraryBuilder.addProblem(
+ compilationUnit.addProblem(
messageMultipleRepresentationFields, charOffset, 1, uri);
}
}
}
- libraryBuilder.beginNestedDeclaration(
+ compilationUnit.beginNestedDeclaration(
TypeParameterScopeKind.constructor, "#method",
hasMembers: false);
- TypeParameterScopeBuilder scopeBuilder = libraryBuilder
+ TypeParameterScopeBuilder scopeBuilder = compilationUnit
.endNestedDeclaration(TypeParameterScopeKind.constructor, "#method");
var (
List<NominalVariableBuilder>? typeVariables,
_
) = _createSyntheticTypeVariables(
- libraryBuilder.currentTypeParameterScopeBuilder, scopeBuilder, null);
+ compilationUnit.currentTypeParameterScopeBuilder, scopeBuilder, null);
scopeBuilder.resolveNamedTypes(typeVariables, libraryBuilder);
- libraryBuilder.addPrimaryConstructor(
+ compilationUnit.addPrimaryConstructor(
offsetMap: _offsetMap,
beginToken: beginToken,
constructorName: constructorName == "new" ? "" : constructorName,
@@ -1749,7 +1754,7 @@
void beginTopLevelMethod(
Token lastConsumed, Token? augmentToken, Token? externalToken) {
pushDeclarationContext(DeclarationContext.TopLevelMethod);
- libraryBuilder.beginNestedDeclaration(
+ compilationUnit.beginNestedDeclaration(
TypeParameterScopeKind.topLevelMethod, "#method",
hasMembers: false);
int modifiers = 0;
@@ -1806,13 +1811,13 @@
}
List<MetadataBuilder>? metadata = pop() as List<MetadataBuilder>?;
checkEmpty(beginToken.charOffset);
- libraryBuilder
+ compilationUnit
.endNestedDeclaration(TypeParameterScopeKind.topLevelMethod, "#method")
.resolveNamedTypes(typeVariables, libraryBuilder);
if (identifier is Identifier) {
final int startCharOffset =
metadata == null ? beginToken.charOffset : metadata.first.charOffset;
- libraryBuilder.addProcedure(
+ compilationUnit.addProcedure(
_offsetMap,
metadata,
modifiers,
@@ -1887,7 +1892,7 @@
Token? getOrSet,
Token name) {
inConstructor =
- name.lexeme == libraryBuilder.currentTypeParameterScopeBuilder.name &&
+ name.lexeme == compilationUnit.currentTypeParameterScopeBuilder.name &&
getOrSet == null;
DeclarationContext declarationContext;
switch (declarationKind) {
@@ -1987,7 +1992,7 @@
} else {
kind = TypeParameterScopeKind.instanceMethod;
}
- libraryBuilder.beginNestedDeclaration(kind, "#method", hasMembers: false);
+ compilationUnit.beginNestedDeclaration(kind, "#method", hasMembers: false);
}
@override
@@ -2065,7 +2070,7 @@
// rename 'T' to '#T'. We cannot do it on the builders because their
// names are used to create the scope.
List<NominalVariableBuilder> synthesizedTypeVariables =
- libraryBuilder.copyTypeVariables(
+ compilationUnit.copyTypeVariables(
enclosingDeclarationScopeBuilder.typeVariables!,
memberScopeBuilder,
kind: TypeVariableKind.extensionSynthesized);
@@ -2127,7 +2132,7 @@
scopeKind = TypeParameterScopeKind.instanceMethod;
}
TypeParameterScopeBuilder declarationBuilder =
- libraryBuilder.endNestedDeclaration(scopeKind, "#method");
+ compilationUnit.endNestedDeclaration(scopeKind, "#method");
if (identifier is! Identifier) {
assert(identifier is ParserRecovery,
@@ -2236,7 +2241,7 @@
case _MethodKind.extensionTypeConstructor:
case _MethodKind.enumConstructor:
constructorName =
- libraryBuilder.computeAndValidateConstructorName(identifier) ??
+ compilationUnit.computeAndValidateConstructorName(identifier) ??
name;
break;
case _MethodKind.classMethod:
@@ -2249,7 +2254,7 @@
bool isStatic = (modifiers & staticMask) != 0;
bool isConstructor = constructorName != null;
bool cloneTypeVariablesFromEnclosingDeclaration;
- switch (libraryBuilder.currentTypeParameterScopeBuilder.kind) {
+ switch (compilationUnit.currentTypeParameterScopeBuilder.kind) {
case TypeParameterScopeKind.extensionDeclaration:
case TypeParameterScopeKind.extensionTypeDeclaration:
cloneTypeVariablesFromEnclosingDeclaration = !isStatic;
@@ -2272,7 +2277,7 @@
}
if (cloneTypeVariablesFromEnclosingDeclaration) {
TypeParameterScopeBuilder declaration =
- libraryBuilder.currentTypeParameterScopeBuilder;
+ compilationUnit.currentTypeParameterScopeBuilder;
Map<NominalVariableBuilder, TypeBuilder>? substitution;
(typeVariables, substitution) = _createSyntheticTypeVariables(
declaration, declarationBuilder, typeVariables);
@@ -2282,7 +2287,7 @@
if (declaration.kind == TypeParameterScopeKind.extensionDeclaration) {
thisType = declaration.extensionThisType;
} else {
- thisType = libraryBuilder.addNamedType(
+ thisType = compilationUnit.addNamedType(
new SyntheticTypeName(declaration.name, charOffset),
const NullabilityBuilder.omitted(),
declaration.typeVariables != null
@@ -2308,7 +2313,7 @@
for (NamedTypeBuilder unboundType in unboundTypes) {
declaration.registerUnresolvedNamedType(unboundType);
}
- libraryBuilder.unboundStructuralVariables
+ compilationUnit.unboundStructuralVariables
.addAll(unboundTypeVariables);
}
synthesizedFormals.add(new FormalParameterBuilder(
@@ -2343,7 +2348,7 @@
}
final int startCharOffset =
metadata == null ? beginToken.charOffset : metadata.first.charOffset;
- libraryBuilder.addConstructor(
+ compilationUnit.addConstructor(
_offsetMap,
metadata,
modifiers,
@@ -2370,7 +2375,7 @@
bool isExtensionMember = methodKind == _MethodKind.extensionMethod;
bool isExtensionTypeMember =
methodKind == _MethodKind.extensionTypeMethod;
- libraryBuilder.addProcedure(
+ compilationUnit.addProcedure(
_offsetMap,
metadata,
modifiers,
@@ -2412,7 +2417,7 @@
if (mixins is ParserRecovery) {
push(mixins);
} else {
- push(libraryBuilder.addMixinApplication(
+ push(compilationUnit.addMixinApplication(
mixins as List<TypeBuilder>, withKeyword.charOffset));
}
assert(checkState(withKeyword, [
@@ -2499,7 +2504,7 @@
if (name is ParserRecovery ||
supertype is ParserRecovery ||
mixinApplication is ParserRecovery) {
- libraryBuilder
+ compilationUnit
.endNestedDeclaration(
TypeParameterScopeKind.namedMixinApplication, "<syntax-error>")
.resolveNamedTypes(typeVariables, libraryBuilder);
@@ -2511,7 +2516,7 @@
List<TypeBuilder> mixins = mixinApplicationBuilder.mixins;
if (supertype is TypeBuilder && supertype is! MixinApplicationBuilder) {
if (supertype.nullabilityBuilder.build() == Nullability.nullable) {
- libraryBuilder.addProblem(
+ compilationUnit.addProblem(
templateNullableSuperclassError
.withArguments(supertype.fullNameForErrors),
identifier.nameOffset,
@@ -2521,7 +2526,7 @@
}
for (TypeBuilder mixin in mixins) {
if (mixin.nullabilityBuilder.build() == Nullability.nullable) {
- libraryBuilder.addProblem(
+ compilationUnit.addProblem(
templateNullableMixinError.withArguments(mixin.fullNameForErrors),
identifier.nameOffset,
classNameForErrors.length,
@@ -2531,7 +2536,7 @@
if (interfaces != null) {
for (TypeBuilder interface in interfaces) {
if (interface.nullabilityBuilder.build() == Nullability.nullable) {
- libraryBuilder.addProblem(
+ compilationUnit.addProblem(
templateNullableInterfaceError
.withArguments(interface.fullNameForErrors),
identifier.nameOffset,
@@ -2547,7 +2552,7 @@
int startCharOffset = beginToken.charOffset;
int charEndOffset = endToken.charOffset;
- libraryBuilder.addNamedMixinApplication(
+ compilationUnit.addNamedMixinApplication(
metadata,
identifier.name,
typeVariables,
@@ -2592,7 +2597,7 @@
@override
void handleScript(Token token) {
debugEvent("handleScript");
- libraryBuilder.addScriptToken(token.charOffset);
+ compilationUnit.addScriptToken(token.charOffset);
}
@override
@@ -2612,7 +2617,7 @@
push(name);
} else {
Identifier identifier = name as Identifier;
- push(libraryBuilder.addNamedType(
+ push(compilationUnit.addNamedType(
identifier.typeName,
isMarkedAsNullable
? const NullabilityBuilder.nullable()
@@ -2659,14 +2664,14 @@
@override
void handleVoidKeyword(Token token) {
debugEvent("VoidKeyword");
- push(libraryBuilder.addVoidType(token.charOffset));
+ push(compilationUnit.addVoidType(token.charOffset));
}
@override
void handleVoidKeywordWithTypeArguments(Token token) {
debugEvent("VoidKeyword");
/*List<TypeBuilder> arguments =*/ pop();
- push(libraryBuilder.addVoidType(token.charOffset));
+ push(compilationUnit.addVoidType(token.charOffset));
}
@override
@@ -2714,13 +2719,13 @@
push(name);
} else {
Identifier? identifier = name as Identifier?;
- push(libraryBuilder.addFormalParameter(
+ push(compilationUnit.addFormalParameter(
metadata,
kind,
modifiers,
type ??
(memberKind.isParameterInferable
- ? libraryBuilder.addInferableType()
+ ? compilationUnit.addInferableType()
: const ImplicitTypeBuilder()),
identifier == null
? FormalParameterBuilder.noNameSentinel
@@ -2793,7 +2798,7 @@
optional(",", tokenBeforeEnd) &&
kind == MemberKind.PrimaryConstructor &&
declarationContext == DeclarationContext.ExtensionType) {
- libraryBuilder.addProblem(messageRepresentationFieldTrailingComma,
+ compilationUnit.addProblem(messageRepresentationFieldTrailingComma,
tokenBeforeEnd.charOffset, 1, uri);
}
} else if (count > 1) {
@@ -2871,7 +2876,7 @@
formals != null) {
for (FormalParameterBuilder formal in formals) {
if (formal.isSuperInitializingFormal) {
- libraryBuilder.addProblem(
+ compilationUnit.addProblem(
messageExtensionTypeConstructorWithSuperFormalParameter,
formal.charOffset,
formal.name.length,
@@ -2909,10 +2914,10 @@
} else {
declarationName = '#enum';
}
- libraryBuilder.beginIndexedContainer(declarationName,
+ compilationUnit.beginIndexedContainer(declarationName,
isExtensionTypeDeclaration: false);
pushDeclarationContext(DeclarationContext.Enum);
- libraryBuilder.beginNestedDeclaration(
+ compilationUnit.beginNestedDeclaration(
TypeParameterScopeKind.enumDeclaration, declarationName);
}
@@ -2963,11 +2968,11 @@
Object? identifier = peek();
if (identifier is Identifier) {
- libraryBuilder.currentTypeParameterScopeBuilder.markAsEnumDeclaration(
+ compilationUnit.currentTypeParameterScopeBuilder.markAsEnumDeclaration(
identifier.name, identifier.nameOffset, typeVariables);
} else {
identifier as ParserRecovery;
- libraryBuilder.currentTypeParameterScopeBuilder.markAsEnumDeclaration(
+ compilationUnit.currentTypeParameterScopeBuilder.markAsEnumDeclaration(
"<syntax-error>", identifier.charOffset, typeVariables);
}
@@ -3054,7 +3059,7 @@
if (interfaces != null) {
for (TypeBuilder interface in interfaces) {
if (interface.nullabilityBuilder.build() == Nullability.nullable) {
- libraryBuilder.addProblem(
+ compilationUnit.addProblem(
templateNullableInterfaceError
.withArguments(interface.fullNameForErrors),
interface.charOffset ?? startCharOffset,
@@ -3064,7 +3069,7 @@
}
}
- libraryBuilder.addEnum(
+ compilationUnit.addEnum(
_offsetMap,
metadata,
identifier,
@@ -3075,13 +3080,13 @@
startCharOffset,
endCharOffset);
} else {
- libraryBuilder
+ compilationUnit
.endNestedDeclaration(
TypeParameterScopeKind.enumDeclaration, "<syntax-error>")
.resolveNamedTypes(typeVariables, libraryBuilder);
}
- libraryBuilder.endIndexedContainer();
+ compilationUnit.endIndexedContainer();
checkEmpty(enumKeyword.charOffset);
popDeclarationContext(DeclarationContext.Enum);
}
@@ -3089,7 +3094,7 @@
@override
void beginTypedef(Token token) {
pushDeclarationContext(DeclarationContext.Typedef);
- libraryBuilder.beginNestedDeclaration(
+ compilationUnit.beginNestedDeclaration(
TypeParameterScopeKind.typedef, "#typedef",
hasMembers: false);
}
@@ -3098,7 +3103,7 @@
void beginFunctionType(Token beginToken) {
debugEvent("beginFunctionType");
_structuralParameterDepthLevel++;
- libraryBuilder.beginNestedDeclaration(
+ compilationUnit.beginNestedDeclaration(
TypeParameterScopeKind.functionType, "#function_type",
hasMembers: false);
}
@@ -3107,7 +3112,7 @@
void beginFunctionTypedFormalParameter(Token token) {
debugEvent("beginFunctionTypedFormalParameter");
_insideOfFormalParameterType = false;
- libraryBuilder.beginNestedDeclaration(
+ compilationUnit.beginNestedDeclaration(
TypeParameterScopeKind.functionType, "#function_type",
hasMembers: false);
}
@@ -3197,7 +3202,7 @@
TypeBuilder? returnType = pop() as TypeBuilder?;
List<StructuralVariableBuilder>? typeVariables =
pop() as List<StructuralVariableBuilder>?;
- push(libraryBuilder.addFunctionType(
+ push(compilationUnit.addFunctionType(
returnType ?? const ImplicitTypeBuilder(),
typeVariables,
formals,
@@ -3218,7 +3223,7 @@
TypeBuilder? returnType = pop() as TypeBuilder?;
List<StructuralVariableBuilder>? typeVariables =
pop() as List<StructuralVariableBuilder>?;
- push(libraryBuilder.addFunctionType(
+ push(compilationUnit.addFunctionType(
returnType ?? const ImplicitTypeBuilder(),
typeVariables,
formals,
@@ -3271,7 +3276,7 @@
// `library.addFunctionType`.
if (name is ParserRecovery) {
pop(NullValues.Metadata); // Metadata.
- libraryBuilder
+ compilationUnit
.endNestedDeclaration(
TypeParameterScopeKind.typedef, "<syntax-error>")
.resolveNamedTypes(typeVariables, libraryBuilder);
@@ -3279,11 +3284,11 @@
return;
}
identifier = name as Identifier;
- libraryBuilder.beginNestedDeclaration(
+ compilationUnit.beginNestedDeclaration(
TypeParameterScopeKind.functionType, "#function_type",
hasMembers: false);
// TODO(cstefantsova): Make sure that RHS of typedefs can't have '?'.
- aliasedType = libraryBuilder.addFunctionType(
+ aliasedType = compilationUnit.addFunctionType(
returnType ?? const ImplicitTypeBuilder(),
null,
formals,
@@ -3298,7 +3303,7 @@
name = pop();
if (name is ParserRecovery) {
pop(NullValues.Metadata); // Metadata.
- libraryBuilder
+ compilationUnit
.endNestedDeclaration(
TypeParameterScopeKind.functionType, "<syntax-error>")
.resolveNamedTypes(typeVariables, libraryBuilder);
@@ -3309,9 +3314,6 @@
if (type is FunctionTypeBuilder &&
!libraryFeatures.nonfunctionTypeAliases.isEnabled) {
if (type.nullabilityBuilder.build() == Nullability.nullable) {
- // The error is reported when the non-nullable experiment is enabled.
- // Otherwise, the attempt to use a nullable type will be reported
- // elsewhere.
addProblem(
messageTypedefNullableType, equals.charOffset, equals.length);
aliasedType = new NamedTypeBuilderImpl.fromTypeDeclarationBuilder(
@@ -3375,7 +3377,7 @@
pop(NullValues.Metadata) as List<MetadataBuilder>?;
checkEmpty(typedefKeyword.charOffset);
- libraryBuilder.addFunctionTypeAlias(metadata, identifier.name,
+ compilationUnit.addFunctionTypeAlias(metadata, identifier.name,
typeVariables, aliasedType, identifier.nameOffset);
popDeclarationContext(DeclarationContext.Typedef);
}
@@ -3478,7 +3480,7 @@
List<MetadataBuilder>? metadata = pop() as List<MetadataBuilder>?;
checkEmpty(beginToken.charOffset);
if (fieldInfos != null) {
- libraryBuilder.addFields(_offsetMap, metadata, modifiers,
+ compilationUnit.addFields(_offsetMap, metadata, modifiers,
/* isTopLevel = */ true, type, fieldInfos);
}
popDeclarationContext();
@@ -3541,7 +3543,7 @@
}
List<MetadataBuilder>? metadata = pop() as List<MetadataBuilder>?;
if (fieldInfos != null) {
- libraryBuilder.addFields(_offsetMap, metadata, modifiers,
+ compilationUnit.addFields(_offsetMap, metadata, modifiers,
/* isTopLevel = */ false, type, fieldInfos);
}
popDeclarationContext();
@@ -3591,10 +3593,10 @@
} else {
Identifier identifier = name as Identifier;
if (inFunctionType) {
- push(libraryBuilder.addStructuralTypeVariable(
+ push(compilationUnit.addStructuralTypeVariable(
metadata, identifier.name, null, identifier.nameOffset, uri));
} else {
- push(libraryBuilder.addNominalTypeVariable(
+ push(compilationUnit.addNominalTypeVariable(
metadata, identifier.name, null, identifier.nameOffset, uri,
kind: declarationContext.typeVariableKind));
}
@@ -3672,7 +3674,7 @@
if (hasName) {
Identifier containingLibrary = pop() as Identifier;
List<MetadataBuilder>? metadata = pop() as List<MetadataBuilder>?;
- libraryBuilder.addPartOf(
+ compilationUnit.addPartOf(
metadata,
flattenName(containingLibrary, containingLibrary.firstOffset, uri),
null,
@@ -3681,7 +3683,7 @@
int charOffset = popCharOffset();
String uriString = pop() as String;
List<MetadataBuilder>? metadata = pop() as List<MetadataBuilder>?;
- libraryBuilder.addPartOf(metadata, null, uriString, charOffset);
+ compilationUnit.addPartOf(metadata, null, uriString, charOffset);
}
}
@@ -3702,19 +3704,19 @@
if (name is ParserRecovery) {
push(name);
} else if (name is Identifier) {
- push(libraryBuilder.addConstructorReference(
+ push(compilationUnit.addConstructorReference(
name.typeName, typeArguments, suffix?.name, name.qualifierOffset));
} else {
assert(name == null);
// At the moment, the name of the type in a constructor reference can be
// omitted only within an enum element declaration.
- if (libraryBuilder.currentTypeParameterScopeBuilder.kind ==
+ if (compilationUnit.currentTypeParameterScopeBuilder.kind ==
TypeParameterScopeKind.enumDeclaration) {
if (libraryFeatures.enhancedEnums.isEnabled) {
int constructorNameOffset = suffix?.nameOffset ?? charOffset;
- push(libraryBuilder.addConstructorReference(
+ push(compilationUnit.addConstructorReference(
new SyntheticTypeName(
- libraryBuilder.currentTypeParameterScopeBuilder.name,
+ compilationUnit.currentTypeParameterScopeBuilder.name,
constructorNameOffset),
typeArguments,
suffix?.name,
@@ -3723,7 +3725,7 @@
// For entries that consist of their name only, all of the elements
// of the constructor reference should be null.
if (typeArguments != null || suffix != null) {
- libraryBuilder.reportFeatureNotEnabled(
+ compilationUnit.reportFeatureNotEnabled(
libraryFeatures.enhancedEnums, uri, charOffset, noLength);
}
push(NullValues.ConstructorReference);
@@ -3763,7 +3765,7 @@
pushDeclarationContext(declarationContext);
inConstructor = true;
- libraryBuilder.beginNestedDeclaration(
+ compilationUnit.beginNestedDeclaration(
TypeParameterScopeKind.factoryMethod, "#factory_method",
hasMembers: false);
push((externalToken != null ? externalMask : 0) |
@@ -3812,10 +3814,10 @@
if (name is! Identifier) {
assert(name is ParserRecovery,
"Unexpected name $name (${name.runtimeType}).");
- libraryBuilder.endNestedDeclaration(
+ compilationUnit.endNestedDeclaration(
TypeParameterScopeKind.factoryMethod, "<syntax-error>");
} else {
- libraryBuilder.addFactoryMethod(
+ compilationUnit.addFactoryMethod(
_offsetMap,
metadata,
modifiers,
@@ -3999,7 +4001,7 @@
if (supertype is ParserRecovery || mixins is ParserRecovery) {
push(new ParserRecovery(withKeyword.charOffset));
} else {
- push(libraryBuilder.addMixinApplication(
+ push(compilationUnit.addMixinApplication(
mixins as List<TypeBuilder>, withKeyword.charOffset));
}
assert(checkState(withKeyword, [
@@ -4053,7 +4055,7 @@
if (mixins is ParserRecovery) {
push(new ParserRecovery(withKeyword.charOffset));
} else {
- push(libraryBuilder.addMixinApplication(
+ push(compilationUnit.addMixinApplication(
mixins as List<TypeBuilder>, withKeyword.charOffset));
}
assert(checkState(withKeyword, [
@@ -4113,7 +4115,7 @@
@override
void addProblem(Message message, int charOffset, int length,
{bool wasHandled = false, List<LocatedMessage>? context}) {
- libraryBuilder.addProblem(message, charOffset, length, uri,
+ compilationUnit.addProblem(message, charOffset, length, uri,
wasHandled: wasHandled, context: context);
}
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 627df40..df7d169 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -124,13 +124,96 @@
LibraryBuilder? _libraryBuilder;
+ /// Map used to find objects created in the [OutlineBuilder] from within
+ /// the [DietListener].
+ ///
+ /// This is meant to be written once and read once.
+ OffsetMap? _offsetMap;
+
SourceCompilationUnitImpl(this._sourceLibraryBuilder);
@override
SourceLibraryBuilder get sourceLibraryBuilder => _sourceLibraryBuilder;
@override
- OffsetMap get offsetMap => _sourceLibraryBuilder.offsetMap;
+ LibraryFeatures get libraryFeatures => _sourceLibraryBuilder.libraryFeatures;
+
+ /// Returns the map of objects created in the [OutlineBuilder].
+ ///
+ /// This should only be called once.
+ @override
+ OffsetMap get offsetMap {
+ assert(_offsetMap != null, "No OffsetMap for $this");
+ OffsetMap map = _offsetMap!;
+ _offsetMap = null;
+ return map;
+ }
+
+ /// Registers the map of objects created in the [OutlineBuilder].
+ ///
+ /// This should only be called once.
+ @override
+ void set offsetMap(OffsetMap value) {
+ assert(_offsetMap == null, "OffsetMap has already been set for $this");
+ _offsetMap = value;
+ }
+
+ @override
+ TypeParameterScopeBuilder get currentTypeParameterScopeBuilder =>
+ _sourceLibraryBuilder.currentTypeParameterScopeBuilder;
+
+ @override
+ void beginNestedDeclaration(TypeParameterScopeKind kind, String name,
+ {bool hasMembers = true}) {
+ _sourceLibraryBuilder.currentTypeParameterScopeBuilder =
+ currentTypeParameterScopeBuilder.createNested(kind, name, hasMembers);
+ }
+
+ @override
+ TypeParameterScopeBuilder endNestedDeclaration(
+ TypeParameterScopeKind kind, String? name) {
+ assert(
+ currentTypeParameterScopeBuilder.kind == kind,
+ "Unexpected declaration. "
+ "Trying to end a ${currentTypeParameterScopeBuilder.kind} as a $kind.");
+ assert(
+ (name?.startsWith(currentTypeParameterScopeBuilder.name) ??
+ (name == currentTypeParameterScopeBuilder.name)) ||
+ currentTypeParameterScopeBuilder.name == "operator" ||
+ (name == null &&
+ currentTypeParameterScopeBuilder.name ==
+ UnnamedExtensionName.unnamedExtensionSentinel) ||
+ identical(name, "<syntax-error>"),
+ "${name} != ${currentTypeParameterScopeBuilder.name}");
+ TypeParameterScopeBuilder previous = currentTypeParameterScopeBuilder;
+ _sourceLibraryBuilder.currentTypeParameterScopeBuilder =
+ currentTypeParameterScopeBuilder.parent!;
+ return previous;
+ }
+
+ IndexedLibrary? get indexedLibrary => _sourceLibraryBuilder.indexedLibrary;
+
+ // TODO(johnniwinther): Use [_indexedContainer] for library members and make
+ // it [null] when there is null corresponding [IndexedContainer].
+ IndexedContainer? _indexedContainer;
+
+ @override
+ void beginIndexedContainer(String name,
+ {required bool isExtensionTypeDeclaration}) {
+ if (_sourceLibraryBuilder.indexedLibrary != null) {
+ if (isExtensionTypeDeclaration) {
+ _indexedContainer =
+ indexedLibrary!.lookupIndexedExtensionTypeDeclaration(name);
+ } else {
+ _indexedContainer = indexedLibrary!.lookupIndexedClass(name);
+ }
+ }
+ }
+
+ @override
+ void endIndexedContainer() {
+ _indexedContainer = null;
+ }
@override
LibraryBuilder get libraryBuilder {
@@ -274,6 +357,2002 @@
_libraryBuilder = library ?? _sourceLibraryBuilder;
_sourceLibraryBuilder.validatePart(library, usedParts);
}
+
+ @override
+ void addPart(OffsetMap offsetMap, Token partKeyword,
+ List<MetadataBuilder>? metadata, String uri, int charOffset) {
+ Uri resolvedUri = _sourceLibraryBuilder
+ .resolve(this.importUri, uri, charOffset, isPart: true);
+ // To support absolute paths from within packages in the part uri, we try to
+ // translate the file uri from the resolved import uri before resolving
+ // through the file uri of this library. See issue #52964.
+ Uri newFileUri = loader.target.uriTranslator.translate(resolvedUri) ??
+ _sourceLibraryBuilder.resolve(fileUri, uri, charOffset);
+ // TODO(johnniwinther): Add a LibraryPartBuilder instead of using
+ // [LibraryBuilder] to represent both libraries and parts.
+ CompilationUnit compilationUnit = loader.read(resolvedUri, charOffset,
+ origin: isAugmenting ? _sourceLibraryBuilder.origin : null,
+ fileUri: newFileUri,
+ accessor: this,
+ isPatch: isAugmenting);
+ _sourceLibraryBuilder.parts.add(new Part(charOffset, compilationUnit));
+
+ // TODO(ahe): [metadata] should be stored, evaluated, and added to [part].
+ LibraryPart part = new LibraryPart(<Expression>[], uri)
+ ..fileOffset = charOffset;
+ library.addPart(part);
+ offsetMap.registerPart(partKeyword, part);
+ }
+
+ @override
+ void addPartOf(List<MetadataBuilder>? metadata, String? name, String? uri,
+ int uriOffset) {
+ _sourceLibraryBuilder.partOfName = name;
+ if (uri != null) {
+ Uri resolvedUri = _sourceLibraryBuilder.partOfUri =
+ _sourceLibraryBuilder.resolve(this.importUri, uri, uriOffset);
+ // To support absolute paths from within packages in the part of uri, we
+ // try to translate the file uri from the resolved import uri before
+ // resolving through the file uri of this library. See issue #52964.
+ Uri newFileUri = loader.target.uriTranslator.translate(resolvedUri) ??
+ _sourceLibraryBuilder.resolve(fileUri, uri, uriOffset);
+ loader.read(partOfUri!, uriOffset, fileUri: newFileUri, accessor: this);
+ }
+ if (_scriptTokenOffset != null) {
+ addProblem(
+ messageScriptTagInPartFile, _scriptTokenOffset!, noLength, fileUri);
+ }
+ }
+
+ /// Offset of the first script tag (`#!...`) in this library or part.
+ int? _scriptTokenOffset;
+
+ @override
+ void addScriptToken(int charOffset) {
+ _scriptTokenOffset ??= charOffset;
+ }
+
+ @override
+ void addImport(
+ {OffsetMap? offsetMap,
+ Token? importKeyword,
+ required List<MetadataBuilder>? metadata,
+ required bool isAugmentationImport,
+ required String uri,
+ required List<Configuration>? configurations,
+ required String? prefix,
+ required List<CombinatorBuilder>? combinators,
+ required bool deferred,
+ required int charOffset,
+ required int prefixCharOffset,
+ required int uriOffset,
+ required int importIndex}) {
+ if (configurations != null) {
+ for (Configuration config in configurations) {
+ if (loader.getLibrarySupportValue(config.dottedName) ==
+ config.condition) {
+ uri = config.importUri;
+ break;
+ }
+ }
+ }
+
+ CompilationUnit? compilationUnit = null;
+ Uri? resolvedUri;
+ String? nativePath;
+ const String nativeExtensionScheme = "dart-ext:";
+ if (uri.startsWith(nativeExtensionScheme)) {
+ addProblem(messageUnsupportedDartExt, charOffset, noLength, fileUri);
+ String strippedUri = uri.substring(nativeExtensionScheme.length);
+ if (strippedUri.startsWith("package")) {
+ resolvedUri = _sourceLibraryBuilder.resolve(this.importUri, strippedUri,
+ uriOffset + nativeExtensionScheme.length);
+ resolvedUri = loader.target.translateUri(resolvedUri);
+ nativePath = resolvedUri.toString();
+ } else {
+ resolvedUri = new Uri(scheme: "dart-ext", pathSegments: [uri]);
+ nativePath = uri;
+ }
+ } else {
+ resolvedUri =
+ _sourceLibraryBuilder.resolve(this.importUri, uri, uriOffset);
+ compilationUnit = loader.read(resolvedUri, uriOffset,
+ origin: isAugmentationImport ? _sourceLibraryBuilder : null,
+ accessor: this,
+ isAugmentation: isAugmentationImport,
+ referencesFromIndex: isAugmentationImport ? indexedLibrary : null);
+ }
+
+ Import import = new Import(
+ _sourceLibraryBuilder,
+ compilationUnit,
+ isAugmentationImport,
+ deferred,
+ prefix,
+ combinators,
+ configurations,
+ charOffset,
+ prefixCharOffset,
+ importIndex,
+ nativeImportPath: nativePath);
+ _sourceLibraryBuilder.imports.add(import);
+ offsetMap?.registerImport(importKeyword!, import);
+ }
+
+ @override
+ void addExport(
+ OffsetMap offsetMap,
+ Token exportKeyword,
+ List<MetadataBuilder>? metadata,
+ String uri,
+ List<Configuration>? configurations,
+ List<CombinatorBuilder>? combinators,
+ int charOffset,
+ int uriOffset) {
+ if (configurations != null) {
+ for (Configuration config in configurations) {
+ if (loader.getLibrarySupportValue(config.dottedName) ==
+ config.condition) {
+ uri = config.importUri;
+ break;
+ }
+ }
+ }
+
+ CompilationUnit exportedLibrary = loader.read(
+ _sourceLibraryBuilder.resolve(this.importUri, uri, uriOffset),
+ charOffset,
+ accessor: this);
+ exportedLibrary.addExporter(_sourceLibraryBuilder, combinators, charOffset);
+ Export export = new Export(
+ _sourceLibraryBuilder, exportedLibrary, combinators, charOffset);
+ _sourceLibraryBuilder.exports.add(export);
+ offsetMap.registerExport(exportKeyword, export);
+ }
+
+ @override
+ void addClass(
+ OffsetMap offsetMap,
+ List<MetadataBuilder>? metadata,
+ int modifiers,
+ Identifier identifier,
+ List<NominalVariableBuilder>? typeVariables,
+ TypeBuilder? supertype,
+ MixinApplicationBuilder? mixins,
+ List<TypeBuilder>? interfaces,
+ int startOffset,
+ int nameOffset,
+ int endOffset,
+ int supertypeOffset,
+ {required bool isMacro,
+ required bool isSealed,
+ required bool isBase,
+ required bool isInterface,
+ required bool isFinal,
+ required bool isAugmentation,
+ required bool isMixinClass}) {
+ _addClass(
+ offsetMap,
+ TypeParameterScopeKind.classDeclaration,
+ metadata,
+ modifiers,
+ identifier,
+ typeVariables,
+ supertype,
+ mixins,
+ interfaces,
+ startOffset,
+ nameOffset,
+ endOffset,
+ supertypeOffset,
+ isMacro: isMacro,
+ isSealed: isSealed,
+ isBase: isBase,
+ isInterface: isInterface,
+ isFinal: isFinal,
+ isAugmentation: isAugmentation,
+ isMixinClass: isMixinClass);
+ }
+
+ @override
+ void addEnum(
+ OffsetMap offsetMap,
+ List<MetadataBuilder>? metadata,
+ Identifier identifier,
+ List<NominalVariableBuilder>? typeVariables,
+ MixinApplicationBuilder? supertypeBuilder,
+ List<TypeBuilder>? interfaceBuilders,
+ List<EnumConstantInfo?>? enumConstantInfos,
+ int startCharOffset,
+ int charEndOffset) {
+ String name = identifier.name;
+ int charOffset = identifier.nameOffset;
+
+ IndexedClass? referencesFromIndexedClass;
+ if (indexedLibrary != null) {
+ referencesFromIndexedClass = indexedLibrary!.lookupIndexedClass(name);
+ }
+ // Nested declaration began in `OutlineBuilder.beginEnum`.
+ TypeParameterScopeBuilder declaration =
+ endNestedDeclaration(TypeParameterScopeKind.enumDeclaration, name)
+ ..resolveNamedTypes(typeVariables, _sourceLibraryBuilder);
+ Map<String, Builder> members = declaration.members!;
+ Map<String, MemberBuilder> constructors = declaration.constructors!;
+ Map<String, MemberBuilder> setters = declaration.setters!;
+
+ SourceEnumBuilder enumBuilder = new SourceEnumBuilder(
+ metadata,
+ name,
+ typeVariables,
+ _applyMixins(
+ loader.target.underscoreEnumType,
+ supertypeBuilder,
+ startCharOffset,
+ charOffset,
+ charEndOffset,
+ name,
+ /* isMixinDeclaration = */
+ false,
+ typeVariables: typeVariables,
+ isMacro: false,
+ isSealed: false,
+ isBase: false,
+ isInterface: false,
+ isFinal: false,
+ isAugmentation: false,
+ isMixinClass: false),
+ interfaceBuilders,
+ enumConstantInfos,
+ _sourceLibraryBuilder,
+ new List<ConstructorReferenceBuilder>.of(constructorReferences),
+ startCharOffset,
+ charOffset,
+ charEndOffset,
+ referencesFromIndexedClass,
+ new Scope(
+ kind: ScopeKind.declaration,
+ local: members,
+ setters: setters,
+ parent: scope.withTypeVariables(typeVariables),
+ debugName: "enum $name",
+ isModifiable: false),
+ new ConstructorScope(name, constructors),
+ loader.coreLibrary);
+ constructorReferences.clear();
+
+ Map<String, NominalVariableBuilder>? typeVariablesByName =
+ _checkTypeVariables(typeVariables, enumBuilder);
+
+ void setParent(MemberBuilder? member) {
+ while (member != null) {
+ member.parent = enumBuilder;
+ member = member.next as MemberBuilder?;
+ }
+ }
+
+ void setParentAndCheckConflicts(String name, Builder member) {
+ if (typeVariablesByName != null) {
+ NominalVariableBuilder? tv = typeVariablesByName[name];
+ if (tv != null) {
+ enumBuilder.addProblem(
+ templateConflictsWithTypeVariable.withArguments(name),
+ member.charOffset,
+ name.length,
+ context: [
+ messageConflictsWithTypeVariableCause.withLocation(
+ tv.fileUri!, tv.charOffset, name.length)
+ ]);
+ }
+ }
+ setParent(member as MemberBuilder);
+ }
+
+ members.forEach(setParentAndCheckConflicts);
+ constructors.forEach(setParentAndCheckConflicts);
+ setters.forEach(setParentAndCheckConflicts);
+ _sourceLibraryBuilder.addBuilder(name, enumBuilder, charOffset,
+ getterReference: referencesFromIndexedClass?.cls.reference);
+
+ offsetMap.registerNamedDeclaration(identifier, enumBuilder);
+ }
+
+ @override
+ void addMixinDeclaration(
+ OffsetMap offsetMap,
+ List<MetadataBuilder>? metadata,
+ int modifiers,
+ Identifier identifier,
+ List<NominalVariableBuilder>? typeVariables,
+ List<TypeBuilder>? supertypeConstraints,
+ List<TypeBuilder>? interfaces,
+ int startOffset,
+ int nameOffset,
+ int endOffset,
+ int supertypeOffset,
+ {required bool isBase,
+ required bool isAugmentation}) {
+ TypeBuilder? supertype;
+ MixinApplicationBuilder? mixinApplication;
+ if (supertypeConstraints != null && supertypeConstraints.isNotEmpty) {
+ supertype = supertypeConstraints.first;
+ if (supertypeConstraints.length > 1) {
+ mixinApplication = new MixinApplicationBuilder(
+ supertypeConstraints.skip(1).toList(),
+ supertype.fileUri!,
+ supertype.charOffset!);
+ }
+ }
+ _addClass(
+ offsetMap,
+ TypeParameterScopeKind.mixinDeclaration,
+ metadata,
+ modifiers,
+ identifier,
+ typeVariables,
+ supertype,
+ mixinApplication,
+ interfaces,
+ startOffset,
+ nameOffset,
+ endOffset,
+ supertypeOffset,
+ isMacro: false,
+ isSealed: false,
+ isBase: isBase,
+ isInterface: false,
+ isFinal: false,
+ isAugmentation: isAugmentation,
+ isMixinClass: false);
+ }
+
+ void _addClass(
+ OffsetMap offsetMap,
+ TypeParameterScopeKind kind,
+ List<MetadataBuilder>? metadata,
+ int modifiers,
+ Identifier identifier,
+ List<NominalVariableBuilder>? typeVariables,
+ TypeBuilder? supertype,
+ MixinApplicationBuilder? mixins,
+ List<TypeBuilder>? interfaces,
+ int startOffset,
+ int nameOffset,
+ int endOffset,
+ int supertypeOffset,
+ {required bool isMacro,
+ required bool isSealed,
+ required bool isBase,
+ required bool isInterface,
+ required bool isFinal,
+ required bool isAugmentation,
+ required bool isMixinClass}) {
+ String className = identifier.name;
+ // Nested declaration began in `OutlineBuilder.beginClassDeclaration`.
+ TypeParameterScopeBuilder declaration =
+ endNestedDeclaration(kind, className)
+ ..resolveNamedTypes(typeVariables, _sourceLibraryBuilder);
+ assert(declaration.parent ==
+ _sourceLibraryBuilder._libraryTypeParameterScopeBuilder);
+ Map<String, Builder> members = declaration.members!;
+ Map<String, MemberBuilder> constructors = declaration.constructors!;
+ Map<String, MemberBuilder> setters = declaration.setters!;
+
+ Scope classScope = new Scope(
+ kind: ScopeKind.declaration,
+ local: members,
+ setters: setters,
+ parent: scope.withTypeVariables(typeVariables),
+ debugName: "class $className",
+ isModifiable: false);
+
+ // When looking up a constructor, we don't consider type variables or the
+ // library scope.
+ ConstructorScope constructorScope =
+ new ConstructorScope(className, constructors);
+ bool isMixinDeclaration = false;
+ if (modifiers & mixinDeclarationMask != 0) {
+ isMixinDeclaration = true;
+ modifiers = (modifiers & ~mixinDeclarationMask) | abstractMask;
+ }
+ if (declaration.declaresConstConstructor) {
+ modifiers |= declaresConstConstructorMask;
+ }
+ SourceClassBuilder classBuilder = new SourceClassBuilder(
+ metadata,
+ modifiers,
+ className,
+ typeVariables,
+ _applyMixins(supertype, mixins, startOffset, nameOffset, endOffset,
+ className, isMixinDeclaration,
+ typeVariables: typeVariables,
+ isMacro: false,
+ isSealed: false,
+ isBase: false,
+ isInterface: false,
+ isFinal: false,
+ // TODO(johnniwinther): How can we support class with mixins?
+ isAugmentation: false,
+ isMixinClass: false),
+ interfaces,
+ // TODO(johnniwinther): Add the `on` clause types of a mixin declaration
+ // here.
+ null,
+ classScope,
+ constructorScope,
+ _sourceLibraryBuilder,
+ new List<ConstructorReferenceBuilder>.of(constructorReferences),
+ startOffset,
+ nameOffset,
+ endOffset,
+ _indexedContainer,
+ isMixinDeclaration: isMixinDeclaration,
+ isMacro: isMacro,
+ isSealed: isSealed,
+ isBase: isBase,
+ isInterface: isInterface,
+ isFinal: isFinal,
+ isAugmentation: isAugmentation,
+ isMixinClass: isMixinClass);
+
+ constructorReferences.clear();
+ Map<String, NominalVariableBuilder>? typeVariablesByName =
+ _checkTypeVariables(typeVariables, classBuilder);
+ void setParent(MemberBuilder? member) {
+ while (member != null) {
+ member.parent = classBuilder;
+ member = member.next as MemberBuilder?;
+ }
+ }
+
+ void setParentAndCheckConflicts(String name, Builder member) {
+ if (typeVariablesByName != null) {
+ NominalVariableBuilder? tv = typeVariablesByName[name];
+ if (tv != null) {
+ classBuilder.addProblem(
+ templateConflictsWithTypeVariable.withArguments(name),
+ member.charOffset,
+ name.length,
+ context: [
+ messageConflictsWithTypeVariableCause.withLocation(
+ tv.fileUri!, tv.charOffset, name.length)
+ ]);
+ }
+ }
+ setParent(member as MemberBuilder);
+ }
+
+ members.forEach(setParentAndCheckConflicts);
+ constructors.forEach(setParentAndCheckConflicts);
+ setters.forEach(setParentAndCheckConflicts);
+ _sourceLibraryBuilder.addBuilder(className, classBuilder, nameOffset,
+ getterReference: _indexedContainer?.reference);
+ offsetMap.registerNamedDeclaration(identifier, classBuilder);
+ }
+
+ @override
+ MixinApplicationBuilder addMixinApplication(
+ List<TypeBuilder> mixins, int charOffset) {
+ return new MixinApplicationBuilder(mixins, fileUri, charOffset);
+ }
+
+ @override
+ void addNamedMixinApplication(
+ List<MetadataBuilder>? metadata,
+ String name,
+ List<NominalVariableBuilder>? typeVariables,
+ int modifiers,
+ TypeBuilder? supertype,
+ MixinApplicationBuilder mixinApplication,
+ List<TypeBuilder>? interfaces,
+ int startCharOffset,
+ int charOffset,
+ int charEndOffset,
+ {required bool isMacro,
+ required bool isSealed,
+ required bool isBase,
+ required bool isInterface,
+ required bool isFinal,
+ required bool isAugmentation,
+ required bool isMixinClass}) {
+ // Nested declaration began in `OutlineBuilder.beginNamedMixinApplication`.
+ endNestedDeclaration(TypeParameterScopeKind.namedMixinApplication, name)
+ .resolveNamedTypes(typeVariables, _sourceLibraryBuilder);
+ supertype = _applyMixins(supertype, mixinApplication, startCharOffset,
+ charOffset, charEndOffset, name, false,
+ metadata: metadata,
+ name: name,
+ typeVariables: typeVariables,
+ modifiers: modifiers,
+ interfaces: interfaces,
+ isMacro: isMacro,
+ isSealed: isSealed,
+ isBase: isBase,
+ isInterface: isInterface,
+ isFinal: isFinal,
+ isAugmentation: isAugmentation,
+ isMixinClass: isMixinClass)!;
+ _checkTypeVariables(typeVariables, supertype.declaration);
+ }
+
+ TypeBuilder? _applyMixins(
+ TypeBuilder? supertype,
+ MixinApplicationBuilder? mixinApplications,
+ int startCharOffset,
+ int charOffset,
+ int charEndOffset,
+ String subclassName,
+ bool isMixinDeclaration,
+ {List<MetadataBuilder>? metadata,
+ String? name,
+ List<NominalVariableBuilder>? typeVariables,
+ int modifiers = 0,
+ List<TypeBuilder>? interfaces,
+ required bool isMacro,
+ required bool isSealed,
+ required bool isBase,
+ required bool isInterface,
+ required bool isFinal,
+ required bool isAugmentation,
+ required bool isMixinClass}) {
+ if (name == null) {
+ // The following parameters should only be used when building a named
+ // mixin application.
+ if (metadata != null) {
+ unhandled("metadata", "unnamed mixin application", charOffset, fileUri);
+ } else if (interfaces != null) {
+ unhandled(
+ "interfaces", "unnamed mixin application", charOffset, fileUri);
+ }
+ }
+ if (mixinApplications != null) {
+ // Documentation below assumes the given mixin application is in one of
+ // these forms:
+ //
+ // class C extends S with M1, M2, M3;
+ // class Named = S with M1, M2, M3;
+ //
+ // When we refer to the subclass, we mean `C` or `Named`.
+
+ /// The current supertype.
+ ///
+ /// Starts out having the value `S` and on each iteration of the loop
+ /// below, it will take on the value corresponding to:
+ ///
+ /// 1. `S with M1`.
+ /// 2. `(S with M1) with M2`.
+ /// 3. `((S with M1) with M2) with M3`.
+ supertype ??= loader.target.objectType;
+
+ /// The variable part of the mixin application's synthetic name. It
+ /// starts out as the name of the superclass, but is only used after it
+ /// has been combined with the name of the current mixin. In the examples
+ /// from above, it will take these values:
+ ///
+ /// 1. `S&M1`
+ /// 2. `S&M1&M2`
+ /// 3. `S&M1&M2&M3`.
+ ///
+ /// The full name of the mixin application is obtained by prepending the
+ /// name of the subclass (`C` or `Named` in the above examples) to the
+ /// running name. For the example `C`, that leads to these full names:
+ ///
+ /// 1. `_C&S&M1`
+ /// 2. `_C&S&M1&M2`
+ /// 3. `_C&S&M1&M2&M3`.
+ ///
+ /// For a named mixin application, the last name has been given by the
+ /// programmer, so for the example `Named` we see these full names:
+ ///
+ /// 1. `_Named&S&M1`
+ /// 2. `_Named&S&M1&M2`
+ /// 3. `Named`.
+ String runningName;
+ if (supertype.typeName == null) {
+ assert(supertype is FunctionTypeBuilder);
+
+ // Function types don't have names, and we can supply any string that
+ // doesn't have to be unique. The actual supertype of the mixin will
+ // not be built in that case.
+ runningName = "";
+ } else {
+ runningName = supertype.typeName!.name;
+ }
+
+ /// True when we're building a named mixin application. Notice that for
+ /// the `Named` example above, this is only true on the last
+ /// iteration because only the full mixin application is named.
+ bool isNamedMixinApplication;
+
+ /// The names of the type variables of the subclass.
+ Set<String>? typeVariableNames;
+ if (typeVariables != null) {
+ typeVariableNames = new Set<String>();
+ for (NominalVariableBuilder typeVariable in typeVariables) {
+ typeVariableNames.add(typeVariable.name);
+ }
+ }
+
+ /// Helper function that returns `true` if a type variable with a name
+ /// from [typeVariableNames] is referenced in [type].
+ bool usesTypeVariables(TypeBuilder? type) {
+ switch (type) {
+ case NamedTypeBuilder(
+ :TypeDeclarationBuilder? declaration,
+ typeArguments: List<TypeBuilder>? arguments
+ ):
+ if (declaration is NominalVariableBuilder) {
+ return typeVariableNames!.contains(declaration.name);
+ }
+ if (declaration is StructuralVariableBuilder) {
+ return typeVariableNames!.contains(declaration.name);
+ }
+
+ if (arguments != null && typeVariables != null) {
+ for (TypeBuilder argument in arguments) {
+ if (usesTypeVariables(argument)) {
+ return true;
+ }
+ }
+ }
+ case FunctionTypeBuilder(
+ :List<ParameterBuilder>? formals,
+ :List<StructuralVariableBuilder>? typeVariables
+ ):
+ if (formals != null) {
+ for (ParameterBuilder formal in formals) {
+ if (usesTypeVariables(formal.type)) {
+ return true;
+ }
+ }
+ }
+ if (typeVariables != null) {
+ for (StructuralVariableBuilder variable in typeVariables) {
+ if (usesTypeVariables(variable.bound)) {
+ return true;
+ }
+ }
+ }
+ return usesTypeVariables(type.returnType);
+ case RecordTypeBuilder(
+ :List<RecordTypeFieldBuilder>? positionalFields,
+ :List<RecordTypeFieldBuilder>? namedFields
+ ):
+ if (positionalFields != null) {
+ for (RecordTypeFieldBuilder fieldBuilder in positionalFields) {
+ if (usesTypeVariables(fieldBuilder.type)) {
+ return true;
+ }
+ }
+ }
+ if (namedFields != null) {
+ for (RecordTypeFieldBuilder fieldBuilder in namedFields) {
+ if (usesTypeVariables(fieldBuilder.type)) {
+ return true;
+ }
+ }
+ }
+ case FixedTypeBuilder():
+ case InvalidTypeBuilder():
+ case OmittedTypeBuilder():
+ case null:
+ return false;
+ }
+ return false;
+ }
+
+ /// Iterate over the mixins from left to right. At the end of each
+ /// iteration, a new [supertype] is computed that is the mixin
+ /// application of [supertype] with the current mixin.
+ for (int i = 0; i < mixinApplications.mixins.length; i++) {
+ TypeBuilder mixin = mixinApplications.mixins[i];
+ isNamedMixinApplication =
+ name != null && mixin == mixinApplications.mixins.last;
+ bool isGeneric = false;
+ if (!isNamedMixinApplication) {
+ if (supertype is NamedTypeBuilder) {
+ isGeneric = isGeneric || usesTypeVariables(supertype);
+ }
+ if (mixin is NamedTypeBuilder) {
+ runningName += "&${mixin.typeName.name}";
+ isGeneric = isGeneric || usesTypeVariables(mixin);
+ }
+ }
+ String fullname =
+ isNamedMixinApplication ? name : "_$subclassName&$runningName";
+ List<NominalVariableBuilder>? applicationTypeVariables;
+ List<TypeBuilder>? applicationTypeArguments;
+ if (isNamedMixinApplication) {
+ // If this is a named mixin application, it must be given all the
+ // declared type variables.
+ applicationTypeVariables = typeVariables;
+ } else {
+ // Otherwise, we pass the fresh type variables to the mixin
+ // application in the same order as they're declared on the subclass.
+ if (isGeneric) {
+ this.beginNestedDeclaration(
+ TypeParameterScopeKind.unnamedMixinApplication,
+ "mixin application");
+
+ applicationTypeVariables = copyTypeVariables(
+ typeVariables!, currentTypeParameterScopeBuilder,
+ kind: TypeVariableKind.extensionSynthesized);
+
+ List<NamedTypeBuilder> newTypes = <NamedTypeBuilder>[];
+ if (supertype is NamedTypeBuilder &&
+ supertype.typeArguments != null) {
+ for (int i = 0; i < supertype.typeArguments!.length; ++i) {
+ supertype.typeArguments![i] = supertype.typeArguments![i].clone(
+ newTypes,
+ _sourceLibraryBuilder,
+ currentTypeParameterScopeBuilder);
+ }
+ }
+ if (mixin is NamedTypeBuilder && mixin.typeArguments != null) {
+ for (int i = 0; i < mixin.typeArguments!.length; ++i) {
+ mixin.typeArguments![i] = mixin.typeArguments![i].clone(
+ newTypes,
+ _sourceLibraryBuilder,
+ currentTypeParameterScopeBuilder);
+ }
+ }
+ for (NamedTypeBuilder newType in newTypes) {
+ currentTypeParameterScopeBuilder
+ .registerUnresolvedNamedType(newType);
+ }
+
+ TypeParameterScopeBuilder mixinDeclaration = this
+ .endNestedDeclaration(
+ TypeParameterScopeKind.unnamedMixinApplication,
+ "mixin application");
+ mixinDeclaration.resolveNamedTypes(
+ applicationTypeVariables, _sourceLibraryBuilder);
+
+ applicationTypeArguments = <TypeBuilder>[];
+ for (NominalVariableBuilder typeVariable in typeVariables) {
+ applicationTypeArguments.add(
+ new NamedTypeBuilderImpl.fromTypeDeclarationBuilder(
+ // The type variable types passed as arguments to the
+ // generic class representing the anonymous mixin
+ // application should refer back to the type variables of
+ // the class that extend the anonymous mixin application.
+ typeVariable,
+ const NullabilityBuilder.omitted(),
+ fileUri: fileUri,
+ charOffset: charOffset,
+ instanceTypeVariableAccess:
+ InstanceTypeVariableAccessState.Allowed));
+ }
+ }
+ }
+ final int computedStartCharOffset =
+ !isNamedMixinApplication || metadata == null
+ ? startCharOffset
+ : metadata.first.charOffset;
+
+ IndexedClass? referencesFromIndexedClass;
+ if (indexedLibrary != null) {
+ referencesFromIndexedClass =
+ indexedLibrary!.lookupIndexedClass(fullname);
+ }
+
+ SourceClassBuilder application = new SourceClassBuilder(
+ isNamedMixinApplication ? metadata : null,
+ isNamedMixinApplication
+ ? modifiers | namedMixinApplicationMask
+ : abstractMask,
+ fullname,
+ applicationTypeVariables,
+ isMixinDeclaration ? null : supertype,
+ isNamedMixinApplication
+ ? interfaces
+ : isMixinDeclaration
+ ? [supertype!, mixin]
+ : null,
+ null,
+ // No `on` clause types.
+ new Scope(
+ kind: ScopeKind.declaration,
+ local: <String, MemberBuilder>{},
+ setters: <String, MemberBuilder>{},
+ parent: scope.withTypeVariables(typeVariables),
+ debugName: "mixin $fullname ",
+ isModifiable: false),
+ new ConstructorScope(fullname, <String, MemberBuilder>{}),
+ _sourceLibraryBuilder,
+ <ConstructorReferenceBuilder>[],
+ computedStartCharOffset,
+ charOffset,
+ charEndOffset,
+ referencesFromIndexedClass,
+ mixedInTypeBuilder: isMixinDeclaration ? null : mixin,
+ isMacro: isNamedMixinApplication && isMacro,
+ isSealed: isNamedMixinApplication && isSealed,
+ isBase: isNamedMixinApplication && isBase,
+ isInterface: isNamedMixinApplication && isInterface,
+ isFinal: isNamedMixinApplication && isFinal,
+ isAugmentation: isNamedMixinApplication && isAugmentation,
+ isMixinClass: isNamedMixinApplication && isMixinClass);
+ // TODO(ahe, kmillikin): Should always be true?
+ // pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart can't
+ // handle that :(
+ application.cls.isAnonymousMixin = !isNamedMixinApplication;
+ _sourceLibraryBuilder.addBuilder(fullname, application, charOffset,
+ getterReference: referencesFromIndexedClass?.cls.reference);
+ supertype = new NamedTypeBuilderImpl.fromTypeDeclarationBuilder(
+ application, const NullabilityBuilder.omitted(),
+ arguments: applicationTypeArguments,
+ fileUri: fileUri,
+ charOffset: charOffset,
+ instanceTypeVariableAccess:
+ InstanceTypeVariableAccessState.Allowed);
+ _registerMixinApplication(application, mixin);
+ }
+ return supertype;
+ } else {
+ return supertype;
+ }
+ }
+
+ /// Registers that [mixinApplication] is a mixin application introduced by
+ /// the [mixedInType] in a with-clause.
+ ///
+ /// This is used to check that super access in mixin declarations have a
+ /// concrete target.
+ void _registerMixinApplication(
+ SourceClassBuilder mixinApplication, TypeBuilder mixedInType) {
+ assert(_sourceLibraryBuilder._mixinApplications != null,
+ "Late registration of mixin application.");
+ _sourceLibraryBuilder._mixinApplications![mixinApplication] = mixedInType;
+ }
+
+ @override
+ void addExtensionDeclaration(
+ OffsetMap offsetMap,
+ Token beginToken,
+ List<MetadataBuilder>? metadata,
+ int modifiers,
+ Identifier? identifier,
+ List<NominalVariableBuilder>? typeVariables,
+ TypeBuilder type,
+ int startOffset,
+ int nameOffset,
+ int endOffset) {
+ String? name = identifier?.name;
+ // Nested declaration began in
+ // `OutlineBuilder.beginExtensionDeclarationPrelude`.
+ TypeParameterScopeBuilder declaration =
+ endNestedDeclaration(TypeParameterScopeKind.extensionDeclaration, name)
+ ..resolveNamedTypes(typeVariables, _sourceLibraryBuilder);
+ assert(declaration.parent ==
+ _sourceLibraryBuilder._libraryTypeParameterScopeBuilder);
+ Map<String, Builder> members = declaration.members!;
+ Map<String, MemberBuilder> constructors = declaration.constructors!;
+ Map<String, MemberBuilder> setters = declaration.setters!;
+
+ Scope classScope = new Scope(
+ kind: ScopeKind.declaration,
+ local: members,
+ setters: setters,
+ parent: scope.withTypeVariables(typeVariables),
+ debugName: "extension $name",
+ isModifiable: false);
+
+ Extension? referenceFrom;
+ ExtensionName extensionName = declaration.extensionName!;
+ if (name != null) {
+ referenceFrom = indexedLibrary?.lookupExtension(name);
+ }
+
+ ExtensionBuilder extensionBuilder = new SourceExtensionBuilder(
+ metadata,
+ modifiers,
+ extensionName,
+ typeVariables,
+ type,
+ classScope,
+ _sourceLibraryBuilder,
+ startOffset,
+ nameOffset,
+ endOffset,
+ referenceFrom);
+ constructorReferences.clear();
+ Map<String, NominalVariableBuilder>? typeVariablesByName =
+ _checkTypeVariables(typeVariables, extensionBuilder);
+ void setParent(MemberBuilder? member) {
+ while (member != null) {
+ member.parent = extensionBuilder;
+ member = member.next as MemberBuilder?;
+ }
+ }
+
+ void setParentAndCheckConflicts(String name, Builder member) {
+ if (typeVariablesByName != null) {
+ NominalVariableBuilder? tv = typeVariablesByName[name];
+ if (tv != null) {
+ extensionBuilder.addProblem(
+ templateConflictsWithTypeVariable.withArguments(name),
+ member.charOffset,
+ name.length,
+ context: [
+ messageConflictsWithTypeVariableCause.withLocation(
+ tv.fileUri!, tv.charOffset, name.length)
+ ]);
+ }
+ }
+ setParent(member as MemberBuilder);
+ }
+
+ members.forEach(setParentAndCheckConflicts);
+ constructors.forEach(setParentAndCheckConflicts);
+ setters.forEach(setParentAndCheckConflicts);
+ _sourceLibraryBuilder.addBuilder(
+ extensionBuilder.name, extensionBuilder, nameOffset,
+ getterReference: referenceFrom?.reference);
+ if (identifier != null) {
+ offsetMap.registerNamedDeclaration(identifier, extensionBuilder);
+ } else {
+ offsetMap.registerUnnamedDeclaration(beginToken, extensionBuilder);
+ }
+ }
+
+ @override
+ void addExtensionTypeDeclaration(
+ OffsetMap offsetMap,
+ List<MetadataBuilder>? metadata,
+ int modifiers,
+ Identifier identifier,
+ List<NominalVariableBuilder>? typeVariables,
+ List<TypeBuilder>? interfaces,
+ int startOffset,
+ int endOffset) {
+ String name = identifier.name;
+ // Nested declaration began in `OutlineBuilder.beginExtensionDeclaration`.
+ TypeParameterScopeBuilder declaration = endNestedDeclaration(
+ TypeParameterScopeKind.extensionTypeDeclaration, name)
+ ..resolveNamedTypes(typeVariables, _sourceLibraryBuilder);
+ assert(declaration.parent ==
+ _sourceLibraryBuilder._libraryTypeParameterScopeBuilder);
+ Map<String, Builder> members = declaration.members!;
+ Map<String, MemberBuilder> constructors = declaration.constructors!;
+ Map<String, MemberBuilder> setters = declaration.setters!;
+
+ Scope memberScope = new Scope(
+ kind: ScopeKind.declaration,
+ local: members,
+ setters: setters,
+ parent: scope.withTypeVariables(typeVariables),
+ debugName: "extension type $name",
+ isModifiable: false);
+ ConstructorScope constructorScope =
+ new ConstructorScope(name, constructors);
+
+ IndexedContainer? indexedContainer =
+ indexedLibrary?.lookupIndexedExtensionTypeDeclaration(name);
+
+ SourceFieldBuilder? representationFieldBuilder;
+ outer:
+ for (Builder? member in members.values) {
+ while (member != null) {
+ if (!member.isDuplicate &&
+ member is SourceFieldBuilder &&
+ !member.isStatic) {
+ representationFieldBuilder = member;
+ break outer;
+ }
+ member = member.next;
+ }
+ }
+
+ ExtensionTypeDeclarationBuilder extensionTypeDeclarationBuilder =
+ new SourceExtensionTypeDeclarationBuilder(
+ metadata,
+ modifiers,
+ declaration.name,
+ typeVariables,
+ interfaces,
+ memberScope,
+ constructorScope,
+ _sourceLibraryBuilder,
+ new List<ConstructorReferenceBuilder>.of(constructorReferences),
+ startOffset,
+ identifier.nameOffset,
+ endOffset,
+ indexedContainer,
+ representationFieldBuilder);
+ constructorReferences.clear();
+ Map<String, NominalVariableBuilder>? typeVariablesByName =
+ _checkTypeVariables(typeVariables, extensionTypeDeclarationBuilder);
+ void setParent(MemberBuilder? member) {
+ while (member != null) {
+ member.parent = extensionTypeDeclarationBuilder;
+ member = member.next as MemberBuilder?;
+ }
+ }
+
+ void setParentAndCheckConflicts(String name, Builder member) {
+ if (typeVariablesByName != null) {
+ NominalVariableBuilder? tv = typeVariablesByName[name];
+ if (tv != null) {
+ extensionTypeDeclarationBuilder.addProblem(
+ templateConflictsWithTypeVariable.withArguments(name),
+ member.charOffset,
+ name.length,
+ context: [
+ messageConflictsWithTypeVariableCause.withLocation(
+ tv.fileUri!, tv.charOffset, name.length)
+ ]);
+ }
+ }
+ setParent(member as MemberBuilder);
+ }
+
+ members.forEach(setParentAndCheckConflicts);
+ constructors.forEach(setParentAndCheckConflicts);
+ setters.forEach(setParentAndCheckConflicts);
+ _sourceLibraryBuilder.addBuilder(extensionTypeDeclarationBuilder.name,
+ extensionTypeDeclarationBuilder, identifier.nameOffset,
+ getterReference: indexedContainer?.reference);
+ offsetMap.registerNamedDeclaration(
+ identifier, extensionTypeDeclarationBuilder);
+ }
+
+ @override
+ void addFunctionTypeAlias(
+ List<MetadataBuilder>? metadata,
+ String name,
+ List<NominalVariableBuilder>? typeVariables,
+ TypeBuilder type,
+ int charOffset) {
+ if (typeVariables != null) {
+ for (NominalVariableBuilder typeVariable in typeVariables) {
+ typeVariable.varianceCalculationValue =
+ VarianceCalculationValue.pending;
+ }
+ }
+ Typedef? referenceFrom = indexedLibrary?.lookupTypedef(name);
+ TypeAliasBuilder typedefBuilder = new SourceTypeAliasBuilder(
+ metadata, name, typeVariables, type, _sourceLibraryBuilder, charOffset,
+ referenceFrom: referenceFrom);
+ _checkTypeVariables(typeVariables, typedefBuilder);
+ // Nested declaration began in `OutlineBuilder.beginFunctionTypeAlias`.
+ endNestedDeclaration(TypeParameterScopeKind.typedef, "#typedef")
+ .resolveNamedTypes(typeVariables, _sourceLibraryBuilder);
+ _sourceLibraryBuilder.addBuilder(name, typedefBuilder, charOffset,
+ getterReference: referenceFrom?.reference);
+ }
+
+ @override
+ void addConstructor(
+ OffsetMap offsetMap,
+ List<MetadataBuilder>? metadata,
+ int modifiers,
+ Identifier identifier,
+ String constructorName,
+ List<NominalVariableBuilder>? typeVariables,
+ List<FormalParameterBuilder>? formals,
+ int startCharOffset,
+ int charOffset,
+ int charOpenParenOffset,
+ int charEndOffset,
+ String? nativeMethodName,
+ {Token? beginInitializers,
+ required bool forAbstractClassOrMixin}) {
+ SourceFunctionBuilder builder = _addConstructor(
+ metadata,
+ modifiers,
+ constructorName,
+ typeVariables,
+ formals,
+ startCharOffset,
+ charOffset,
+ charOpenParenOffset,
+ charEndOffset,
+ nativeMethodName,
+ beginInitializers: beginInitializers,
+ forAbstractClassOrMixin: forAbstractClassOrMixin);
+ offsetMap.registerConstructor(identifier, builder);
+ }
+
+ @override
+ void addPrimaryConstructor(
+ {required OffsetMap offsetMap,
+ required Token beginToken,
+ required String constructorName,
+ required List<NominalVariableBuilder>? typeVariables,
+ required List<FormalParameterBuilder>? formals,
+ required int charOffset,
+ required bool isConst}) {
+ SourceFunctionBuilder builder = _addConstructor(
+ null,
+ isConst ? constMask : 0,
+ constructorName,
+ typeVariables,
+ formals,
+ /* startCharOffset = */ charOffset,
+ charOffset,
+ /* charOpenParenOffset = */ charOffset,
+ /* charEndOffset = */ charOffset,
+ /* nativeMethodName = */ null,
+ forAbstractClassOrMixin: false);
+ offsetMap.registerPrimaryConstructor(beginToken, builder);
+ }
+
+ @override
+ void addPrimaryConstructorField(
+ {required List<MetadataBuilder>? metadata,
+ required TypeBuilder type,
+ required String name,
+ required int charOffset}) {
+ _addField(
+ metadata,
+ finalMask,
+ /* isTopLevel = */ false,
+ type,
+ name,
+ /* charOffset = */ charOffset,
+ /* charEndOffset = */ charOffset,
+ /* initializerToken = */ null,
+ /* hasInitializer = */ false);
+ }
+
+ SourceFunctionBuilder _addConstructor(
+ List<MetadataBuilder>? metadata,
+ int modifiers,
+ String constructorName,
+ List<NominalVariableBuilder>? typeVariables,
+ List<FormalParameterBuilder>? formals,
+ int startCharOffset,
+ int charOffset,
+ int charOpenParenOffset,
+ int charEndOffset,
+ String? nativeMethodName,
+ {Token? beginInitializers,
+ required bool forAbstractClassOrMixin}) {
+ ContainerType containerType =
+ currentTypeParameterScopeBuilder.containerType;
+ ContainerName? containerName =
+ currentTypeParameterScopeBuilder.containerName;
+ NameScheme nameScheme = new NameScheme(
+ isInstanceMember: false,
+ containerName: containerName,
+ containerType: containerType,
+ libraryName: indexedLibrary != null
+ ? new LibraryName(indexedLibrary!.library.reference)
+ : libraryName);
+
+ Reference? constructorReference;
+ Reference? tearOffReference;
+
+ IndexedContainer? indexedContainer = _indexedContainer;
+ if (indexedContainer != null) {
+ constructorReference = indexedContainer.lookupConstructorReference(
+ nameScheme
+ .getConstructorMemberName(constructorName, isTearOff: false)
+ .name);
+ tearOffReference = indexedContainer.lookupGetterReference(nameScheme
+ .getConstructorMemberName(constructorName, isTearOff: true)
+ .name);
+ }
+ AbstractSourceConstructorBuilder constructorBuilder;
+
+ if (currentTypeParameterScopeBuilder.kind ==
+ TypeParameterScopeKind.extensionTypeDeclaration) {
+ constructorBuilder = new SourceExtensionTypeConstructorBuilder(
+ metadata,
+ modifiers & ~abstractMask,
+ addInferableType(),
+ constructorName,
+ typeVariables,
+ formals,
+ _sourceLibraryBuilder,
+ startCharOffset,
+ charOffset,
+ charOpenParenOffset,
+ charEndOffset,
+ constructorReference,
+ tearOffReference,
+ nameScheme,
+ nativeMethodName: nativeMethodName,
+ forAbstractClassOrEnumOrMixin: forAbstractClassOrMixin);
+ } else {
+ constructorBuilder = new DeclaredSourceConstructorBuilder(
+ metadata,
+ modifiers & ~abstractMask,
+ addInferableType(),
+ constructorName,
+ typeVariables,
+ formals,
+ _sourceLibraryBuilder,
+ startCharOffset,
+ charOffset,
+ charOpenParenOffset,
+ charEndOffset,
+ constructorReference,
+ tearOffReference,
+ nameScheme,
+ nativeMethodName: nativeMethodName,
+ forAbstractClassOrEnumOrMixin: forAbstractClassOrMixin);
+ }
+ _checkTypeVariables(typeVariables, constructorBuilder);
+ // TODO(johnniwinther): There is no way to pass the tear off reference here.
+ _sourceLibraryBuilder.addBuilder(
+ constructorName, constructorBuilder, charOffset,
+ getterReference: constructorReference);
+ if (nativeMethodName != null) {
+ _addNativeMethod(constructorBuilder);
+ }
+ if (constructorBuilder.isConst) {
+ currentTypeParameterScopeBuilder.declaresConstConstructor = true;
+ }
+ if (constructorBuilder.isConst ||
+ libraryFeatures.superParameters.isEnabled) {
+ // const constructors will have their initializers compiled and written
+ // into the outline. In case of super-parameters language feature, the
+ // super initializers are required to infer the types of super parameters.
+ constructorBuilder.beginInitializers =
+ beginInitializers ?? new Token.eof(-1);
+ }
+ return constructorBuilder;
+ }
+
+ @override
+ void addFactoryMethod(
+ OffsetMap offsetMap,
+ List<MetadataBuilder>? metadata,
+ int modifiers,
+ Identifier identifier,
+ List<FormalParameterBuilder>? formals,
+ ConstructorReferenceBuilder? redirectionTarget,
+ int startCharOffset,
+ int charOffset,
+ int charOpenParenOffset,
+ int charEndOffset,
+ String? nativeMethodName,
+ AsyncMarker asyncModifier) {
+ TypeBuilder returnType;
+ if (currentTypeParameterScopeBuilder.parent?.kind ==
+ TypeParameterScopeKind.extensionDeclaration) {
+ // Make the synthesized return type invalid for extensions.
+ String name = currentTypeParameterScopeBuilder.parent!.name;
+ returnType = new NamedTypeBuilderImpl.forInvalidType(
+ currentTypeParameterScopeBuilder.parent!.name,
+ const NullabilityBuilder.omitted(),
+ messageExtensionDeclaresConstructor.withLocation(
+ fileUri, charOffset, name.length));
+ } else {
+ returnType = addNamedType(
+ new SyntheticTypeName(
+ currentTypeParameterScopeBuilder.parent!.name, charOffset),
+ const NullabilityBuilder.omitted(),
+ <TypeBuilder>[],
+ charOffset,
+ instanceTypeVariableAccess: InstanceTypeVariableAccessState.Allowed);
+ }
+ // Nested declaration began in `OutlineBuilder.beginFactoryMethod`.
+ TypeParameterScopeBuilder factoryDeclaration = endNestedDeclaration(
+ TypeParameterScopeKind.factoryMethod, "#factory_method");
+
+ // Prepare the simple procedure name.
+ String procedureName;
+ String? constructorName =
+ computeAndValidateConstructorName(identifier, isFactory: true);
+ if (constructorName != null) {
+ procedureName = constructorName;
+ } else {
+ procedureName = identifier.name;
+ }
+
+ ContainerType containerType =
+ currentTypeParameterScopeBuilder.containerType;
+ ContainerName? containerName =
+ currentTypeParameterScopeBuilder.containerName;
+
+ NameScheme procedureNameScheme = new NameScheme(
+ containerName: containerName,
+ containerType: containerType,
+ isInstanceMember: false,
+ libraryName: indexedLibrary != null
+ ? new LibraryName(
+ (_indexedContainer ?? indexedLibrary)!.library.reference)
+ : libraryName);
+
+ Reference? constructorReference;
+ Reference? tearOffReference;
+ if (_indexedContainer != null) {
+ constructorReference = _indexedContainer!.lookupConstructorReference(
+ procedureNameScheme
+ .getConstructorMemberName(procedureName, isTearOff: false)
+ .name);
+ tearOffReference = _indexedContainer!.lookupGetterReference(
+ procedureNameScheme
+ .getConstructorMemberName(procedureName, isTearOff: true)
+ .name);
+ } else if (indexedLibrary != null) {
+ constructorReference = indexedLibrary!.lookupGetterReference(
+ procedureNameScheme
+ .getConstructorMemberName(procedureName, isTearOff: false)
+ .name);
+ tearOffReference = indexedLibrary!.lookupGetterReference(
+ procedureNameScheme
+ .getConstructorMemberName(procedureName, isTearOff: true)
+ .name);
+ }
+
+ SourceFactoryBuilder procedureBuilder;
+ List<NominalVariableBuilder> typeVariables;
+ if (redirectionTarget != null) {
+ procedureBuilder = new RedirectingFactoryBuilder(
+ metadata,
+ staticMask | modifiers,
+ returnType,
+ procedureName,
+ typeVariables = copyTypeVariables(
+ currentTypeParameterScopeBuilder.typeVariables ??
+ const <NominalVariableBuilder>[],
+ factoryDeclaration,
+ kind: TypeVariableKind.function),
+ formals,
+ _sourceLibraryBuilder,
+ startCharOffset,
+ charOffset,
+ charOpenParenOffset,
+ charEndOffset,
+ constructorReference,
+ tearOffReference,
+ procedureNameScheme,
+ nativeMethodName,
+ redirectionTarget);
+ } else {
+ procedureBuilder = new SourceFactoryBuilder(
+ metadata,
+ staticMask | modifiers,
+ returnType,
+ procedureName,
+ typeVariables = copyTypeVariables(
+ currentTypeParameterScopeBuilder.typeVariables ??
+ const <NominalVariableBuilder>[],
+ factoryDeclaration,
+ kind: TypeVariableKind.function),
+ formals,
+ _sourceLibraryBuilder,
+ startCharOffset,
+ charOffset,
+ charOpenParenOffset,
+ charEndOffset,
+ constructorReference,
+ tearOffReference,
+ asyncModifier,
+ procedureNameScheme,
+ nativeMethodName: nativeMethodName);
+ }
+
+ TypeParameterScopeBuilder savedDeclaration =
+ currentTypeParameterScopeBuilder;
+ _sourceLibraryBuilder.currentTypeParameterScopeBuilder = factoryDeclaration;
+ if (returnType is NamedTypeBuilderImpl && !typeVariables.isEmpty) {
+ returnType.typeArguments =
+ new List<TypeBuilder>.generate(typeVariables.length, (int index) {
+ return addNamedType(
+ new SyntheticTypeName(
+ typeVariables[index].name, procedureBuilder.charOffset),
+ const NullabilityBuilder.omitted(),
+ null,
+ procedureBuilder.charOffset,
+ instanceTypeVariableAccess:
+ InstanceTypeVariableAccessState.Allowed);
+ });
+ }
+ _sourceLibraryBuilder.currentTypeParameterScopeBuilder = savedDeclaration;
+
+ factoryDeclaration.resolveNamedTypes(
+ procedureBuilder.typeVariables, _sourceLibraryBuilder);
+ _sourceLibraryBuilder.addBuilder(
+ procedureName, procedureBuilder, charOffset,
+ getterReference: constructorReference);
+ if (nativeMethodName != null) {
+ _addNativeMethod(procedureBuilder);
+ }
+ offsetMap.registerConstructor(identifier, procedureBuilder);
+ }
+
+ void _addNativeMethod(SourceFunctionBuilder method) {
+ nativeMethods.add(method);
+ }
+
+ @override
+ String? computeAndValidateConstructorName(Identifier identifier,
+ {isFactory = false}) {
+ String className = currentTypeParameterScopeBuilder.name;
+ String prefix;
+ String? suffix;
+ int charOffset;
+ if (identifier is QualifiedName) {
+ Identifier qualifier = identifier.qualifier as Identifier;
+ prefix = qualifier.name;
+ suffix = identifier.name;
+ charOffset = qualifier.nameOffset;
+ } else {
+ prefix = identifier.name;
+ suffix = null;
+ charOffset = identifier.nameOffset;
+ }
+ if (libraryFeatures.constructorTearoffs.isEnabled) {
+ suffix = suffix == "new" ? "" : suffix;
+ }
+ if (prefix == className) {
+ return suffix ?? "";
+ }
+ if (suffix == null && !isFactory) {
+ // A legal name for a regular method, but not for a constructor.
+ return null;
+ }
+
+ addProblem(
+ messageConstructorWithWrongName, charOffset, prefix.length, fileUri,
+ context: [
+ templateConstructorWithWrongNameContext
+ .withArguments(currentTypeParameterScopeBuilder.name)
+ .withLocation(
+ importUri,
+ currentTypeParameterScopeBuilder.charOffset,
+ currentTypeParameterScopeBuilder.name.length)
+ ]);
+
+ return suffix;
+ }
+
+ @override
+ ConstructorReferenceBuilder addConstructorReference(TypeName name,
+ List<TypeBuilder>? typeArguments, String? suffix, int charOffset) {
+ ConstructorReferenceBuilder ref = new ConstructorReferenceBuilder(
+ name, typeArguments, suffix, fileUri, charOffset);
+ constructorReferences.add(ref);
+ return ref;
+ }
+
+ @override
+ void addProcedure(
+ OffsetMap offsetMap,
+ List<MetadataBuilder>? metadata,
+ int modifiers,
+ TypeBuilder? returnType,
+ Identifier identifier,
+ String name,
+ List<NominalVariableBuilder>? typeVariables,
+ List<FormalParameterBuilder>? formals,
+ ProcedureKind kind,
+ int startCharOffset,
+ int charOffset,
+ int charOpenParenOffset,
+ int charEndOffset,
+ String? nativeMethodName,
+ AsyncMarker asyncModifier,
+ {required bool isInstanceMember,
+ required bool isExtensionMember,
+ required bool isExtensionTypeMember}) {
+ assert(!isExtensionMember ||
+ currentTypeParameterScopeBuilder.kind ==
+ TypeParameterScopeKind.extensionDeclaration);
+ assert(!isExtensionTypeMember ||
+ currentTypeParameterScopeBuilder.kind ==
+ TypeParameterScopeKind.extensionTypeDeclaration);
+ ContainerType containerType =
+ currentTypeParameterScopeBuilder.containerType;
+ ContainerName? containerName =
+ currentTypeParameterScopeBuilder.containerName;
+ NameScheme nameScheme = new NameScheme(
+ containerName: containerName,
+ containerType: containerType,
+ isInstanceMember: isInstanceMember,
+ libraryName: indexedLibrary != null
+ ? new LibraryName(indexedLibrary!.library.reference)
+ : libraryName);
+
+ if (returnType == null) {
+ if (kind == ProcedureKind.Operator &&
+ identical(name, indexSetName.text)) {
+ returnType = addVoidType(charOffset);
+ } else if (kind == ProcedureKind.Setter) {
+ returnType = addVoidType(charOffset);
+ }
+ }
+ Reference? procedureReference;
+ Reference? tearOffReference;
+ IndexedContainer? indexedContainer =
+ _indexedContainer ?? _sourceLibraryBuilder.indexedLibrary;
+
+ bool isAugmentation = isAugmenting && (modifiers & augmentMask) != 0;
+ if (indexedContainer != null && !isAugmentation) {
+ Name nameToLookup = nameScheme.getProcedureMemberName(kind, name).name;
+ if (kind == ProcedureKind.Setter) {
+ if ((isExtensionMember || isExtensionTypeMember) && isInstanceMember) {
+ // Extension (type) instance setters are encoded as methods.
+ procedureReference =
+ indexedContainer.lookupGetterReference(nameToLookup);
+ } else {
+ procedureReference =
+ indexedContainer.lookupSetterReference(nameToLookup);
+ }
+ } else {
+ procedureReference =
+ indexedContainer.lookupGetterReference(nameToLookup);
+ if ((isExtensionMember || isExtensionTypeMember) &&
+ kind == ProcedureKind.Method) {
+ tearOffReference = indexedContainer.lookupGetterReference(nameScheme
+ .getProcedureMemberName(ProcedureKind.Getter, name)
+ .name);
+ }
+ }
+ }
+ SourceProcedureBuilder procedureBuilder = new SourceProcedureBuilder(
+ metadata,
+ modifiers,
+ returnType ?? addInferableType(),
+ name,
+ typeVariables,
+ formals,
+ kind,
+ _sourceLibraryBuilder,
+ startCharOffset,
+ charOffset,
+ charOpenParenOffset,
+ charEndOffset,
+ procedureReference,
+ tearOffReference,
+ asyncModifier,
+ nameScheme,
+ nativeMethodName: nativeMethodName);
+ _checkTypeVariables(typeVariables, procedureBuilder);
+ _sourceLibraryBuilder.addBuilder(name, procedureBuilder, charOffset,
+ getterReference: procedureReference);
+ if (nativeMethodName != null) {
+ _addNativeMethod(procedureBuilder);
+ }
+ offsetMap.registerProcedure(identifier, procedureBuilder);
+ }
+
+ @override
+ void addFields(
+ OffsetMap offsetMap,
+ List<MetadataBuilder>? metadata,
+ int modifiers,
+ bool isTopLevel,
+ TypeBuilder? type,
+ List<FieldInfo> fieldInfos) {
+ for (FieldInfo info in fieldInfos) {
+ bool isConst = modifiers & constMask != 0;
+ bool isFinal = modifiers & finalMask != 0;
+ bool potentiallyNeedInitializerInOutline = isConst || isFinal;
+ Token? startToken;
+ if (potentiallyNeedInitializerInOutline || type == null) {
+ startToken = info.initializerToken;
+ }
+ if (startToken != null) {
+ // Extract only the tokens for the initializer expression from the
+ // token stream.
+ Token endToken = info.beforeLast!;
+ endToken.setNext(new Token.eof(endToken.next!.offset));
+ new Token.eof(startToken.previous!.offset).setNext(startToken);
+ }
+ bool hasInitializer = info.initializerToken != null;
+ offsetMap.registerField(
+ info.identifier,
+ _addField(
+ metadata,
+ modifiers,
+ isTopLevel,
+ type ?? addInferableType(),
+ info.identifier.name,
+ info.identifier.nameOffset,
+ info.charEndOffset,
+ startToken,
+ hasInitializer,
+ constInitializerToken:
+ potentiallyNeedInitializerInOutline ? startToken : null));
+ }
+ }
+
+ SourceFieldBuilder _addField(
+ List<MetadataBuilder>? metadata,
+ int modifiers,
+ bool isTopLevel,
+ TypeBuilder type,
+ String name,
+ int charOffset,
+ int charEndOffset,
+ Token? initializerToken,
+ bool hasInitializer,
+ {Token? constInitializerToken}) {
+ if (hasInitializer) {
+ modifiers |= hasInitializerMask;
+ }
+ bool isLate = (modifiers & lateMask) != 0;
+ bool isFinal = (modifiers & finalMask) != 0;
+ bool isStatic = (modifiers & staticMask) != 0;
+ bool isExternal = (modifiers & externalMask) != 0;
+ final bool fieldIsLateWithLowering = isLate &&
+ (loader.target.backendTarget.isLateFieldLoweringEnabled(
+ hasInitializer: hasInitializer,
+ isFinal: isFinal,
+ isStatic: isTopLevel || isStatic) ||
+ (loader.target.backendTarget.useStaticFieldLowering &&
+ (isStatic || isTopLevel)));
+
+ final bool isInstanceMember = currentTypeParameterScopeBuilder.kind !=
+ TypeParameterScopeKind.library &&
+ (modifiers & staticMask) == 0;
+ final bool isExtensionMember = currentTypeParameterScopeBuilder.kind ==
+ TypeParameterScopeKind.extensionDeclaration;
+ final bool isExtensionTypeMember = currentTypeParameterScopeBuilder.kind ==
+ TypeParameterScopeKind.extensionTypeDeclaration;
+ ContainerType containerType =
+ currentTypeParameterScopeBuilder.containerType;
+ ContainerName? containerName =
+ currentTypeParameterScopeBuilder.containerName;
+
+ Reference? fieldReference;
+ Reference? fieldGetterReference;
+ Reference? fieldSetterReference;
+ Reference? lateIsSetFieldReference;
+ Reference? lateIsSetGetterReference;
+ Reference? lateIsSetSetterReference;
+ Reference? lateGetterReference;
+ Reference? lateSetterReference;
+
+ NameScheme nameScheme = new NameScheme(
+ isInstanceMember: isInstanceMember,
+ containerName: containerName,
+ containerType: containerType,
+ libraryName: _sourceLibraryBuilder.indexedLibrary != null
+ ? new LibraryName(_sourceLibraryBuilder.indexedLibrary!.reference)
+ : libraryName);
+ IndexedContainer? indexedContainer =
+ _indexedContainer ?? _sourceLibraryBuilder.indexedLibrary;
+ if (indexedContainer != null) {
+ if ((isExtensionMember || isExtensionTypeMember) &&
+ isInstanceMember &&
+ isExternal) {
+ /// An external extension (type) instance field is special. It is
+ /// treated as an external getter/setter pair and is therefore encoded
+ /// as a pair of top level methods using the extension instance member
+ /// naming convention.
+ fieldGetterReference = indexedContainer.lookupGetterReference(
+ nameScheme.getProcedureMemberName(ProcedureKind.Getter, name).name);
+ fieldSetterReference = indexedContainer.lookupGetterReference(
+ nameScheme.getProcedureMemberName(ProcedureKind.Setter, name).name);
+ } else if (isExtensionTypeMember && isInstanceMember) {
+ Name nameToLookup = nameScheme
+ .getFieldMemberName(FieldNameType.RepresentationField, name,
+ isSynthesized: true)
+ .name;
+ fieldGetterReference =
+ indexedContainer.lookupGetterReference(nameToLookup);
+ } else {
+ Name nameToLookup = nameScheme
+ .getFieldMemberName(FieldNameType.Field, name,
+ isSynthesized: fieldIsLateWithLowering)
+ .name;
+ fieldReference = indexedContainer.lookupFieldReference(nameToLookup);
+ fieldGetterReference =
+ indexedContainer.lookupGetterReference(nameToLookup);
+ fieldSetterReference =
+ indexedContainer.lookupSetterReference(nameToLookup);
+ }
+
+ if (fieldIsLateWithLowering) {
+ Name lateIsSetName = nameScheme
+ .getFieldMemberName(FieldNameType.IsSetField, name,
+ isSynthesized: fieldIsLateWithLowering)
+ .name;
+ lateIsSetFieldReference =
+ indexedContainer.lookupFieldReference(lateIsSetName);
+ lateIsSetGetterReference =
+ indexedContainer.lookupGetterReference(lateIsSetName);
+ lateIsSetSetterReference =
+ indexedContainer.lookupSetterReference(lateIsSetName);
+ lateGetterReference = indexedContainer.lookupGetterReference(nameScheme
+ .getFieldMemberName(FieldNameType.Getter, name,
+ isSynthesized: fieldIsLateWithLowering)
+ .name);
+ lateSetterReference = indexedContainer.lookupSetterReference(nameScheme
+ .getFieldMemberName(FieldNameType.Setter, name,
+ isSynthesized: fieldIsLateWithLowering)
+ .name);
+ }
+ }
+
+ SourceFieldBuilder fieldBuilder = new SourceFieldBuilder(
+ metadata,
+ type,
+ name,
+ modifiers,
+ isTopLevel,
+ _sourceLibraryBuilder,
+ charOffset,
+ charEndOffset,
+ nameScheme,
+ fieldReference: fieldReference,
+ fieldGetterReference: fieldGetterReference,
+ fieldSetterReference: fieldSetterReference,
+ lateIsSetFieldReference: lateIsSetFieldReference,
+ lateIsSetGetterReference: lateIsSetGetterReference,
+ lateIsSetSetterReference: lateIsSetSetterReference,
+ lateGetterReference: lateGetterReference,
+ lateSetterReference: lateSetterReference,
+ initializerToken: initializerToken,
+ constInitializerToken: constInitializerToken);
+ _sourceLibraryBuilder.addBuilder(name, fieldBuilder, charOffset,
+ getterReference: fieldGetterReference,
+ setterReference: fieldSetterReference);
+ return fieldBuilder;
+ }
+
+ @override
+ FormalParameterBuilder addFormalParameter(
+ List<MetadataBuilder>? metadata,
+ FormalParameterKind kind,
+ int modifiers,
+ TypeBuilder type,
+ String name,
+ bool hasThis,
+ bool hasSuper,
+ int charOffset,
+ Token? initializerToken) {
+ assert(!hasThis || !hasSuper,
+ "Formal parameter '${name}' has both 'this' and 'super' prefixes.");
+ if (hasThis) {
+ modifiers |= initializingFormalMask;
+ }
+ if (hasSuper) {
+ modifiers |= superInitializingFormalMask;
+ }
+ FormalParameterBuilder formal = new FormalParameterBuilder(
+ kind, modifiers, type, name, _sourceLibraryBuilder, charOffset,
+ fileUri: fileUri,
+ hasImmediatelyDeclaredInitializer: initializerToken != null)
+ ..initializerToken = initializerToken;
+ return formal;
+ }
+
+ @override
+ TypeBuilder addNamedType(
+ TypeName typeName,
+ NullabilityBuilder nullabilityBuilder,
+ List<TypeBuilder>? arguments,
+ int charOffset,
+ {required InstanceTypeVariableAccessState instanceTypeVariableAccess}) {
+ if (_sourceLibraryBuilder._omittedTypeDeclarationBuilders != null) {
+ Builder? builder =
+ _sourceLibraryBuilder._omittedTypeDeclarationBuilders[typeName.name];
+ if (builder is OmittedTypeDeclarationBuilder) {
+ return new DependentTypeBuilder(builder.omittedTypeBuilder);
+ }
+ }
+ return _registerUnresolvedNamedType(new NamedTypeBuilderImpl(
+ typeName, nullabilityBuilder,
+ arguments: arguments,
+ fileUri: fileUri,
+ charOffset: charOffset,
+ instanceTypeVariableAccess: instanceTypeVariableAccess));
+ }
+
+ NamedTypeBuilder _registerUnresolvedNamedType(NamedTypeBuilder type) {
+ currentTypeParameterScopeBuilder.registerUnresolvedNamedType(type);
+ return type;
+ }
+
+ @override
+ FunctionTypeBuilder addFunctionType(
+ TypeBuilder returnType,
+ List<StructuralVariableBuilder>? structuralVariableBuilders,
+ List<FormalParameterBuilder>? formals,
+ NullabilityBuilder nullabilityBuilder,
+ Uri fileUri,
+ int charOffset,
+ {required bool hasFunctionFormalParameterSyntax}) {
+ FunctionTypeBuilder builder = new FunctionTypeBuilderImpl(
+ returnType,
+ structuralVariableBuilders,
+ formals,
+ nullabilityBuilder,
+ fileUri,
+ charOffset,
+ hasFunctionFormalParameterSyntax: hasFunctionFormalParameterSyntax);
+ _checkStructuralVariables(structuralVariableBuilders, null);
+ if (structuralVariableBuilders != null) {
+ for (StructuralVariableBuilder builder in structuralVariableBuilders) {
+ if (builder.metadata != null) {
+ if (!libraryFeatures.genericMetadata.isEnabled) {
+ addProblem(messageAnnotationOnFunctionTypeTypeVariable,
+ builder.charOffset, builder.name.length, builder.fileUri);
+ }
+ }
+ }
+ }
+ // Nested declaration began in `OutlineBuilder.beginFunctionType` or
+ // `OutlineBuilder.beginFunctionTypedFormalParameter`.
+ endNestedDeclaration(TypeParameterScopeKind.functionType, "#function_type")
+ .resolveNamedTypesWithStructuralVariables(
+ structuralVariableBuilders, _sourceLibraryBuilder);
+ return builder;
+ }
+
+ Map<String, StructuralVariableBuilder>? _checkStructuralVariables(
+ List<StructuralVariableBuilder>? typeVariables, Builder? owner) {
+ if (typeVariables == null || typeVariables.isEmpty) return null;
+ Map<String, StructuralVariableBuilder> typeVariablesByName =
+ <String, StructuralVariableBuilder>{};
+ for (StructuralVariableBuilder tv in typeVariables) {
+ StructuralVariableBuilder? existing = typeVariablesByName[tv.name];
+ if (existing != null) {
+ addProblem(messageTypeVariableDuplicatedName, tv.charOffset,
+ tv.name.length, fileUri,
+ context: [
+ templateTypeVariableDuplicatedNameCause
+ .withArguments(tv.name)
+ .withLocation(
+ fileUri, existing.charOffset, existing.name.length)
+ ]);
+ } else {
+ typeVariablesByName[tv.name] = tv;
+ if (owner is ClassBuilder) {
+ // Only classes and type variables can't have the same name. See
+ // [#29555](https://github.com/dart-lang/sdk/issues/29555).
+ if (tv.name == owner.name) {
+ addProblem(messageTypeVariableSameNameAsEnclosing, tv.charOffset,
+ tv.name.length, fileUri);
+ }
+ }
+ }
+ }
+ return typeVariablesByName;
+ }
+
+ @override
+ TypeBuilder addVoidType(int charOffset) {
+ // 'void' is always nullable.
+ return new NamedTypeBuilderImpl.fromTypeDeclarationBuilder(
+ new VoidTypeDeclarationBuilder(
+ const VoidType(), _sourceLibraryBuilder, charOffset),
+ const NullabilityBuilder.inherent(),
+ charOffset: charOffset,
+ fileUri: fileUri,
+ instanceTypeVariableAccess: InstanceTypeVariableAccessState.Unexpected);
+ }
+
+ @override
+ NominalVariableBuilder addNominalTypeVariable(List<MetadataBuilder>? metadata,
+ String name, TypeBuilder? bound, int charOffset, Uri fileUri,
+ {required TypeVariableKind kind}) {
+ NominalVariableBuilder builder = new NominalVariableBuilder(
+ name, _sourceLibraryBuilder, charOffset, fileUri,
+ bound: bound, metadata: metadata, kind: kind);
+
+ unboundNominalVariables.add(builder);
+ return builder;
+ }
+
+ @override
+ StructuralVariableBuilder addStructuralTypeVariable(
+ List<MetadataBuilder>? metadata,
+ String name,
+ TypeBuilder? bound,
+ int charOffset,
+ Uri fileUri) {
+ StructuralVariableBuilder builder = new StructuralVariableBuilder(
+ name, _sourceLibraryBuilder, charOffset, fileUri,
+ bound: bound, metadata: metadata);
+
+ unboundStructuralVariables.add(builder);
+ return builder;
+ }
+
+ Map<String, NominalVariableBuilder>? _checkTypeVariables(
+ List<NominalVariableBuilder>? typeVariables, Builder? owner) {
+ if (typeVariables == null || typeVariables.isEmpty) return null;
+ Map<String, NominalVariableBuilder> typeVariablesByName =
+ <String, NominalVariableBuilder>{};
+ for (NominalVariableBuilder tv in typeVariables) {
+ NominalVariableBuilder? existing = typeVariablesByName[tv.name];
+ if (existing != null) {
+ if (existing.kind == TypeVariableKind.extensionSynthesized) {
+ // The type parameter from the extension is shadowed by the type
+ // parameter from the member. Rename the shadowed type parameter.
+ existing.parameter.name = '#${existing.name}';
+ typeVariablesByName[tv.name] = tv;
+ } else {
+ addProblem(messageTypeVariableDuplicatedName, tv.charOffset,
+ tv.name.length, fileUri,
+ context: [
+ templateTypeVariableDuplicatedNameCause
+ .withArguments(tv.name)
+ .withLocation(
+ fileUri, existing.charOffset, existing.name.length)
+ ]);
+ }
+ } else {
+ typeVariablesByName[tv.name] = tv;
+ if (owner is TypeDeclarationBuilder) {
+ // Only classes and extension types and type variables can't have the
+ // same name. See
+ // [#29555](https://github.com/dart-lang/sdk/issues/29555) and
+ // [#54602](https://github.com/dart-lang/sdk/issues/54602).
+ switch (owner) {
+ case ClassBuilder():
+ case ExtensionBuilder():
+ case ExtensionTypeDeclarationBuilder():
+ if (tv.name == owner.name) {
+ addProblem(messageTypeVariableSameNameAsEnclosing,
+ tv.charOffset, tv.name.length, fileUri);
+ }
+ case TypeAliasBuilder():
+ case NominalVariableBuilder():
+ case StructuralVariableBuilder():
+ case InvalidTypeDeclarationBuilder():
+ case BuiltinTypeDeclarationBuilder():
+ // TODO(johnniwinther): How should we handle this case?
+ case OmittedTypeDeclarationBuilder():
+ }
+ }
+ }
+ }
+ return typeVariablesByName;
+ }
+
+ @override
+ List<NominalVariableBuilder> copyTypeVariables(
+ List<NominalVariableBuilder> original,
+ TypeParameterScopeBuilder declaration,
+ {required TypeVariableKind kind}) {
+ List<NamedTypeBuilder> newTypes = <NamedTypeBuilder>[];
+ List<NominalVariableBuilder> copy = <NominalVariableBuilder>[];
+ for (NominalVariableBuilder variable in original) {
+ NominalVariableBuilder newVariable = new NominalVariableBuilder(
+ variable.name,
+ _sourceLibraryBuilder,
+ variable.charOffset,
+ variable.fileUri,
+ bound: variable.bound
+ ?.clone(newTypes, _sourceLibraryBuilder, declaration),
+ kind: kind,
+ variableVariance:
+ variable.parameter.isLegacyCovariant ? null : variable.variance);
+ copy.add(newVariable);
+ unboundNominalVariables.add(newVariable);
+ }
+ for (NamedTypeBuilder newType in newTypes) {
+ declaration.registerUnresolvedNamedType(newType);
+ }
+ return copy;
+ }
+
+ @override
+ List<MetadataBuilder>? get metadata => _sourceLibraryBuilder.metadata;
+
+ @override
+ void set metadata(List<MetadataBuilder>? value) {
+ _sourceLibraryBuilder.metadata = value;
+ }
+
+ @override
+ String? get name => _sourceLibraryBuilder.name;
+
+ @override
+ void set name(String? value) {
+ _sourceLibraryBuilder.name = value;
+ }
+
+ @override
+ InferableTypeBuilder addInferableType() {
+ return _sourceLibraryBuilder.addInferableType();
+ }
+
+ @override
+ Message reportFeatureNotEnabled(
+ LibraryFeature feature, Uri fileUri, int charOffset, int length) {
+ return _sourceLibraryBuilder.reportFeatureNotEnabled(
+ feature, fileUri, charOffset, length);
+ }
}
class SourceLibraryBuilder extends LibraryBuilderImpl {
@@ -285,12 +2364,7 @@
@override
final SourceLoader loader;
- /// Map used to find objects created in the [OutlineBuilder] from within
- /// the [DietListener].
- ///
- /// This is meant to be written once and read once.
- OffsetMap? _offsetMap;
-
+ // TODO(johnniwinther): Move this to [SourceCompilationUnitImpl].
final TypeParameterScopeBuilder _libraryTypeParameterScopeBuilder;
final List<ConstructorReferenceBuilder> constructorReferences =
@@ -326,15 +2400,13 @@
@override
LibraryBuilder? partOfLibrary;
- /// Offset of the first script tag (`#!...`) in this library or part.
- int? _scriptTokenOffset;
-
List<MetadataBuilder>? metadata;
/// The current declaration that is being built. When we start parsing a
/// declaration (class, method, and so on), we don't have enough information
/// to create a builder and this object records its members and types until,
/// for example, [addClass] is called.
+ // TODO(johnniwinther): Move this to [SourceCompilationUnitImpl].
TypeParameterScopeBuilder currentTypeParameterScopeBuilder;
/// Non-null if this library causes an error upon access, that is, there was
@@ -381,12 +2453,9 @@
final LibraryBuilder? _nameOrigin;
/// Index of the library we use references for.
+ // TODO(johnniwinther): Move this to [SourceCompilationUnitImpl].
final IndexedLibrary? indexedLibrary;
- // TODO(johnniwinther): Use [_indexedContainer] for library members and make
- // it [null] when there is null corresponding [IndexedContainer].
- IndexedContainer? _indexedContainer;
-
/// Exports that can't be serialized.
///
/// The key is the name of the exported member.
@@ -437,6 +2506,7 @@
///
/// This is used in macro generated code to create type annotations from
/// inferred types in the original code.
+ // TODO(johnniwinther): Move to [SourceCompilationUnitImpl].
final Map<String, Builder>? _omittedTypeDeclarationBuilders;
MergedLibraryScope? _mergedScope;
@@ -520,24 +2590,6 @@
"'${importUri}'.");
}
- /// Returns the map of objects created in the [OutlineBuilder].
- ///
- /// This should only be called once.
- OffsetMap get offsetMap {
- assert(_offsetMap != null, "No OffsetMap for $this");
- OffsetMap map = _offsetMap!;
- _offsetMap = null;
- return map;
- }
-
- /// Registers the map of objects created in the [OutlineBuilder].
- ///
- /// This should only be called once.
- void set offsetMap(OffsetMap value) {
- assert(_offsetMap == null, "OffsetMap has already been set for $this");
- _offsetMap = value;
- }
-
MergedLibraryScope get mergedScope {
return _mergedScope ??=
isAugmenting ? origin.mergedScope : new MergedLibraryScope(this);
@@ -723,7 +2775,8 @@
referencesFromIndex: indexedLibrary,
omittedTypes: omittedTypeDeclarationBuilders);
addAugmentationLibrary(augmentationLibrary);
- loader.registerUnparsedLibrarySource(augmentationLibrary, source);
+ loader.registerUnparsedLibrarySource(
+ augmentationLibrary.compilationUnit, source);
return augmentationLibrary;
}
@@ -733,11 +2786,6 @@
@override
bool get isSynthetic => accessProblem != null;
- NamedTypeBuilder registerUnresolvedNamedType(NamedTypeBuilder type) {
- currentTypeParameterScopeBuilder.registerUnresolvedNamedType(type);
- return type;
- }
-
bool get isInferenceUpdate1Enabled =>
libraryFeatures.inferenceUpdate1.isSupported &&
languageVersion.version >=
@@ -805,42 +2853,9 @@
_languageVersion.isFinal = true;
}
- ConstructorReferenceBuilder addConstructorReference(TypeName name,
- List<TypeBuilder>? typeArguments, String? suffix, int charOffset) {
- ConstructorReferenceBuilder ref = new ConstructorReferenceBuilder(
- name, typeArguments, suffix, fileUri, charOffset);
- constructorReferences.add(ref);
- return ref;
- }
-
- void beginNestedDeclaration(TypeParameterScopeKind kind, String name,
- {bool hasMembers = true}) {
- currentTypeParameterScopeBuilder =
- currentTypeParameterScopeBuilder.createNested(kind, name, hasMembers);
- }
-
- TypeParameterScopeBuilder endNestedDeclaration(
- TypeParameterScopeKind kind, String? name) {
- assert(
- currentTypeParameterScopeBuilder.kind == kind,
- "Unexpected declaration. "
- "Trying to end a ${currentTypeParameterScopeBuilder.kind} as a $kind.");
- assert(
- (name?.startsWith(currentTypeParameterScopeBuilder.name) ??
- (name == currentTypeParameterScopeBuilder.name)) ||
- currentTypeParameterScopeBuilder.name == "operator" ||
- (name == null &&
- currentTypeParameterScopeBuilder.name ==
- UnnamedExtensionName.unnamedExtensionSentinel) ||
- identical(name, "<syntax-error>"),
- "${name} != ${currentTypeParameterScopeBuilder.name}");
- TypeParameterScopeBuilder previous = currentTypeParameterScopeBuilder;
- currentTypeParameterScopeBuilder = currentTypeParameterScopeBuilder.parent!;
- return previous;
- }
-
bool uriIsValid(Uri uri) => !uri.isScheme(MALFORMED_URI_SCHEME);
+ // TODO(johnniwinther): Move this to [SourceCompilationUnitImpl].
Uri resolve(Uri baseUri, String? uri, int uriOffset, {isPart = false}) {
if (uri == null) {
addProblem(messageExpectedUri, uriOffset, noLength, fileUri);
@@ -866,47 +2881,6 @@
}
}
- String? computeAndValidateConstructorName(Identifier identifier,
- {isFactory = false}) {
- String className = currentTypeParameterScopeBuilder.name;
- String prefix;
- String? suffix;
- int charOffset;
- if (identifier is QualifiedName) {
- Identifier qualifier = identifier.qualifier as Identifier;
- prefix = qualifier.name;
- suffix = identifier.name;
- charOffset = qualifier.nameOffset;
- } else {
- prefix = identifier.name;
- suffix = null;
- charOffset = identifier.nameOffset;
- }
- if (libraryFeatures.constructorTearoffs.isEnabled) {
- suffix = suffix == "new" ? "" : suffix;
- }
- if (prefix == className) {
- return suffix ?? "";
- }
- if (suffix == null && !isFactory) {
- // A legal name for a regular method, but not for a constructor.
- return null;
- }
-
- addProblem(
- messageConstructorWithWrongName, charOffset, prefix.length, fileUri,
- context: [
- templateConstructorWithWrongNameContext
- .withArguments(currentTypeParameterScopeBuilder.name)
- .withLocation(
- importUri,
- currentTypeParameterScopeBuilder.charOffset,
- currentTypeParameterScopeBuilder.name.length)
- ]);
-
- return suffix;
- }
-
@override
Iterable<Uri> get dependencies sync* {
for (Export export in exports) {
@@ -920,186 +2894,6 @@
}
}
- void addExport(
- OffsetMap offsetMap,
- Token exportKeyword,
- List<MetadataBuilder>? metadata,
- String uri,
- List<Configuration>? configurations,
- List<CombinatorBuilder>? combinators,
- int charOffset,
- int uriOffset) {
- if (configurations != null) {
- for (Configuration config in configurations) {
- if (loader.getLibrarySupportValue(config.dottedName) ==
- config.condition) {
- uri = config.importUri;
- break;
- }
- }
- }
-
- CompilationUnit exportedLibrary = loader.read(
- resolve(this.importUri, uri, uriOffset), charOffset,
- accessor: compilationUnit);
- exportedLibrary.addExporter(this, combinators, charOffset);
- Export export = new Export(this, exportedLibrary, combinators, charOffset);
- exports.add(export);
- offsetMap.registerExport(exportKeyword, export);
- }
-
- void addImport(
- {OffsetMap? offsetMap,
- Token? importKeyword,
- required List<MetadataBuilder>? metadata,
- required bool isAugmentationImport,
- required String uri,
- required List<Configuration>? configurations,
- required String? prefix,
- required List<CombinatorBuilder>? combinators,
- required bool deferred,
- required int charOffset,
- required int prefixCharOffset,
- required int uriOffset,
- required int importIndex}) {
- if (configurations != null) {
- for (Configuration config in configurations) {
- if (loader.getLibrarySupportValue(config.dottedName) ==
- config.condition) {
- uri = config.importUri;
- break;
- }
- }
- }
-
- CompilationUnit? compilationUnit = null;
- Uri? resolvedUri;
- String? nativePath;
- const String nativeExtensionScheme = "dart-ext:";
- if (uri.startsWith(nativeExtensionScheme)) {
- addProblem(messageUnsupportedDartExt, charOffset, noLength, fileUri);
- String strippedUri = uri.substring(nativeExtensionScheme.length);
- if (strippedUri.startsWith("package")) {
- resolvedUri = resolve(this.importUri, strippedUri,
- uriOffset + nativeExtensionScheme.length);
- resolvedUri = loader.target.translateUri(resolvedUri);
- nativePath = resolvedUri.toString();
- } else {
- resolvedUri = new Uri(scheme: "dart-ext", pathSegments: [uri]);
- nativePath = uri;
- }
- } else {
- resolvedUri = resolve(this.importUri, uri, uriOffset);
- compilationUnit = loader.read(resolvedUri, uriOffset,
- origin: isAugmentationImport ? this : null,
- accessor: this.compilationUnit,
- isAugmentation: isAugmentationImport,
- referencesFromIndex: isAugmentationImport ? indexedLibrary : null);
- }
-
- Import import = new Import(
- this,
- compilationUnit,
- isAugmentationImport,
- deferred,
- prefix,
- combinators,
- configurations,
- charOffset,
- prefixCharOffset,
- importIndex,
- nativeImportPath: nativePath);
- imports.add(import);
- offsetMap?.registerImport(importKeyword!, import);
- }
-
- void addPart(OffsetMap offsetMap, Token partKeyword,
- List<MetadataBuilder>? metadata, String uri, int charOffset) {
- Uri resolvedUri = resolve(this.importUri, uri, charOffset, isPart: true);
- // To support absolute paths from within packages in the part uri, we try to
- // translate the file uri from the resolved import uri before resolving
- // through the file uri of this library. See issue #52964.
- Uri newFileUri = loader.target.uriTranslator.translate(resolvedUri) ??
- resolve(fileUri, uri, charOffset);
- // TODO(johnniwinther): Add a LibraryPartBuilder instead of using
- // [LibraryBuilder] to represent both libraries and parts.
- CompilationUnit compilationUnit = loader.read(resolvedUri, charOffset,
- origin: isAugmenting ? origin : null,
- fileUri: newFileUri,
- accessor: this.compilationUnit,
- isPatch: isAugmenting);
- parts.add(new Part(charOffset, compilationUnit));
-
- // TODO(ahe): [metadata] should be stored, evaluated, and added to [part].
- LibraryPart part = new LibraryPart(<Expression>[], uri)
- ..fileOffset = charOffset;
- library.addPart(part);
- offsetMap.registerPart(partKeyword, part);
- }
-
- void addPartOf(List<MetadataBuilder>? metadata, String? name, String? uri,
- int uriOffset) {
- partOfName = name;
- if (uri != null) {
- Uri resolvedUri = partOfUri = resolve(this.importUri, uri, uriOffset);
- // To support absolute paths from within packages in the part of uri, we
- // try to translate the file uri from the resolved import uri before
- // resolving through the file uri of this library. See issue #52964.
- Uri newFileUri = loader.target.uriTranslator.translate(resolvedUri) ??
- resolve(fileUri, uri, uriOffset);
- loader.read(partOfUri!, uriOffset,
- fileUri: newFileUri, accessor: compilationUnit);
- }
- if (_scriptTokenOffset != null) {
- addProblem(
- messageScriptTagInPartFile, _scriptTokenOffset!, noLength, fileUri);
- }
- }
-
- void addScriptToken(int charOffset) {
- _scriptTokenOffset ??= charOffset;
- }
-
- void addFields(
- OffsetMap offsetMap,
- List<MetadataBuilder>? metadata,
- int modifiers,
- bool isTopLevel,
- TypeBuilder? type,
- List<FieldInfo> fieldInfos) {
- for (FieldInfo info in fieldInfos) {
- bool isConst = modifiers & constMask != 0;
- bool isFinal = modifiers & finalMask != 0;
- bool potentiallyNeedInitializerInOutline = isConst || isFinal;
- Token? startToken;
- if (potentiallyNeedInitializerInOutline || type == null) {
- startToken = info.initializerToken;
- }
- if (startToken != null) {
- // Extract only the tokens for the initializer expression from the
- // token stream.
- Token endToken = info.beforeLast!;
- endToken.setNext(new Token.eof(endToken.next!.offset));
- new Token.eof(startToken.previous!.offset).setNext(startToken);
- }
- bool hasInitializer = info.initializerToken != null;
- offsetMap.registerField(
- info.identifier,
- addField(
- metadata,
- modifiers,
- isTopLevel,
- type ?? addInferableType(),
- info.identifier.name,
- info.identifier.nameOffset,
- info.charEndOffset,
- startToken,
- hasInitializer,
- constInitializerToken:
- potentiallyNeedInitializerInOutline ? startToken : null));
- }
- }
-
Builder addBuilder(String name, Builder declaration, int charOffset,
{Reference? getterReference, Reference? setterReference}) {
// TODO(ahe): Set the parent correctly here. Could then change the
@@ -2018,41 +3812,6 @@
_inferableTypes = null;
}
- TypeBuilder addNamedType(
- TypeName typeName,
- NullabilityBuilder nullabilityBuilder,
- List<TypeBuilder>? arguments,
- int charOffset,
- {required InstanceTypeVariableAccessState instanceTypeVariableAccess}) {
- if (_omittedTypeDeclarationBuilders != null) {
- Builder? builder = _omittedTypeDeclarationBuilders[typeName.name];
- if (builder is OmittedTypeDeclarationBuilder) {
- return new DependentTypeBuilder(builder.omittedTypeBuilder);
- }
- }
- return registerUnresolvedNamedType(new NamedTypeBuilderImpl(
- typeName, nullabilityBuilder,
- arguments: arguments,
- fileUri: fileUri,
- charOffset: charOffset,
- instanceTypeVariableAccess: instanceTypeVariableAccess));
- }
-
- MixinApplicationBuilder addMixinApplication(
- List<TypeBuilder> mixins, int charOffset) {
- return new MixinApplicationBuilder(mixins, fileUri, charOffset);
- }
-
- TypeBuilder addVoidType(int charOffset) {
- // 'void' is always nullable.
- return new NamedTypeBuilderImpl.fromTypeDeclarationBuilder(
- new VoidTypeDeclarationBuilder(const VoidType(), this, charOffset),
- const NullabilityBuilder.inherent(),
- charOffset: charOffset,
- fileUri: fileUri,
- instanceTypeVariableAccess: InstanceTypeVariableAccessState.Unexpected);
- }
-
/// Add a problem that might not be reported immediately.
///
/// Problems will be issued after source information has been added.
@@ -2110,303 +3869,6 @@
factory.setRedirectingFactoryError(text);
}
- void addClass(
- OffsetMap offsetMap,
- List<MetadataBuilder>? metadata,
- int modifiers,
- Identifier identifier,
- List<NominalVariableBuilder>? typeVariables,
- TypeBuilder? supertype,
- MixinApplicationBuilder? mixins,
- List<TypeBuilder>? interfaces,
- int startOffset,
- int nameOffset,
- int endOffset,
- int supertypeOffset,
- {required bool isMacro,
- required bool isSealed,
- required bool isBase,
- required bool isInterface,
- required bool isFinal,
- required bool isAugmentation,
- required bool isMixinClass}) {
- _addClass(
- offsetMap,
- TypeParameterScopeKind.classDeclaration,
- metadata,
- modifiers,
- identifier,
- typeVariables,
- supertype,
- mixins,
- interfaces,
- startOffset,
- nameOffset,
- endOffset,
- supertypeOffset,
- isMacro: isMacro,
- isSealed: isSealed,
- isBase: isBase,
- isInterface: isInterface,
- isFinal: isFinal,
- isAugmentation: isAugmentation,
- isMixinClass: isMixinClass);
- }
-
- void addMixinDeclaration(
- OffsetMap offsetMap,
- List<MetadataBuilder>? metadata,
- int modifiers,
- Identifier identifier,
- List<NominalVariableBuilder>? typeVariables,
- List<TypeBuilder>? supertypeConstraints,
- List<TypeBuilder>? interfaces,
- int startOffset,
- int nameOffset,
- int endOffset,
- int supertypeOffset,
- {required bool isBase,
- required bool isAugmentation}) {
- TypeBuilder? supertype;
- MixinApplicationBuilder? mixinApplication;
- if (supertypeConstraints != null && supertypeConstraints.isNotEmpty) {
- supertype = supertypeConstraints.first;
- if (supertypeConstraints.length > 1) {
- mixinApplication = new MixinApplicationBuilder(
- supertypeConstraints.skip(1).toList(),
- supertype.fileUri!,
- supertype.charOffset!);
- }
- }
- _addClass(
- offsetMap,
- TypeParameterScopeKind.mixinDeclaration,
- metadata,
- modifiers,
- identifier,
- typeVariables,
- supertype,
- mixinApplication,
- interfaces,
- startOffset,
- nameOffset,
- endOffset,
- supertypeOffset,
- isMacro: false,
- isSealed: false,
- isBase: isBase,
- isInterface: false,
- isFinal: false,
- isAugmentation: isAugmentation,
- isMixinClass: false);
- }
-
- void _addClass(
- OffsetMap offsetMap,
- TypeParameterScopeKind kind,
- List<MetadataBuilder>? metadata,
- int modifiers,
- Identifier identifier,
- List<NominalVariableBuilder>? typeVariables,
- TypeBuilder? supertype,
- MixinApplicationBuilder? mixins,
- List<TypeBuilder>? interfaces,
- int startOffset,
- int nameOffset,
- int endOffset,
- int supertypeOffset,
- {required bool isMacro,
- required bool isSealed,
- required bool isBase,
- required bool isInterface,
- required bool isFinal,
- required bool isAugmentation,
- required bool isMixinClass}) {
- String className = identifier.name;
- // Nested declaration began in `OutlineBuilder.beginClassDeclaration`.
- TypeParameterScopeBuilder declaration =
- endNestedDeclaration(kind, className)
- ..resolveNamedTypes(typeVariables, this);
- assert(declaration.parent == _libraryTypeParameterScopeBuilder);
- Map<String, Builder> members = declaration.members!;
- Map<String, MemberBuilder> constructors = declaration.constructors!;
- Map<String, MemberBuilder> setters = declaration.setters!;
-
- Scope classScope = new Scope(
- kind: ScopeKind.declaration,
- local: members,
- setters: setters,
- parent: scope.withTypeVariables(typeVariables),
- debugName: "class $className",
- isModifiable: false);
-
- // When looking up a constructor, we don't consider type variables or the
- // library scope.
- ConstructorScope constructorScope =
- new ConstructorScope(className, constructors);
- bool isMixinDeclaration = false;
- if (modifiers & mixinDeclarationMask != 0) {
- isMixinDeclaration = true;
- modifiers = (modifiers & ~mixinDeclarationMask) | abstractMask;
- }
- if (declaration.declaresConstConstructor) {
- modifiers |= declaresConstConstructorMask;
- }
- SourceClassBuilder classBuilder = new SourceClassBuilder(
- metadata,
- modifiers,
- className,
- typeVariables,
- _applyMixins(supertype, mixins, startOffset, nameOffset, endOffset,
- className, isMixinDeclaration,
- typeVariables: typeVariables,
- isMacro: false,
- isSealed: false,
- isBase: false,
- isInterface: false,
- isFinal: false,
- // TODO(johnniwinther): How can we support class with mixins?
- isAugmentation: false,
- isMixinClass: false),
- interfaces,
- // TODO(johnniwinther): Add the `on` clause types of a mixin declaration
- // here.
- null,
- classScope,
- constructorScope,
- this,
- new List<ConstructorReferenceBuilder>.of(constructorReferences),
- startOffset,
- nameOffset,
- endOffset,
- _indexedContainer,
- isMixinDeclaration: isMixinDeclaration,
- isMacro: isMacro,
- isSealed: isSealed,
- isBase: isBase,
- isInterface: isInterface,
- isFinal: isFinal,
- isAugmentation: isAugmentation,
- isMixinClass: isMixinClass);
-
- constructorReferences.clear();
- Map<String, NominalVariableBuilder>? typeVariablesByName =
- checkTypeVariables(typeVariables, classBuilder);
- void setParent(MemberBuilder? member) {
- while (member != null) {
- member.parent = classBuilder;
- member = member.next as MemberBuilder?;
- }
- }
-
- void setParentAndCheckConflicts(String name, Builder member) {
- if (typeVariablesByName != null) {
- NominalVariableBuilder? tv = typeVariablesByName[name];
- if (tv != null) {
- classBuilder.addProblem(
- templateConflictsWithTypeVariable.withArguments(name),
- member.charOffset,
- name.length,
- context: [
- messageConflictsWithTypeVariableCause.withLocation(
- tv.fileUri!, tv.charOffset, name.length)
- ]);
- }
- }
- setParent(member as MemberBuilder);
- }
-
- members.forEach(setParentAndCheckConflicts);
- constructors.forEach(setParentAndCheckConflicts);
- setters.forEach(setParentAndCheckConflicts);
- addBuilder(className, classBuilder, nameOffset,
- getterReference: _indexedContainer?.reference);
- offsetMap.registerNamedDeclaration(identifier, classBuilder);
- }
-
- Map<String, NominalVariableBuilder>? checkTypeVariables(
- List<NominalVariableBuilder>? typeVariables, Builder? owner) {
- if (typeVariables == null || typeVariables.isEmpty) return null;
- Map<String, NominalVariableBuilder> typeVariablesByName =
- <String, NominalVariableBuilder>{};
- for (NominalVariableBuilder tv in typeVariables) {
- NominalVariableBuilder? existing = typeVariablesByName[tv.name];
- if (existing != null) {
- if (existing.kind == TypeVariableKind.extensionSynthesized) {
- // The type parameter from the extension is shadowed by the type
- // parameter from the member. Rename the shadowed type parameter.
- existing.parameter.name = '#${existing.name}';
- typeVariablesByName[tv.name] = tv;
- } else {
- addProblem(messageTypeVariableDuplicatedName, tv.charOffset,
- tv.name.length, fileUri,
- context: [
- templateTypeVariableDuplicatedNameCause
- .withArguments(tv.name)
- .withLocation(
- fileUri, existing.charOffset, existing.name.length)
- ]);
- }
- } else {
- typeVariablesByName[tv.name] = tv;
- if (owner is TypeDeclarationBuilder) {
- // Only classes and extension types and type variables can't have the
- // same name. See
- // [#29555](https://github.com/dart-lang/sdk/issues/29555) and
- // [#54602](https://github.com/dart-lang/sdk/issues/54602).
- switch (owner) {
- case ClassBuilder():
- case ExtensionBuilder():
- case ExtensionTypeDeclarationBuilder():
- if (tv.name == owner.name) {
- addProblem(messageTypeVariableSameNameAsEnclosing,
- tv.charOffset, tv.name.length, fileUri);
- }
- case TypeAliasBuilder():
- case NominalVariableBuilder():
- case StructuralVariableBuilder():
- case InvalidTypeDeclarationBuilder():
- case BuiltinTypeDeclarationBuilder():
- // TODO(johnniwinther): How should we handle this case?
- case OmittedTypeDeclarationBuilder():
- }
- }
- }
- }
- return typeVariablesByName;
- }
-
- Map<String, StructuralVariableBuilder>? checkStructuralVariables(
- List<StructuralVariableBuilder>? typeVariables, Builder? owner) {
- if (typeVariables == null || typeVariables.isEmpty) return null;
- Map<String, StructuralVariableBuilder> typeVariablesByName =
- <String, StructuralVariableBuilder>{};
- for (StructuralVariableBuilder tv in typeVariables) {
- StructuralVariableBuilder? existing = typeVariablesByName[tv.name];
- if (existing != null) {
- addProblem(messageTypeVariableDuplicatedName, tv.charOffset,
- tv.name.length, fileUri,
- context: [
- templateTypeVariableDuplicatedNameCause
- .withArguments(tv.name)
- .withLocation(
- fileUri, existing.charOffset, existing.name.length)
- ]);
- } else {
- typeVariablesByName[tv.name] = tv;
- if (owner is ClassBuilder) {
- // Only classes and type variables can't have the same name. See
- // [#29555](https://github.com/dart-lang/sdk/issues/29555).
- if (tv.name == owner.name) {
- addProblem(messageTypeVariableSameNameAsEnclosing, tv.charOffset,
- tv.name.length, fileUri);
- }
- }
- }
- }
- return typeVariablesByName;
- }
-
void checkGetterSetterTypes(ProcedureBuilder getterBuilder,
ProcedureBuilder setterBuilder, TypeEnvironment typeEnvironment) {
DartType getterType;
@@ -2494,520 +3956,11 @@
}
}
- void addExtensionDeclaration(
- OffsetMap offsetMap,
- Token beginToken,
- List<MetadataBuilder>? metadata,
- int modifiers,
- Identifier? identifier,
- List<NominalVariableBuilder>? typeVariables,
- TypeBuilder type,
- int startOffset,
- int nameOffset,
- int endOffset) {
- String? name = identifier?.name;
- // Nested declaration began in
- // `OutlineBuilder.beginExtensionDeclarationPrelude`.
- TypeParameterScopeBuilder declaration =
- endNestedDeclaration(TypeParameterScopeKind.extensionDeclaration, name)
- ..resolveNamedTypes(typeVariables, this);
- assert(declaration.parent == _libraryTypeParameterScopeBuilder);
- Map<String, Builder> members = declaration.members!;
- Map<String, MemberBuilder> constructors = declaration.constructors!;
- Map<String, MemberBuilder> setters = declaration.setters!;
-
- Scope classScope = new Scope(
- kind: ScopeKind.declaration,
- local: members,
- setters: setters,
- parent: scope.withTypeVariables(typeVariables),
- debugName: "extension $name",
- isModifiable: false);
-
- Extension? referenceFrom;
- ExtensionName extensionName = declaration.extensionName!;
- if (name != null) {
- referenceFrom = indexedLibrary?.lookupExtension(name);
- }
-
- ExtensionBuilder extensionBuilder = new SourceExtensionBuilder(
- metadata,
- modifiers,
- extensionName,
- typeVariables,
- type,
- classScope,
- this,
- startOffset,
- nameOffset,
- endOffset,
- referenceFrom);
- constructorReferences.clear();
- Map<String, NominalVariableBuilder>? typeVariablesByName =
- checkTypeVariables(typeVariables, extensionBuilder);
- void setParent(MemberBuilder? member) {
- while (member != null) {
- member.parent = extensionBuilder;
- member = member.next as MemberBuilder?;
- }
- }
-
- void setParentAndCheckConflicts(String name, Builder member) {
- if (typeVariablesByName != null) {
- NominalVariableBuilder? tv = typeVariablesByName[name];
- if (tv != null) {
- extensionBuilder.addProblem(
- templateConflictsWithTypeVariable.withArguments(name),
- member.charOffset,
- name.length,
- context: [
- messageConflictsWithTypeVariableCause.withLocation(
- tv.fileUri!, tv.charOffset, name.length)
- ]);
- }
- }
- setParent(member as MemberBuilder);
- }
-
- members.forEach(setParentAndCheckConflicts);
- constructors.forEach(setParentAndCheckConflicts);
- setters.forEach(setParentAndCheckConflicts);
- addBuilder(extensionBuilder.name, extensionBuilder, nameOffset,
- getterReference: referenceFrom?.reference);
- if (identifier != null) {
- offsetMap.registerNamedDeclaration(identifier, extensionBuilder);
- } else {
- offsetMap.registerUnnamedDeclaration(beginToken, extensionBuilder);
- }
- }
-
- void addExtensionTypeDeclaration(
- OffsetMap offsetMap,
- List<MetadataBuilder>? metadata,
- int modifiers,
- Identifier identifier,
- List<NominalVariableBuilder>? typeVariables,
- List<TypeBuilder>? interfaces,
- int startOffset,
- int endOffset) {
- String name = identifier.name;
- // Nested declaration began in `OutlineBuilder.beginExtensionDeclaration`.
- TypeParameterScopeBuilder declaration = endNestedDeclaration(
- TypeParameterScopeKind.extensionTypeDeclaration, name)
- ..resolveNamedTypes(typeVariables, this);
- assert(declaration.parent == _libraryTypeParameterScopeBuilder);
- Map<String, Builder> members = declaration.members!;
- Map<String, MemberBuilder> constructors = declaration.constructors!;
- Map<String, MemberBuilder> setters = declaration.setters!;
-
- Scope memberScope = new Scope(
- kind: ScopeKind.declaration,
- local: members,
- setters: setters,
- parent: scope.withTypeVariables(typeVariables),
- debugName: "extension type $name",
- isModifiable: false);
- ConstructorScope constructorScope =
- new ConstructorScope(name, constructors);
-
- IndexedContainer? indexedContainer =
- indexedLibrary?.lookupIndexedExtensionTypeDeclaration(name);
-
- SourceFieldBuilder? representationFieldBuilder;
- outer:
- for (Builder? member in members.values) {
- while (member != null) {
- if (!member.isDuplicate &&
- member is SourceFieldBuilder &&
- !member.isStatic) {
- representationFieldBuilder = member;
- break outer;
- }
- member = member.next;
- }
- }
-
- ExtensionTypeDeclarationBuilder extensionTypeDeclarationBuilder =
- new SourceExtensionTypeDeclarationBuilder(
- metadata,
- modifiers,
- declaration.name,
- typeVariables,
- interfaces,
- memberScope,
- constructorScope,
- this,
- new List<ConstructorReferenceBuilder>.of(constructorReferences),
- startOffset,
- identifier.nameOffset,
- endOffset,
- indexedContainer,
- representationFieldBuilder);
- constructorReferences.clear();
- Map<String, NominalVariableBuilder>? typeVariablesByName =
- checkTypeVariables(typeVariables, extensionTypeDeclarationBuilder);
- void setParent(MemberBuilder? member) {
- while (member != null) {
- member.parent = extensionTypeDeclarationBuilder;
- member = member.next as MemberBuilder?;
- }
- }
-
- void setParentAndCheckConflicts(String name, Builder member) {
- if (typeVariablesByName != null) {
- NominalVariableBuilder? tv = typeVariablesByName[name];
- if (tv != null) {
- extensionTypeDeclarationBuilder.addProblem(
- templateConflictsWithTypeVariable.withArguments(name),
- member.charOffset,
- name.length,
- context: [
- messageConflictsWithTypeVariableCause.withLocation(
- tv.fileUri!, tv.charOffset, name.length)
- ]);
- }
- }
- setParent(member as MemberBuilder);
- }
-
- members.forEach(setParentAndCheckConflicts);
- constructors.forEach(setParentAndCheckConflicts);
- setters.forEach(setParentAndCheckConflicts);
- addBuilder(extensionTypeDeclarationBuilder.name,
- extensionTypeDeclarationBuilder, identifier.nameOffset,
- getterReference: indexedContainer?.reference);
- offsetMap.registerNamedDeclaration(
- identifier, extensionTypeDeclarationBuilder);
- }
-
- TypeBuilder? _applyMixins(
- TypeBuilder? supertype,
- MixinApplicationBuilder? mixinApplications,
- int startCharOffset,
- int charOffset,
- int charEndOffset,
- String subclassName,
- bool isMixinDeclaration,
- {List<MetadataBuilder>? metadata,
- String? name,
- List<NominalVariableBuilder>? typeVariables,
- int modifiers = 0,
- List<TypeBuilder>? interfaces,
- required bool isMacro,
- required bool isSealed,
- required bool isBase,
- required bool isInterface,
- required bool isFinal,
- required bool isAugmentation,
- required bool isMixinClass}) {
- if (name == null) {
- // The following parameters should only be used when building a named
- // mixin application.
- if (metadata != null) {
- unhandled("metadata", "unnamed mixin application", charOffset, fileUri);
- } else if (interfaces != null) {
- unhandled(
- "interfaces", "unnamed mixin application", charOffset, fileUri);
- }
- }
- if (mixinApplications != null) {
- // Documentation below assumes the given mixin application is in one of
- // these forms:
- //
- // class C extends S with M1, M2, M3;
- // class Named = S with M1, M2, M3;
- //
- // When we refer to the subclass, we mean `C` or `Named`.
-
- /// The current supertype.
- ///
- /// Starts out having the value `S` and on each iteration of the loop
- /// below, it will take on the value corresponding to:
- ///
- /// 1. `S with M1`.
- /// 2. `(S with M1) with M2`.
- /// 3. `((S with M1) with M2) with M3`.
- supertype ??= loader.target.objectType;
-
- /// The variable part of the mixin application's synthetic name. It
- /// starts out as the name of the superclass, but is only used after it
- /// has been combined with the name of the current mixin. In the examples
- /// from above, it will take these values:
- ///
- /// 1. `S&M1`
- /// 2. `S&M1&M2`
- /// 3. `S&M1&M2&M3`.
- ///
- /// The full name of the mixin application is obtained by prepending the
- /// name of the subclass (`C` or `Named` in the above examples) to the
- /// running name. For the example `C`, that leads to these full names:
- ///
- /// 1. `_C&S&M1`
- /// 2. `_C&S&M1&M2`
- /// 3. `_C&S&M1&M2&M3`.
- ///
- /// For a named mixin application, the last name has been given by the
- /// programmer, so for the example `Named` we see these full names:
- ///
- /// 1. `_Named&S&M1`
- /// 2. `_Named&S&M1&M2`
- /// 3. `Named`.
- String runningName;
- if (supertype.typeName == null) {
- assert(supertype is FunctionTypeBuilder);
-
- // Function types don't have names, and we can supply any string that
- // doesn't have to be unique. The actual supertype of the mixin will
- // not be built in that case.
- runningName = "";
- } else {
- runningName = supertype.typeName!.name;
- }
-
- /// True when we're building a named mixin application. Notice that for
- /// the `Named` example above, this is only true on the last
- /// iteration because only the full mixin application is named.
- bool isNamedMixinApplication;
-
- /// The names of the type variables of the subclass.
- Set<String>? typeVariableNames;
- if (typeVariables != null) {
- typeVariableNames = new Set<String>();
- for (NominalVariableBuilder typeVariable in typeVariables) {
- typeVariableNames.add(typeVariable.name);
- }
- }
-
- /// Helper function that returns `true` if a type variable with a name
- /// from [typeVariableNames] is referenced in [type].
- bool usesTypeVariables(TypeBuilder? type) {
- switch (type) {
- case NamedTypeBuilder(
- :TypeDeclarationBuilder? declaration,
- typeArguments: List<TypeBuilder>? arguments
- ):
- if (declaration is NominalVariableBuilder) {
- return typeVariableNames!.contains(declaration.name);
- }
- if (declaration is StructuralVariableBuilder) {
- return typeVariableNames!.contains(declaration.name);
- }
-
- if (arguments != null && typeVariables != null) {
- for (TypeBuilder argument in arguments) {
- if (usesTypeVariables(argument)) {
- return true;
- }
- }
- }
- case FunctionTypeBuilder(
- :List<ParameterBuilder>? formals,
- :List<StructuralVariableBuilder>? typeVariables
- ):
- if (formals != null) {
- for (ParameterBuilder formal in formals) {
- if (usesTypeVariables(formal.type)) {
- return true;
- }
- }
- }
- if (typeVariables != null) {
- for (StructuralVariableBuilder variable in typeVariables) {
- if (usesTypeVariables(variable.bound)) {
- return true;
- }
- }
- }
- return usesTypeVariables(type.returnType);
- case RecordTypeBuilder(
- :List<RecordTypeFieldBuilder>? positionalFields,
- :List<RecordTypeFieldBuilder>? namedFields
- ):
- if (positionalFields != null) {
- for (RecordTypeFieldBuilder fieldBuilder in positionalFields) {
- if (usesTypeVariables(fieldBuilder.type)) {
- return true;
- }
- }
- }
- if (namedFields != null) {
- for (RecordTypeFieldBuilder fieldBuilder in namedFields) {
- if (usesTypeVariables(fieldBuilder.type)) {
- return true;
- }
- }
- }
- case FixedTypeBuilder():
- case InvalidTypeBuilder():
- case OmittedTypeBuilder():
- case null:
- return false;
- }
- return false;
- }
-
- /// Iterate over the mixins from left to right. At the end of each
- /// iteration, a new [supertype] is computed that is the mixin
- /// application of [supertype] with the current mixin.
- for (int i = 0; i < mixinApplications.mixins.length; i++) {
- TypeBuilder mixin = mixinApplications.mixins[i];
- isNamedMixinApplication =
- name != null && mixin == mixinApplications.mixins.last;
- bool isGeneric = false;
- if (!isNamedMixinApplication) {
- if (supertype is NamedTypeBuilder) {
- isGeneric = isGeneric || usesTypeVariables(supertype);
- }
- if (mixin is NamedTypeBuilder) {
- runningName += "&${mixin.typeName.name}";
- isGeneric = isGeneric || usesTypeVariables(mixin);
- }
- }
- String fullname =
- isNamedMixinApplication ? name : "_$subclassName&$runningName";
- List<NominalVariableBuilder>? applicationTypeVariables;
- List<TypeBuilder>? applicationTypeArguments;
- if (isNamedMixinApplication) {
- // If this is a named mixin application, it must be given all the
- // declared type variables.
- applicationTypeVariables = typeVariables;
- } else {
- // Otherwise, we pass the fresh type variables to the mixin
- // application in the same order as they're declared on the subclass.
- if (isGeneric) {
- this.beginNestedDeclaration(
- TypeParameterScopeKind.unnamedMixinApplication,
- "mixin application");
-
- applicationTypeVariables = copyTypeVariables(
- typeVariables!, currentTypeParameterScopeBuilder,
- kind: TypeVariableKind.extensionSynthesized);
-
- List<NamedTypeBuilder> newTypes = <NamedTypeBuilder>[];
- if (supertype is NamedTypeBuilder &&
- supertype.typeArguments != null) {
- for (int i = 0; i < supertype.typeArguments!.length; ++i) {
- supertype.typeArguments![i] = supertype.typeArguments![i]
- .clone(newTypes, this, currentTypeParameterScopeBuilder);
- }
- }
- if (mixin is NamedTypeBuilder && mixin.typeArguments != null) {
- for (int i = 0; i < mixin.typeArguments!.length; ++i) {
- mixin.typeArguments![i] = mixin.typeArguments![i]
- .clone(newTypes, this, currentTypeParameterScopeBuilder);
- }
- }
- for (NamedTypeBuilder newType in newTypes) {
- currentTypeParameterScopeBuilder
- .registerUnresolvedNamedType(newType);
- }
-
- TypeParameterScopeBuilder mixinDeclaration = this
- .endNestedDeclaration(
- TypeParameterScopeKind.unnamedMixinApplication,
- "mixin application");
- mixinDeclaration.resolveNamedTypes(applicationTypeVariables, this);
-
- applicationTypeArguments = <TypeBuilder>[];
- for (NominalVariableBuilder typeVariable in typeVariables) {
- applicationTypeArguments.add(
- new NamedTypeBuilderImpl.fromTypeDeclarationBuilder(
- // The type variable types passed as arguments to the
- // generic class representing the anonymous mixin
- // application should refer back to the type variables of
- // the class that extend the anonymous mixin application.
- typeVariable,
- const NullabilityBuilder.omitted(),
- fileUri: fileUri,
- charOffset: charOffset,
- instanceTypeVariableAccess:
- InstanceTypeVariableAccessState.Allowed));
- }
- }
- }
- final int computedStartCharOffset =
- !isNamedMixinApplication || metadata == null
- ? startCharOffset
- : metadata.first.charOffset;
-
- IndexedClass? referencesFromIndexedClass;
- if (indexedLibrary != null) {
- referencesFromIndexedClass =
- indexedLibrary!.lookupIndexedClass(fullname);
- }
-
- SourceClassBuilder application = new SourceClassBuilder(
- isNamedMixinApplication ? metadata : null,
- isNamedMixinApplication
- ? modifiers | namedMixinApplicationMask
- : abstractMask,
- fullname,
- applicationTypeVariables,
- isMixinDeclaration ? null : supertype,
- isNamedMixinApplication
- ? interfaces
- : isMixinDeclaration
- ? [supertype!, mixin]
- : null,
- null,
- // No `on` clause types.
- new Scope(
- kind: ScopeKind.declaration,
- local: <String, MemberBuilder>{},
- setters: <String, MemberBuilder>{},
- parent: scope.withTypeVariables(typeVariables),
- debugName: "mixin $fullname ",
- isModifiable: false),
- new ConstructorScope(fullname, <String, MemberBuilder>{}),
- this,
- <ConstructorReferenceBuilder>[],
- computedStartCharOffset,
- charOffset,
- charEndOffset,
- referencesFromIndexedClass,
- mixedInTypeBuilder: isMixinDeclaration ? null : mixin,
- isMacro: isNamedMixinApplication && isMacro,
- isSealed: isNamedMixinApplication && isSealed,
- isBase: isNamedMixinApplication && isBase,
- isInterface: isNamedMixinApplication && isInterface,
- isFinal: isNamedMixinApplication && isFinal,
- isAugmentation: isNamedMixinApplication && isAugmentation,
- isMixinClass: isNamedMixinApplication && isMixinClass);
- // TODO(ahe, kmillikin): Should always be true?
- // pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart can't
- // handle that :(
- application.cls.isAnonymousMixin = !isNamedMixinApplication;
- addBuilder(fullname, application, charOffset,
- getterReference: referencesFromIndexedClass?.cls.reference);
- supertype = new NamedTypeBuilderImpl.fromTypeDeclarationBuilder(
- application, const NullabilityBuilder.omitted(),
- arguments: applicationTypeArguments,
- fileUri: fileUri,
- charOffset: charOffset,
- instanceTypeVariableAccess:
- InstanceTypeVariableAccessState.Allowed);
- registerMixinApplication(application, mixin);
- }
- return supertype;
- } else {
- return supertype;
- }
- }
-
+ // TODO(johnniwinther): Move this to [SourceCompilationUnitImpl].
Map<SourceClassBuilder, TypeBuilder>? _mixinApplications = {};
- /// Registers that [mixinApplication] is a mixin application introduced by
- /// the [mixedInType] in a with-clause.
- ///
- /// This is used to check that super access in mixin declarations have a
- /// concrete target.
- void registerMixinApplication(
- SourceClassBuilder mixinApplication, TypeBuilder mixedInType) {
- assert(
- _mixinApplications != null, "Late registration of mixin application.");
- _mixinApplications![mixinApplication] = mixedInType;
- }
-
+ // TODO(johnniwinther): Move access to [_mixinApplications] to
+ // [SourceCompilationUnitImpl].
void takeMixinApplications(
Map<SourceClassBuilder, TypeBuilder> mixinApplications) {
assert(_mixinApplications != null,
@@ -3023,815 +3976,6 @@
}
}
- void addNamedMixinApplication(
- List<MetadataBuilder>? metadata,
- String name,
- List<NominalVariableBuilder>? typeVariables,
- int modifiers,
- TypeBuilder? supertype,
- MixinApplicationBuilder mixinApplication,
- List<TypeBuilder>? interfaces,
- int startCharOffset,
- int charOffset,
- int charEndOffset,
- {required bool isMacro,
- required bool isSealed,
- required bool isBase,
- required bool isInterface,
- required bool isFinal,
- required bool isAugmentation,
- required bool isMixinClass}) {
- // Nested declaration began in `OutlineBuilder.beginNamedMixinApplication`.
- endNestedDeclaration(TypeParameterScopeKind.namedMixinApplication, name)
- .resolveNamedTypes(typeVariables, this);
- supertype = _applyMixins(supertype, mixinApplication, startCharOffset,
- charOffset, charEndOffset, name, false,
- metadata: metadata,
- name: name,
- typeVariables: typeVariables,
- modifiers: modifiers,
- interfaces: interfaces,
- isMacro: isMacro,
- isSealed: isSealed,
- isBase: isBase,
- isInterface: isInterface,
- isFinal: isFinal,
- isAugmentation: isAugmentation,
- isMixinClass: isMixinClass)!;
- checkTypeVariables(typeVariables, supertype.declaration);
- }
-
- SourceFieldBuilder addField(
- List<MetadataBuilder>? metadata,
- int modifiers,
- bool isTopLevel,
- TypeBuilder type,
- String name,
- int charOffset,
- int charEndOffset,
- Token? initializerToken,
- bool hasInitializer,
- {Token? constInitializerToken}) {
- if (hasInitializer) {
- modifiers |= hasInitializerMask;
- }
- bool isLate = (modifiers & lateMask) != 0;
- bool isFinal = (modifiers & finalMask) != 0;
- bool isStatic = (modifiers & staticMask) != 0;
- bool isExternal = (modifiers & externalMask) != 0;
- final bool fieldIsLateWithLowering = isLate &&
- (loader.target.backendTarget.isLateFieldLoweringEnabled(
- hasInitializer: hasInitializer,
- isFinal: isFinal,
- isStatic: isTopLevel || isStatic) ||
- (loader.target.backendTarget.useStaticFieldLowering &&
- (isStatic || isTopLevel)));
-
- final bool isInstanceMember = currentTypeParameterScopeBuilder.kind !=
- TypeParameterScopeKind.library &&
- (modifiers & staticMask) == 0;
- final bool isExtensionMember = currentTypeParameterScopeBuilder.kind ==
- TypeParameterScopeKind.extensionDeclaration;
- final bool isExtensionTypeMember = currentTypeParameterScopeBuilder.kind ==
- TypeParameterScopeKind.extensionTypeDeclaration;
- ContainerType containerType =
- currentTypeParameterScopeBuilder.containerType;
- ContainerName? containerName =
- currentTypeParameterScopeBuilder.containerName;
-
- Reference? fieldReference;
- Reference? fieldGetterReference;
- Reference? fieldSetterReference;
- Reference? lateIsSetFieldReference;
- Reference? lateIsSetGetterReference;
- Reference? lateIsSetSetterReference;
- Reference? lateGetterReference;
- Reference? lateSetterReference;
-
- NameScheme nameScheme = new NameScheme(
- isInstanceMember: isInstanceMember,
- containerName: containerName,
- containerType: containerType,
- libraryName: indexedLibrary != null
- ? new LibraryName(indexedLibrary!.reference)
- : libraryName);
- IndexedContainer? indexedContainer = _indexedContainer ?? indexedLibrary;
- if (indexedContainer != null) {
- if ((isExtensionMember || isExtensionTypeMember) &&
- isInstanceMember &&
- isExternal) {
- /// An external extension (type) instance field is special. It is
- /// treated as an external getter/setter pair and is therefore encoded
- /// as a pair of top level methods using the extension instance member
- /// naming convention.
- fieldGetterReference = indexedContainer.lookupGetterReference(
- nameScheme.getProcedureMemberName(ProcedureKind.Getter, name).name);
- fieldSetterReference = indexedContainer.lookupGetterReference(
- nameScheme.getProcedureMemberName(ProcedureKind.Setter, name).name);
- } else if (isExtensionTypeMember && isInstanceMember) {
- Name nameToLookup = nameScheme
- .getFieldMemberName(FieldNameType.RepresentationField, name,
- isSynthesized: true)
- .name;
- fieldGetterReference =
- indexedContainer.lookupGetterReference(nameToLookup);
- } else {
- Name nameToLookup = nameScheme
- .getFieldMemberName(FieldNameType.Field, name,
- isSynthesized: fieldIsLateWithLowering)
- .name;
- fieldReference = indexedContainer.lookupFieldReference(nameToLookup);
- fieldGetterReference =
- indexedContainer.lookupGetterReference(nameToLookup);
- fieldSetterReference =
- indexedContainer.lookupSetterReference(nameToLookup);
- }
-
- if (fieldIsLateWithLowering) {
- Name lateIsSetName = nameScheme
- .getFieldMemberName(FieldNameType.IsSetField, name,
- isSynthesized: fieldIsLateWithLowering)
- .name;
- lateIsSetFieldReference =
- indexedContainer.lookupFieldReference(lateIsSetName);
- lateIsSetGetterReference =
- indexedContainer.lookupGetterReference(lateIsSetName);
- lateIsSetSetterReference =
- indexedContainer.lookupSetterReference(lateIsSetName);
- lateGetterReference = indexedContainer.lookupGetterReference(nameScheme
- .getFieldMemberName(FieldNameType.Getter, name,
- isSynthesized: fieldIsLateWithLowering)
- .name);
- lateSetterReference = indexedContainer.lookupSetterReference(nameScheme
- .getFieldMemberName(FieldNameType.Setter, name,
- isSynthesized: fieldIsLateWithLowering)
- .name);
- }
- }
-
- SourceFieldBuilder fieldBuilder = new SourceFieldBuilder(
- metadata,
- type,
- name,
- modifiers,
- isTopLevel,
- this,
- charOffset,
- charEndOffset,
- nameScheme,
- fieldReference: fieldReference,
- fieldGetterReference: fieldGetterReference,
- fieldSetterReference: fieldSetterReference,
- lateIsSetFieldReference: lateIsSetFieldReference,
- lateIsSetGetterReference: lateIsSetGetterReference,
- lateIsSetSetterReference: lateIsSetSetterReference,
- lateGetterReference: lateGetterReference,
- lateSetterReference: lateSetterReference,
- initializerToken: initializerToken,
- constInitializerToken: constInitializerToken);
- addBuilder(name, fieldBuilder, charOffset,
- getterReference: fieldGetterReference,
- setterReference: fieldSetterReference);
- return fieldBuilder;
- }
-
- void addPrimaryConstructorField(
- {required List<MetadataBuilder>? metadata,
- required TypeBuilder type,
- required String name,
- required int charOffset}) {
- addField(
- metadata,
- finalMask,
- /* isTopLevel = */ false,
- type,
- name,
- /* charOffset = */ charOffset,
- /* charEndOffset = */ charOffset,
- /* initializerToken = */ null,
- /* hasInitializer = */ false);
- }
-
- void addPrimaryConstructor(
- {required OffsetMap offsetMap,
- required Token beginToken,
- required String constructorName,
- required List<NominalVariableBuilder>? typeVariables,
- required List<FormalParameterBuilder>? formals,
- required int charOffset,
- required bool isConst}) {
- SourceFunctionBuilder builder = _addConstructor(
- null,
- isConst ? constMask : 0,
- constructorName,
- typeVariables,
- formals,
- /* startCharOffset = */ charOffset,
- charOffset,
- /* charOpenParenOffset = */ charOffset,
- /* charEndOffset = */ charOffset,
- /* nativeMethodName = */ null,
- forAbstractClassOrMixin: false);
- offsetMap.registerPrimaryConstructor(beginToken, builder);
- }
-
- void addConstructor(
- OffsetMap offsetMap,
- List<MetadataBuilder>? metadata,
- int modifiers,
- Identifier identifier,
- String constructorName,
- List<NominalVariableBuilder>? typeVariables,
- List<FormalParameterBuilder>? formals,
- int startCharOffset,
- int charOffset,
- int charOpenParenOffset,
- int charEndOffset,
- String? nativeMethodName,
- {Token? beginInitializers,
- required bool forAbstractClassOrMixin}) {
- SourceFunctionBuilder builder = _addConstructor(
- metadata,
- modifiers,
- constructorName,
- typeVariables,
- formals,
- startCharOffset,
- charOffset,
- charOpenParenOffset,
- charEndOffset,
- nativeMethodName,
- beginInitializers: beginInitializers,
- forAbstractClassOrMixin: forAbstractClassOrMixin);
- offsetMap.registerConstructor(identifier, builder);
- }
-
- SourceFunctionBuilder _addConstructor(
- List<MetadataBuilder>? metadata,
- int modifiers,
- String constructorName,
- List<NominalVariableBuilder>? typeVariables,
- List<FormalParameterBuilder>? formals,
- int startCharOffset,
- int charOffset,
- int charOpenParenOffset,
- int charEndOffset,
- String? nativeMethodName,
- {Token? beginInitializers,
- required bool forAbstractClassOrMixin}) {
- ContainerType containerType =
- currentTypeParameterScopeBuilder.containerType;
- ContainerName? containerName =
- currentTypeParameterScopeBuilder.containerName;
- NameScheme nameScheme = new NameScheme(
- isInstanceMember: false,
- containerName: containerName,
- containerType: containerType,
- libraryName: indexedLibrary != null
- ? new LibraryName(indexedLibrary!.library.reference)
- : libraryName);
-
- Reference? constructorReference;
- Reference? tearOffReference;
-
- IndexedContainer? indexedContainer = _indexedContainer;
- if (indexedContainer != null) {
- constructorReference = indexedContainer.lookupConstructorReference(
- nameScheme
- .getConstructorMemberName(constructorName, isTearOff: false)
- .name);
- tearOffReference = indexedContainer.lookupGetterReference(nameScheme
- .getConstructorMemberName(constructorName, isTearOff: true)
- .name);
- }
- AbstractSourceConstructorBuilder constructorBuilder;
-
- if (currentTypeParameterScopeBuilder.kind ==
- TypeParameterScopeKind.extensionTypeDeclaration) {
- constructorBuilder = new SourceExtensionTypeConstructorBuilder(
- metadata,
- modifiers & ~abstractMask,
- addInferableType(),
- constructorName,
- typeVariables,
- formals,
- this,
- startCharOffset,
- charOffset,
- charOpenParenOffset,
- charEndOffset,
- constructorReference,
- tearOffReference,
- nameScheme,
- nativeMethodName: nativeMethodName,
- forAbstractClassOrEnumOrMixin: forAbstractClassOrMixin);
- } else {
- constructorBuilder = new DeclaredSourceConstructorBuilder(
- metadata,
- modifiers & ~abstractMask,
- addInferableType(),
- constructorName,
- typeVariables,
- formals,
- this,
- startCharOffset,
- charOffset,
- charOpenParenOffset,
- charEndOffset,
- constructorReference,
- tearOffReference,
- nameScheme,
- nativeMethodName: nativeMethodName,
- forAbstractClassOrEnumOrMixin: forAbstractClassOrMixin);
- }
- checkTypeVariables(typeVariables, constructorBuilder);
- // TODO(johnniwinther): There is no way to pass the tear off reference here.
- addBuilder(constructorName, constructorBuilder, charOffset,
- getterReference: constructorReference);
- if (nativeMethodName != null) {
- addNativeMethod(constructorBuilder);
- }
- if (constructorBuilder.isConst) {
- currentTypeParameterScopeBuilder.declaresConstConstructor = true;
- }
- if (constructorBuilder.isConst ||
- libraryFeatures.superParameters.isEnabled) {
- // const constructors will have their initializers compiled and written
- // into the outline. In case of super-parameters language feature, the
- // super initializers are required to infer the types of super parameters.
- constructorBuilder.beginInitializers =
- beginInitializers ?? new Token.eof(-1);
- }
- return constructorBuilder;
- }
-
- void addProcedure(
- OffsetMap offsetMap,
- List<MetadataBuilder>? metadata,
- int modifiers,
- TypeBuilder? returnType,
- Identifier identifier,
- String name,
- List<NominalVariableBuilder>? typeVariables,
- List<FormalParameterBuilder>? formals,
- ProcedureKind kind,
- int startCharOffset,
- int charOffset,
- int charOpenParenOffset,
- int charEndOffset,
- String? nativeMethodName,
- AsyncMarker asyncModifier,
- {required bool isInstanceMember,
- required bool isExtensionMember,
- required bool isExtensionTypeMember}) {
- assert(!isExtensionMember ||
- currentTypeParameterScopeBuilder.kind ==
- TypeParameterScopeKind.extensionDeclaration);
- assert(!isExtensionTypeMember ||
- currentTypeParameterScopeBuilder.kind ==
- TypeParameterScopeKind.extensionTypeDeclaration);
- ContainerType containerType =
- currentTypeParameterScopeBuilder.containerType;
- ContainerName? containerName =
- currentTypeParameterScopeBuilder.containerName;
- NameScheme nameScheme = new NameScheme(
- containerName: containerName,
- containerType: containerType,
- isInstanceMember: isInstanceMember,
- libraryName: indexedLibrary != null
- ? new LibraryName(indexedLibrary!.library.reference)
- : libraryName);
-
- if (returnType == null) {
- if (kind == ProcedureKind.Operator &&
- identical(name, indexSetName.text)) {
- returnType = addVoidType(charOffset);
- } else if (kind == ProcedureKind.Setter) {
- returnType = addVoidType(charOffset);
- }
- }
- Reference? procedureReference;
- Reference? tearOffReference;
- IndexedContainer? indexedContainer = _indexedContainer ?? indexedLibrary;
-
- bool isAugmentation = isAugmenting && (modifiers & augmentMask) != 0;
- if (indexedContainer != null && !isAugmentation) {
- Name nameToLookup = nameScheme.getProcedureMemberName(kind, name).name;
- if (kind == ProcedureKind.Setter) {
- if ((isExtensionMember || isExtensionTypeMember) && isInstanceMember) {
- // Extension (type) instance setters are encoded as methods.
- procedureReference =
- indexedContainer.lookupGetterReference(nameToLookup);
- } else {
- procedureReference =
- indexedContainer.lookupSetterReference(nameToLookup);
- }
- } else {
- procedureReference =
- indexedContainer.lookupGetterReference(nameToLookup);
- if ((isExtensionMember || isExtensionTypeMember) &&
- kind == ProcedureKind.Method) {
- tearOffReference = indexedContainer.lookupGetterReference(nameScheme
- .getProcedureMemberName(ProcedureKind.Getter, name)
- .name);
- }
- }
- }
- SourceProcedureBuilder procedureBuilder = new SourceProcedureBuilder(
- metadata,
- modifiers,
- returnType ?? addInferableType(),
- name,
- typeVariables,
- formals,
- kind,
- this,
- startCharOffset,
- charOffset,
- charOpenParenOffset,
- charEndOffset,
- procedureReference,
- tearOffReference,
- asyncModifier,
- nameScheme,
- nativeMethodName: nativeMethodName);
- checkTypeVariables(typeVariables, procedureBuilder);
- addBuilder(name, procedureBuilder, charOffset,
- getterReference: procedureReference);
- if (nativeMethodName != null) {
- addNativeMethod(procedureBuilder);
- }
- offsetMap.registerProcedure(identifier, procedureBuilder);
- }
-
- void addFactoryMethod(
- OffsetMap offsetMap,
- List<MetadataBuilder>? metadata,
- int modifiers,
- Identifier identifier,
- List<FormalParameterBuilder>? formals,
- ConstructorReferenceBuilder? redirectionTarget,
- int startCharOffset,
- int charOffset,
- int charOpenParenOffset,
- int charEndOffset,
- String? nativeMethodName,
- AsyncMarker asyncModifier) {
- TypeBuilder returnType;
- if (currentTypeParameterScopeBuilder.parent?.kind ==
- TypeParameterScopeKind.extensionDeclaration) {
- // Make the synthesized return type invalid for extensions.
- String name = currentTypeParameterScopeBuilder.parent!.name;
- returnType = new NamedTypeBuilderImpl.forInvalidType(
- currentTypeParameterScopeBuilder.parent!.name,
- const NullabilityBuilder.omitted(),
- messageExtensionDeclaresConstructor.withLocation(
- fileUri, charOffset, name.length));
- } else {
- returnType = addNamedType(
- new SyntheticTypeName(
- currentTypeParameterScopeBuilder.parent!.name, charOffset),
- const NullabilityBuilder.omitted(),
- <TypeBuilder>[],
- charOffset,
- instanceTypeVariableAccess: InstanceTypeVariableAccessState.Allowed);
- }
- // Nested declaration began in `OutlineBuilder.beginFactoryMethod`.
- TypeParameterScopeBuilder factoryDeclaration = endNestedDeclaration(
- TypeParameterScopeKind.factoryMethod, "#factory_method");
-
- // Prepare the simple procedure name.
- String procedureName;
- String? constructorName =
- computeAndValidateConstructorName(identifier, isFactory: true);
- if (constructorName != null) {
- procedureName = constructorName;
- } else {
- procedureName = identifier.name;
- }
-
- ContainerType containerType =
- currentTypeParameterScopeBuilder.containerType;
- ContainerName? containerName =
- currentTypeParameterScopeBuilder.containerName;
-
- NameScheme procedureNameScheme = new NameScheme(
- containerName: containerName,
- containerType: containerType,
- isInstanceMember: false,
- libraryName: indexedLibrary != null
- ? new LibraryName(
- (_indexedContainer ?? indexedLibrary)!.library.reference)
- : libraryName);
-
- Reference? constructorReference;
- Reference? tearOffReference;
- if (_indexedContainer != null) {
- constructorReference = _indexedContainer!.lookupConstructorReference(
- procedureNameScheme
- .getConstructorMemberName(procedureName, isTearOff: false)
- .name);
- tearOffReference = _indexedContainer!.lookupGetterReference(
- procedureNameScheme
- .getConstructorMemberName(procedureName, isTearOff: true)
- .name);
- } else if (indexedLibrary != null) {
- constructorReference = indexedLibrary!.lookupGetterReference(
- procedureNameScheme
- .getConstructorMemberName(procedureName, isTearOff: false)
- .name);
- tearOffReference = indexedLibrary!.lookupGetterReference(
- procedureNameScheme
- .getConstructorMemberName(procedureName, isTearOff: true)
- .name);
- }
-
- SourceFactoryBuilder procedureBuilder;
- List<NominalVariableBuilder> typeVariables;
- if (redirectionTarget != null) {
- procedureBuilder = new RedirectingFactoryBuilder(
- metadata,
- staticMask | modifiers,
- returnType,
- procedureName,
- typeVariables = copyTypeVariables(
- currentTypeParameterScopeBuilder.typeVariables ??
- const <NominalVariableBuilder>[],
- factoryDeclaration,
- kind: TypeVariableKind.function),
- formals,
- this,
- startCharOffset,
- charOffset,
- charOpenParenOffset,
- charEndOffset,
- constructorReference,
- tearOffReference,
- procedureNameScheme,
- nativeMethodName,
- redirectionTarget);
- } else {
- procedureBuilder = new SourceFactoryBuilder(
- metadata,
- staticMask | modifiers,
- returnType,
- procedureName,
- typeVariables = copyTypeVariables(
- currentTypeParameterScopeBuilder.typeVariables ??
- const <NominalVariableBuilder>[],
- factoryDeclaration,
- kind: TypeVariableKind.function),
- formals,
- this,
- startCharOffset,
- charOffset,
- charOpenParenOffset,
- charEndOffset,
- constructorReference,
- tearOffReference,
- asyncModifier,
- procedureNameScheme,
- nativeMethodName: nativeMethodName);
- }
-
- TypeParameterScopeBuilder savedDeclaration =
- currentTypeParameterScopeBuilder;
- currentTypeParameterScopeBuilder = factoryDeclaration;
- if (returnType is NamedTypeBuilderImpl && !typeVariables.isEmpty) {
- returnType.typeArguments =
- new List<TypeBuilder>.generate(typeVariables.length, (int index) {
- return addNamedType(
- new SyntheticTypeName(
- typeVariables[index].name, procedureBuilder.charOffset),
- const NullabilityBuilder.omitted(),
- null,
- procedureBuilder.charOffset,
- instanceTypeVariableAccess:
- InstanceTypeVariableAccessState.Allowed);
- });
- }
- currentTypeParameterScopeBuilder = savedDeclaration;
-
- factoryDeclaration.resolveNamedTypes(procedureBuilder.typeVariables, this);
- addBuilder(procedureName, procedureBuilder, charOffset,
- getterReference: constructorReference);
- if (nativeMethodName != null) {
- addNativeMethod(procedureBuilder);
- }
- offsetMap.registerConstructor(identifier, procedureBuilder);
- }
-
- void addEnum(
- OffsetMap offsetMap,
- List<MetadataBuilder>? metadata,
- Identifier identifier,
- List<NominalVariableBuilder>? typeVariables,
- MixinApplicationBuilder? supertypeBuilder,
- List<TypeBuilder>? interfaceBuilders,
- List<EnumConstantInfo?>? enumConstantInfos,
- int startCharOffset,
- int charEndOffset) {
- String name = identifier.name;
- int charOffset = identifier.nameOffset;
-
- IndexedClass? referencesFromIndexedClass;
- if (indexedLibrary != null) {
- referencesFromIndexedClass = indexedLibrary!.lookupIndexedClass(name);
- }
- // Nested declaration began in `OutlineBuilder.beginEnum`.
- TypeParameterScopeBuilder declaration =
- endNestedDeclaration(TypeParameterScopeKind.enumDeclaration, name)
- ..resolveNamedTypes(typeVariables, this);
- Map<String, Builder> members = declaration.members!;
- Map<String, MemberBuilder> constructors = declaration.constructors!;
- Map<String, MemberBuilder> setters = declaration.setters!;
-
- SourceEnumBuilder enumBuilder = new SourceEnumBuilder(
- metadata,
- name,
- typeVariables,
- _applyMixins(
- loader.target.underscoreEnumType,
- supertypeBuilder,
- startCharOffset,
- charOffset,
- charEndOffset,
- name,
- /* isMixinDeclaration = */
- false,
- typeVariables: typeVariables,
- isMacro: false,
- isSealed: false,
- isBase: false,
- isInterface: false,
- isFinal: false,
- isAugmentation: false,
- isMixinClass: false),
- interfaceBuilders,
- enumConstantInfos,
- this,
- new List<ConstructorReferenceBuilder>.of(constructorReferences),
- startCharOffset,
- charOffset,
- charEndOffset,
- referencesFromIndexedClass,
- new Scope(
- kind: ScopeKind.declaration,
- local: members,
- setters: setters,
- parent: scope.withTypeVariables(typeVariables),
- debugName: "enum $name",
- isModifiable: false),
- new ConstructorScope(name, constructors),
- loader.coreLibrary);
- constructorReferences.clear();
-
- Map<String, NominalVariableBuilder>? typeVariablesByName =
- checkTypeVariables(typeVariables, enumBuilder);
-
- void setParent(MemberBuilder? member) {
- while (member != null) {
- member.parent = enumBuilder;
- member = member.next as MemberBuilder?;
- }
- }
-
- void setParentAndCheckConflicts(String name, Builder member) {
- if (typeVariablesByName != null) {
- NominalVariableBuilder? tv = typeVariablesByName[name];
- if (tv != null) {
- enumBuilder.addProblem(
- templateConflictsWithTypeVariable.withArguments(name),
- member.charOffset,
- name.length,
- context: [
- messageConflictsWithTypeVariableCause.withLocation(
- tv.fileUri!, tv.charOffset, name.length)
- ]);
- }
- }
- setParent(member as MemberBuilder);
- }
-
- members.forEach(setParentAndCheckConflicts);
- constructors.forEach(setParentAndCheckConflicts);
- setters.forEach(setParentAndCheckConflicts);
- addBuilder(name, enumBuilder, charOffset,
- getterReference: referencesFromIndexedClass?.cls.reference);
-
- offsetMap.registerNamedDeclaration(identifier, enumBuilder);
- }
-
- void addFunctionTypeAlias(
- List<MetadataBuilder>? metadata,
- String name,
- List<NominalVariableBuilder>? typeVariables,
- TypeBuilder type,
- int charOffset) {
- if (typeVariables != null) {
- for (NominalVariableBuilder typeVariable in typeVariables) {
- typeVariable.varianceCalculationValue =
- VarianceCalculationValue.pending;
- }
- }
- Typedef? referenceFrom = indexedLibrary?.lookupTypedef(name);
- TypeAliasBuilder typedefBuilder = new SourceTypeAliasBuilder(
- metadata, name, typeVariables, type, this, charOffset,
- referenceFrom: referenceFrom);
- checkTypeVariables(typeVariables, typedefBuilder);
- // Nested declaration began in `OutlineBuilder.beginFunctionTypeAlias`.
- endNestedDeclaration(TypeParameterScopeKind.typedef, "#typedef")
- .resolveNamedTypes(typeVariables, this);
- addBuilder(name, typedefBuilder, charOffset,
- getterReference: referenceFrom?.reference);
- }
-
- FunctionTypeBuilder addFunctionType(
- TypeBuilder returnType,
- List<StructuralVariableBuilder>? structuralVariableBuilders,
- List<FormalParameterBuilder>? formals,
- NullabilityBuilder nullabilityBuilder,
- Uri fileUri,
- int charOffset,
- {required bool hasFunctionFormalParameterSyntax}) {
- FunctionTypeBuilder builder = new FunctionTypeBuilderImpl(
- returnType,
- structuralVariableBuilders,
- formals,
- nullabilityBuilder,
- fileUri,
- charOffset,
- hasFunctionFormalParameterSyntax: hasFunctionFormalParameterSyntax);
- checkStructuralVariables(structuralVariableBuilders, null);
- if (structuralVariableBuilders != null) {
- for (StructuralVariableBuilder builder in structuralVariableBuilders) {
- if (builder.metadata != null) {
- if (!libraryFeatures.genericMetadata.isEnabled) {
- addProblem(messageAnnotationOnFunctionTypeTypeVariable,
- builder.charOffset, builder.name.length, builder.fileUri);
- }
- }
- }
- }
- // Nested declaration began in `OutlineBuilder.beginFunctionType` or
- // `OutlineBuilder.beginFunctionTypedFormalParameter`.
- endNestedDeclaration(TypeParameterScopeKind.functionType, "#function_type")
- .resolveNamedTypesWithStructuralVariables(
- structuralVariableBuilders, this);
- return builder;
- }
-
- FormalParameterBuilder addFormalParameter(
- List<MetadataBuilder>? metadata,
- FormalParameterKind kind,
- int modifiers,
- TypeBuilder type,
- String name,
- bool hasThis,
- bool hasSuper,
- int charOffset,
- Token? initializerToken) {
- assert(!hasThis || !hasSuper,
- "Formal parameter '${name}' has both 'this' and 'super' prefixes.");
- if (hasThis) {
- modifiers |= initializingFormalMask;
- }
- if (hasSuper) {
- modifiers |= superInitializingFormalMask;
- }
- FormalParameterBuilder formal = new FormalParameterBuilder(
- kind, modifiers, type, name, this, charOffset,
- fileUri: fileUri,
- hasImmediatelyDeclaredInitializer: initializerToken != null)
- ..initializerToken = initializerToken;
- return formal;
- }
-
- NominalVariableBuilder addNominalTypeVariable(List<MetadataBuilder>? metadata,
- String name, TypeBuilder? bound, int charOffset, Uri fileUri,
- {required TypeVariableKind kind}) {
- NominalVariableBuilder builder = new NominalVariableBuilder(
- name, this, charOffset, fileUri,
- bound: bound, metadata: metadata, kind: kind);
-
- unboundNominalVariables.add(builder);
- return builder;
- }
-
- StructuralVariableBuilder addStructuralTypeVariable(
- List<MetadataBuilder>? metadata,
- String name,
- TypeBuilder? bound,
- int charOffset,
- Uri fileUri) {
- StructuralVariableBuilder builder = new StructuralVariableBuilder(
- name, this, charOffset, fileUri,
- bound: bound, metadata: metadata);
-
- unboundStructuralVariables.add(builder);
- return builder;
- }
-
BodyBuilderContext createBodyBuilderContext(
{required bool inOutlineBuildingPhase,
required bool inMetadata,
@@ -4238,10 +4382,6 @@
return count;
}
- void addNativeMethod(SourceFunctionBuilder method) {
- nativeMethods.add(method);
- }
-
int finishNativeMethods() {
int count = 0;
@@ -4261,36 +4401,6 @@
return count;
}
- /// Creates a copy of [original] into the scope of [declaration].
- ///
- /// This is used for adding copies of class type parameters to factory
- /// methods and unnamed mixin applications, and for adding copies of
- /// extension type parameters to extension instance methods.
- ///
- /// If [synthesizeTypeParameterNames] is `true` the names of the
- /// [TypeParameter] are prefix with '#' to indicate that their synthesized.
- List<NominalVariableBuilder> copyTypeVariables(
- List<NominalVariableBuilder> original,
- TypeParameterScopeBuilder declaration,
- {required TypeVariableKind kind}) {
- List<NamedTypeBuilder> newTypes = <NamedTypeBuilder>[];
- List<NominalVariableBuilder> copy = <NominalVariableBuilder>[];
- for (NominalVariableBuilder variable in original) {
- NominalVariableBuilder newVariable = new NominalVariableBuilder(
- variable.name, this, variable.charOffset, variable.fileUri,
- bound: variable.bound?.clone(newTypes, this, declaration),
- kind: kind,
- variableVariance:
- variable.parameter.isLegacyCovariant ? null : variable.variance);
- copy.add(newVariable);
- unboundNominalVariables.add(newVariable);
- }
- for (NamedTypeBuilder newType in newTypes) {
- declaration.registerUnresolvedNamedType(newType);
- }
- return copy;
- }
-
List<StructuralVariableBuilder> copyStructuralVariables(
List<StructuralVariableBuilder> original,
TypeParameterScopeBuilder declaration,
@@ -5534,37 +5644,6 @@
_extensionsInScope = null;
}
- /// Call this when entering a class, mixin, enum, or extension type
- /// declaration.
- ///
- /// This is done to set up the current [_indexedContainer] used to lookup
- /// references of members from a previous incremental compilation.
- ///
- /// Called in `OutlineBuilder.beginClassDeclaration`,
- /// `OutlineBuilder.beginEnum`, `OutlineBuilder.beginMixinDeclaration` and
- /// `OutlineBuilder.beginExtensionTypeDeclaration`.
- void beginIndexedContainer(String name,
- {required bool isExtensionTypeDeclaration}) {
- if (indexedLibrary != null) {
- if (isExtensionTypeDeclaration) {
- _indexedContainer =
- indexedLibrary!.lookupIndexedExtensionTypeDeclaration(name);
- } else {
- _indexedContainer = indexedLibrary!.lookupIndexedClass(name);
- }
- }
- }
-
- /// Call this when leaving a class, mixin, enum, or extension type
- /// declaration.
- ///
- /// Called in `OutlineBuilder.endClassDeclaration`,
- /// `OutlineBuilder.endEnum`, `OutlineBuilder.endMixinDeclaration` and
- /// `OutlineBuilder.endExtensionTypeDeclaration`.
- void endIndexedContainer() {
- _indexedContainer = null;
- }
-
void registerPendingNullability(
Uri fileUri, int charOffset, TypeParameterType type) {
_pendingNullabilities
@@ -6507,12 +6586,4 @@
final CompilationUnit compilationUnit;
Part(this.offset, this.compilationUnit);
-
- OffsetMap get offsetMap {
- if (compilationUnit is SourceCompilationUnit) {
- return (compilationUnit as SourceCompilationUnit).offsetMap;
- }
- assert(false, "No offset map for $compilationUnit.");
- return new OffsetMap(compilationUnit.fileUri);
- }
}
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 2545c9e..b5c9bff 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -156,8 +156,8 @@
List<SourceLibraryBuilder>? _sourceLibraryBuilders;
- final Queue<SourceLibraryBuilder> _unparsedLibraries =
- new Queue<SourceLibraryBuilder>();
+ final Queue<SourceCompilationUnit> _unparsedLibraries =
+ new Queue<SourceCompilationUnit>();
final List<Library> libraries = <Library>[];
@@ -523,7 +523,7 @@
if (uri.isScheme("dart")) {
target.readPatchFiles(libraryBuilder);
}
- _unparsedLibraries.addLast(libraryBuilder);
+ _unparsedLibraries.addLast(libraryBuilder.compilationUnit);
return libraryBuilder;
}
@@ -876,8 +876,9 @@
/// part of the error message.
Set<SourceLibraryBuilder> _unavailableDartLibraries = {};
- Future<Token> tokenize(SourceLibraryBuilder libraryBuilder,
+ Future<Token> tokenize(SourceCompilationUnit compilationUnit,
{bool suppressLexicalErrors = false}) async {
+ SourceLibraryBuilder libraryBuilder = compilationUnit.sourceLibraryBuilder;
target.benchmarker?.beginSubdivide(BenchmarkSubdivides.tokenize);
Uri fileUri = libraryBuilder.fileUri;
@@ -1040,26 +1041,26 @@
_typeInferenceEngine!.typeDependencies[member] = typeDependency;
}
- /// Registers the [library] as unparsed with the given [source] code.
+ /// Registers the [compilationUnit] as unparsed with the given [source] code.
///
/// This is used for creating synthesized augmentation libraries.
void registerUnparsedLibrarySource(
- SourceLibraryBuilder library, String source) {
+ SourceCompilationUnit compilationUnit, String source) {
List<int> codeUnits = source.codeUnits;
Uint8List bytes = new Uint8List(codeUnits.length + 1);
bytes.setRange(0, codeUnits.length, codeUnits);
- sourceBytes[library.fileUri] = bytes;
- _unparsedLibraries.addLast(library);
+ sourceBytes[compilationUnit.fileUri] = bytes;
+ _unparsedLibraries.addLast(compilationUnit);
}
/// Runs the [OutlineBuilder] on the source of all [_unparsedLibraries].
Future<void> buildOutlines() async {
_ensureCoreLibrary();
while (_unparsedLibraries.isNotEmpty) {
- SourceLibraryBuilder library = _unparsedLibraries.removeFirst();
+ SourceCompilationUnit compilationUnit = _unparsedLibraries.removeFirst();
currentUriForCrashReporting =
- new UriOffset(library.importUri, TreeNode.noOffset);
- await buildOutline(library);
+ new UriOffset(compilationUnit.importUri, TreeNode.noOffset);
+ await buildOutline(compilationUnit);
}
currentUriForCrashReporting = null;
logSummary(outlineSummaryTemplate);
@@ -1150,14 +1151,14 @@
return bytes.sublist(0, bytes.length - 1);
}
- Future<Null> buildOutline(SourceLibraryBuilder library) async {
- Token tokens = await tokenize(library);
- OffsetMap offsetMap = new OffsetMap(library.fileUri);
- OutlineBuilder listener = new OutlineBuilder(library, offsetMap);
+ Future<Null> buildOutline(SourceCompilationUnit compilationUnit) async {
+ Token tokens = await tokenize(compilationUnit);
+ OffsetMap offsetMap = new OffsetMap(compilationUnit.fileUri);
+ OutlineBuilder listener = new OutlineBuilder(compilationUnit, offsetMap);
new ClassMemberParser(listener,
- allowPatterns: library.libraryFeatures.patterns.isEnabled)
+ allowPatterns: compilationUnit.libraryFeatures.patterns.isEnabled)
.parseUnit(tokens);
- library.offsetMap = offsetMap;
+ compilationUnit.offsetMap = offsetMap;
}
/// Builds all the method bodies found in the given [library].
@@ -1176,7 +1177,8 @@
// We tokenize source files twice to keep memory usage low. This is the
// second time, and the first time was in [buildOutline] above. So this
// time we suppress lexical errors.
- Token tokens = await tokenize(library, suppressLexicalErrors: true);
+ SourceCompilationUnit compilationUnit = library.compilationUnit;
+ Token tokens = await tokenize(compilationUnit, suppressLexicalErrors: true);
if (target.benchmarker != null) {
// When benchmarking we do extra parsing on it's own to get a timing of
@@ -1204,17 +1206,20 @@
}
}
- DietListener listener = createDietListener(library, library.offsetMap);
+ DietListener listener =
+ createDietListener(library, compilationUnit.offsetMap);
DietParser parser = new DietParser(listener,
allowPatterns: library.libraryFeatures.patterns.isEnabled);
parser.parseUnit(tokens);
for (Part part in library.parts) {
assert(part.compilationUnit.partOfLibrary == library,
"Part ${part.compilationUnit} is not part of ${library}.");
- Token tokens = await tokenize(
- (part.compilationUnit as SourceCompilationUnit).sourceLibraryBuilder,
- suppressLexicalErrors: true);
- DietListener listener = createDietListener(library, part.offsetMap);
+ SourceCompilationUnit compilationUnit =
+ part.compilationUnit as SourceCompilationUnit;
+ Token tokens =
+ await tokenize(compilationUnit, suppressLexicalErrors: true);
+ DietListener listener =
+ createDietListener(library, compilationUnit.offsetMap);
DietParser parser = new DietParser(listener,
allowPatterns: library.libraryFeatures.patterns.isEnabled);
parser.parseUnit(tokens);
@@ -1227,7 +1232,8 @@
bool isClassInstanceMember,
FunctionNode parameters,
VariableDeclaration? extensionThis) async {
- Token token = await tokenize(libraryBuilder, suppressLexicalErrors: false);
+ Token token = await tokenize(libraryBuilder.compilationUnit,
+ suppressLexicalErrors: false);
DietListener dietListener = createDietListener(
libraryBuilder,
// Expression compilation doesn't build an outline, and thus doesn't
diff --git a/pkg/front_end/test/comments_on_certain_arguments_tool.dart b/pkg/front_end/test/comments_on_certain_arguments_tool.dart
index dfc2a3a..2a9d482 100644
--- a/pkg/front_end/test/comments_on_certain_arguments_tool.dart
+++ b/pkg/front_end/test/comments_on_certain_arguments_tool.dart
@@ -3,51 +3,34 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:convert' show utf8;
-
import 'dart:io'
show Directory, File, FileSystemEntity, exitCode, stdin, stdout;
import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
-
import 'package:_fe_analyzer_shared/src/scanner/token.dart'
show CommentToken, Token;
-
import 'package:front_end/src/api_prototype/compiler_options.dart' as api
show CompilerOptions, DiagnosticMessage;
-
import 'package:front_end/src/api_prototype/file_system.dart' as api
show FileSystem;
import 'package:front_end/src/api_prototype/incremental_kernel_generator.dart'
show IncrementalCompilerResult;
-
import 'package:front_end/src/base/processed_options.dart'
show ProcessedOptions;
-
import 'package:front_end/src/compute_platform_binaries_location.dart'
show computePlatformBinariesLocation;
-
+import 'package:front_end/src/fasta/builder/library_builder.dart';
import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
-
import 'package:front_end/src/fasta/dill/dill_target.dart' show DillTarget;
-
import 'package:front_end/src/fasta/incremental_compiler.dart'
show IncrementalCompiler, IncrementalKernelTarget;
-
import 'package:front_end/src/fasta/kernel/kernel_target.dart'
show KernelTarget;
-
-import 'package:front_end/src/fasta/source/source_library_builder.dart'
- show SourceLibraryBuilder;
-
import 'package:front_end/src/fasta/source/source_loader.dart'
show SourceLoader;
-
import 'package:front_end/src/fasta/uri_translator.dart' show UriTranslator;
-
import 'package:kernel/ast.dart';
-
import 'package:kernel/target/targets.dart' show TargetFlags;
-
import "package:vm/modular/target/vm.dart" show VmTarget;
import "utils/io_utils.dart" show computeRepoDirUri;
@@ -414,11 +397,11 @@
: super(fileSystem, includeComments, target);
@override
- Future<Token> tokenize(SourceLibraryBuilder library,
+ Future<Token> tokenize(SourceCompilationUnit sourceCompilationUnit,
{bool suppressLexicalErrors = false}) async {
- Token result = await super
- .tokenize(library, suppressLexicalErrors: suppressLexicalErrors);
- cache[library.fileUri] = result;
+ Token result = await super.tokenize(sourceCompilationUnit,
+ suppressLexicalErrors: suppressLexicalErrors);
+ cache[sourceCompilationUnit.fileUri] = result;
return result;
}
}
diff --git a/pkg/front_end/tool/dart_doctest_impl.dart b/pkg/front_end/tool/dart_doctest_impl.dart
index 76379a4..8663c63 100644
--- a/pkg/front_end/tool/dart_doctest_impl.dart
+++ b/pkg/front_end/tool/dart_doctest_impl.dart
@@ -847,7 +847,7 @@
combinator.fileOffset, libraryBuilder.fileUri));
}
- dartDocTestLibrary.addImport(
+ dartDocTestLibrary.compilationUnit.addImport(
metadata: null,
isAugmentationImport: false,
uri: dependency.importedLibraryReference.asLibrary.importUri
@@ -862,7 +862,7 @@
importIndex: -1);
}
- dartDocTestLibrary.addImport(
+ dartDocTestLibrary.compilationUnit.addImport(
metadata: null,
isAugmentationImport: false,
uri: libraryBuilder.importUri.toString(),