[cfe] Add OffsetMap This adds OffsetMap to avoid using names (or other means) to connect objects/builders created in the OutlineBuilder with the DietListener. The OffsetMap uses offsets, through Tokens or Identifiers, as the key for the created objects. Change-Id: I704d8f8374402463ea741e36ed15b279acb85535 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/366942 Reviewed-by: Chloe Stefantsova <cstefantsova@google.com> Commit-Queue: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/front_end/lib/src/fasta/builder_graph.dart b/pkg/front_end/lib/src/fasta/builder_graph.dart index fdae514..b36f06d 100644 --- a/pkg/front_end/lib/src/fasta/builder_graph.dart +++ b/pkg/front_end/lib/src/fasta/builder_graph.dart
@@ -16,7 +16,7 @@ import 'dill/dill_library_builder.dart' show DillLibraryBuilder; -import 'source/source_library_builder.dart' show SourceLibraryBuilder; +import 'source/source_library_builder.dart' show Part, SourceLibraryBuilder; import 'incremental_compiler.dart' show getPartUri; @@ -52,8 +52,8 @@ neighbors.add(uri); } } - for (LibraryBuilder part in library.parts) { - Uri uri = part.importUri; + for (Part part in library.parts) { + Uri uri = part.builder.importUri; if (builders.containsKey(uri)) { neighbors.add(uri); }
diff --git a/pkg/front_end/lib/src/fasta/export.dart b/pkg/front_end/lib/src/fasta/export.dart index 3eb8ee8..9c0234a 100644 --- a/pkg/front_end/lib/src/fasta/export.dart +++ b/pkg/front_end/lib/src/fasta/export.dart
@@ -4,6 +4,8 @@ library fasta.export; +import 'package:kernel/ast.dart'; + import 'builder/builder.dart'; import 'builder/library_builder.dart'; import 'combinator.dart' show CombinatorBuilder; @@ -23,6 +25,11 @@ Uri get fileUri => exporter.fileUri; + /// The [LibraryDependency] node corresponding to this import. + /// + /// This set in [SourceLibraryBuilder.addDependencies]. + late final LibraryDependency libraryDependency; + bool addToExportScope(String name, Builder member) { if (combinators != null) { for (CombinatorBuilder combinator in combinators!) {
diff --git a/pkg/front_end/lib/src/fasta/import.dart b/pkg/front_end/lib/src/fasta/import.dart index 310033c..dfb8cfe 100644 --- a/pkg/front_end/lib/src/fasta/import.dart +++ b/pkg/front_end/lib/src/fasta/import.dart
@@ -46,6 +46,11 @@ // this field is set. final String? nativeImportPath; + /// The [LibraryDependency] node corresponding to this import. + /// + /// This set in [SourceLibraryBuilder.addDependencies]. + LibraryDependency? libraryDependency; + Import( this.importer, this.imported,
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart index 38a698d..7b9c4d2 100644 --- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart +++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -105,7 +105,7 @@ import 'source/source_class_builder.dart' show SourceClassBuilder; import 'source/source_extension_builder.dart'; import 'source/source_library_builder.dart' - show ImplicitLanguageVersion, SourceLibraryBuilder; + show ImplicitLanguageVersion, Part, SourceLibraryBuilder; import 'source/source_loader.dart'; import 'ticker.dart' show Ticker; import 'uri_translator.dart' show UriTranslator; @@ -2180,12 +2180,12 @@ } if (libraryBuilder is SourceLibraryBuilder) { // TODO(jensj): This shouldn't be possible anymore. - for (LibraryBuilder part in libraryBuilder.parts) { - partUriToParent[part.importUri] = libraryBuilder; - partUriToParent[part.fileUri] = libraryBuilder; - if (isInvalidated(part.importUri, part.fileUri)) { - invalidatedImportUris.add(part.importUri); - builders[part.importUri] = part; + for (Part part in libraryBuilder.parts) { + partUriToParent[part.builder.importUri] = libraryBuilder; + partUriToParent[part.builder.fileUri] = libraryBuilder; + if (isInvalidated(part.builder.importUri, part.builder.fileUri)) { + invalidatedImportUris.add(part.builder.importUri); + builders[part.builder.importUri] = part.builder; } } } else if (libraryBuilder is DillLibraryBuilder) {
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart index 2c843a6..15b3bc3 100644 --- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart +++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -11,8 +11,7 @@ DeclarationKind, IdentifierContext, MemberKind, - Parser, - optional; + Parser; import 'package:_fe_analyzer_shared/src/parser/quote.dart' show unescapeString; import 'package:_fe_analyzer_shared/src/parser/stack_listener.dart' show FixedNullableList, NullValues, ParserRecovery; @@ -26,12 +25,7 @@ import '../builder/declaration_builders.dart'; import '../builder/modifier_builder.dart'; import '../codes/fasta_codes.dart' - show - Code, - LocatedMessage, - Message, - messageExpectedBlockToSkip, - templateInternalProblemNotFound; + show Code, LocatedMessage, Message, messageExpectedBlockToSkip; import '../constant_context.dart' show ConstantContext; import '../crash.dart' show Crash; import '../identifiers.dart' @@ -40,18 +34,16 @@ import '../kernel/benchmarker.dart' show BenchmarkSubdivides, Benchmarker; import '../kernel/body_builder.dart' show BodyBuilder, FormalParameters; import '../kernel/body_builder_context.dart'; -import '../operator.dart'; -import '../problems.dart' show DebugAbort, internalProblem, unexpected; +import '../problems.dart' show DebugAbort; import '../scope.dart'; import '../source/value_kinds.dart'; import '../type_inference/type_inference_engine.dart' show InferenceDataForTesting, TypeInferenceEngine; import '../type_inference/type_inferrer.dart' show TypeInferrer; import 'diet_parser.dart'; -import 'source_class_builder.dart'; +import 'offset_map.dart'; import 'source_constructor_builder.dart'; import 'source_enum_builder.dart'; -import 'source_extension_type_declaration_builder.dart'; import 'source_field_builder.dart'; import 'source_function_builder.dart'; import 'source_library_builder.dart' show SourceLibraryBuilder; @@ -69,9 +61,6 @@ final TypeInferenceEngine typeInferenceEngine; - int importExportDirectiveIndex = 0; - int partDirectiveIndex = 0; - DeclarationBuilder? _currentDeclaration; ClassBuilder? _currentClass; bool _inRedirectingFactory = false; @@ -83,14 +72,16 @@ Scope memberScope; @override - Uri uri; + final Uri uri; final Benchmarker? _benchmarker; + final OffsetMap _offsetMap; + DietListener(SourceLibraryBuilder library, this.hierarchy, this.coreTypes, - this.typeInferenceEngine) + this.typeInferenceEngine, this._offsetMap) : libraryBuilder = library, - uri = library.fileUri, + uri = _offsetMap.uri, memberScope = library.scope, enableNative = library.loader.target.backendTarget.enableNative(library.importUri), @@ -355,9 +346,8 @@ if (name is ParserRecovery) return; Identifier identifier = name as Identifier; - final BodyBuilder listener = createFunctionListener( - lookupBuilder(getOrSet, identifier.name, identifier.nameOffset) - as SourceFunctionBuilderImpl); + final BodyBuilder listener = + createFunctionListener(_offsetMap.lookupProcedure(identifier)); buildFunctionBody(listener, bodyToken, metadata, MemberKind.TopLevelMethod); } @@ -554,9 +544,8 @@ unescapeString(importUriToken.lexeme, importUriToken, this); if (importUri.startsWith("dart-ext:")) return; - Library libraryNode = libraryBuilder.library; LibraryDependency? dependency = - libraryNode.dependencies[importExportDirectiveIndex++]; + _offsetMap.lookupImport(importKeyword).libraryDependency; parseMetadata(libraryBuilder.bodyBuilderContext, libraryBuilder, metadata, dependency); } @@ -571,9 +560,8 @@ debugEvent("Export"); Token? metadata = pop() as Token?; - Library libraryNode = libraryBuilder.library; LibraryDependency dependency = - libraryNode.dependencies[importExportDirectiveIndex++]; + _offsetMap.lookupExport(exportKeyword).libraryDependency; parseMetadata(libraryBuilder.bodyBuilderContext, libraryBuilder, metadata, dependency); } @@ -583,16 +571,9 @@ debugEvent("Part"); Token? metadata = pop() as Token?; - Library libraryNode = libraryBuilder.library; - if (libraryNode.parts.length > partDirectiveIndex) { - // If partDirectiveIndex >= libraryNode.parts.length we are in a case of - // on part having other parts. An error has already been issued. - // Don't try to parse metadata into other parts that have nothing to do - // with the one this keyword is talking about. - LibraryPart part = libraryNode.parts[partDirectiveIndex++]; - parseMetadata( - libraryBuilder.bodyBuilderContext, libraryBuilder, metadata, part); - } + LibraryPart part = _offsetMap.lookupPart(partKeyword); + parseMetadata( + libraryBuilder.bodyBuilderContext, libraryBuilder, metadata, part); } @override @@ -635,9 +616,7 @@ if (name is ParserRecovery || currentClassIsParserRecovery) return; Identifier identifier = name as Identifier; - SourceFunctionBuilderImpl builder = lookupConstructor( - _getConstructorName(identifier), identifier.qualifierOffset) - as SourceFunctionBuilderImpl; + SourceFunctionBuilder builder = _offsetMap.lookupConstructor(identifier); if (_inRedirectingFactory) { buildRedirectingFactoryMethod( bodyToken, builder, MemberKind.Factory, metadata); @@ -755,18 +734,9 @@ SourceFunctionBuilder builder; if (isConstructor) { - builder = lookupConstructor( - _getConstructorName(identifier), identifier.qualifierOffset) - as SourceFunctionBuilder; + builder = _offsetMap.lookupConstructor(identifier); } else { - String name = identifier.name; - // TODO(johnniwinther): Find a uniform way to compute this. - bool hasNoFormals = identical(beginParam.next, beginParam.endGroup); - if (Operator.subtract == identifier.operator && hasNoFormals) { - name = Operator.unaryMinus.text; - } - Builder? memberBuilder = - lookupBuilder(getOrSet, name, identifier.nameOffset); + Builder? memberBuilder = _offsetMap.lookupProcedure(identifier); if (currentClass?.isEnum == true && memberBuilder is SourceFieldBuilder && memberBuilder.name == "values") { @@ -857,8 +827,8 @@ inferenceDataForTesting: builder.dataForTesting?.inferenceData); } - void buildRedirectingFactoryMethod(Token token, - SourceFunctionBuilderImpl builder, MemberKind kind, Token? metadata) { + void buildRedirectingFactoryMethod(Token token, SourceFunctionBuilder builder, + MemberKind kind, Token? metadata) { _benchmarker?.beginSubdivide( BenchmarkSubdivides.diet_listener_buildRedirectingFactoryMethod); final BodyBuilder listener = createFunctionListener(builder); @@ -896,9 +866,7 @@ if (names == null || currentClassIsParserRecovery) return; Identifier first = names.first!; - SourceFieldBuilder declaration = - lookupBuilder(/*getOrSet*/ null, first.name, first.nameOffset) - as SourceFieldBuilder; + SourceFieldBuilder declaration = _offsetMap.lookupField(first); // TODO(paulberry): don't re-parse the field if we've already parsed it // for type inference. _parseFields( @@ -949,11 +917,9 @@ return; } if (name is Identifier) { - currentDeclaration = - lookupBuilder(/*getOrSet*/ null, name.name, name.nameOffset) - as DeclarationBuilder; + currentDeclaration = _offsetMap.lookupNamedDeclaration(name); } else { - currentDeclaration = lookupUnnamedExtensionBuilder(beginToken); + currentDeclaration = _offsetMap.lookupUnnamedDeclaration(beginToken); } memberScope = currentDeclaration!.scope; } @@ -1023,7 +989,8 @@ void beginExtensionTypeDeclaration( Token? augmentToken, Token extensionKeyword, Token nameToken) { debugEvent("beginExtensionTypeDeclaration"); - push(new SimpleIdentifier(nameToken)); + Identifier identifier = new SimpleIdentifier(nameToken); + push(identifier); push(extensionKeyword); // The current declaration is set in [beginClassOrMixinOrExtensionBody] but @@ -1032,9 +999,7 @@ assert(currentDeclaration == null); assert(memberScope == libraryBuilder.scope); - currentDeclaration = - lookupBuilder(/*getOrSet*/ null, nameToken.lexeme, nameToken.charOffset) - as DeclarationBuilder; + currentDeclaration = _offsetMap.lookupNamedDeclaration(identifier); memberScope = currentDeclaration!.scope; } @@ -1052,16 +1017,12 @@ ])); debugEvent("endPrimaryConstructor"); Token formalsToken = pop() as Token; // Pop formals begin token. - int charOffset = formalsToken.charOffset; - String constructorName = ''; if (hasConstructorName) { // TODO(johnniwinther): Handle [ParserRecovery]. - Identifier identifier = pop() as Identifier; - constructorName = identifier.name; - charOffset = identifier.nameOffset; + pop() as Identifier; } SourceFunctionBuilder builder = - lookupConstructor(constructorName, charOffset) as SourceFunctionBuilder; + _offsetMap.lookupPrimaryConstructor(beginToken); if (!builder.isConst) { buildPrimaryConstructor(createFunctionListener(builder), formalsToken); } @@ -1104,9 +1065,7 @@ } Identifier identifier = name as Identifier; - currentDeclaration = - lookupBuilder(/*getOrSet*/ null, identifier.name, identifier.nameOffset) - as DeclarationBuilder; + currentDeclaration = _offsetMap.lookupNamedDeclaration(identifier); memberScope = currentDeclaration!.scope; } @@ -1278,70 +1237,6 @@ bodyBuilder.checkEmpty(token.charOffset); } - Builder? lookupBuilder(Token? getOrSet, String name, int charOffset) { - // TODO(ahe): Can I move this to Scope or ScopeBuilder? - Builder? declaration; - DeclarationBuilder? currentDeclaration = this.currentDeclaration; - if (currentDeclaration != null) { - if (uri != currentDeclaration.fileUri) { - unexpected("$uri", "${currentDeclaration.fileUri}", - currentDeclaration.charOffset, currentDeclaration.fileUri); - } - - if (getOrSet != null && optional("set", getOrSet)) { - declaration = - currentDeclaration.scope.lookupLocalMember(name, setter: true); - } else { - declaration = - currentDeclaration.scope.lookupLocalMember(name, setter: false); - } - } else if (getOrSet != null && optional("set", getOrSet)) { - declaration = libraryBuilder.scope.lookupLocalMember(name, setter: true); - } else { - declaration = libraryBuilder.scope.lookupLocalMember(name, setter: false); - } - declaration = handleDuplicatedName(declaration, charOffset); - checkBuilder(declaration, name, charOffset); - return declaration; - } - - ExtensionBuilder? lookupUnnamedExtensionBuilder(Token extensionToken) { - return libraryBuilder.scope - .lookupLocalUnnamedExtension(uri, extensionToken.charOffset); - } - - String _getConstructorName(Identifier nameOrQualified) { - String suffix; - if (nameOrQualified is QualifiedName) { - suffix = nameOrQualified.name; - } else { - suffix = nameOrQualified.name == currentDeclaration!.name - ? "" - : nameOrQualified.name; - } - return suffix; - } - - Builder? lookupConstructor(String constructorName, int charOffset) { - assert(currentDeclaration != null); - assert(currentDeclaration is SourceClassBuilder || - currentDeclaration is SourceExtensionTypeDeclarationBuilder); - Builder? declaration; - if (libraryFeatures.constructorTearoffs.isEnabled) { - constructorName = constructorName == "new" ? "" : constructorName; - } - declaration = - currentDeclaration!.constructorScope.lookupLocalMember(constructorName); - declaration = handleDuplicatedName(declaration, charOffset); - checkBuilder( - declaration, - constructorName.isEmpty - ? currentDeclaration!.name - : '${currentDeclaration!.name}.$constructorName', - charOffset); - return declaration; - } - Builder? handleDuplicatedName(Builder? declaration, int charOffset) { if (declaration == null) { return null; @@ -1376,7 +1271,7 @@ } } - void checkBuilder(Builder? declaration, String name, int charOffset) { + /*void checkBuilder(Builder? declaration, String name, int charOffset) { if (declaration == null) { internalProblem( templateInternalProblemNotFound.withArguments(name), charOffset, uri); @@ -1385,7 +1280,7 @@ unexpected("$uri", "${declaration.fileUri}", declaration.charOffset, declaration.fileUri); } - } + }*/ @override void addProblem(Message message, int charOffset, int length,
diff --git a/pkg/front_end/lib/src/fasta/source/offset_map.dart b/pkg/front_end/lib/src/fasta/source/offset_map.dart new file mode 100644 index 0000000..363c056 --- /dev/null +++ b/pkg/front_end/lib/src/fasta/source/offset_map.dart
@@ -0,0 +1,150 @@ +// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:_fe_analyzer_shared/src/scanner/token.dart'; +import 'package:kernel/ast.dart'; +import '../builder/builder.dart'; +import '../builder/declaration_builders.dart'; +import '../codes/fasta_codes.dart'; +import '../export.dart'; +import '../identifiers.dart'; +import '../import.dart'; +import '../problems.dart'; +import 'source_field_builder.dart'; +import 'source_function_builder.dart'; + +/// Map from offsets of directives and declarations to the objects the define. +/// +/// This is used to connect parsing of the [OutlineBuilder], where the objects +/// are created, with the [DietListener], where the objects are looked up. +class OffsetMap { + final Uri uri; + final Map<int, DeclarationBuilder> _declarations = {}; + final Map<int, SourceFieldBuilder> _fields = {}; + final Map<int, SourceFunctionBuilder> _constructors = {}; + final Map<int, SourceFunctionBuilder> _procedures = {}; + final Map<int, LibraryPart> _parts = {}; + final Map<int, Import> _imports = {}; + final Map<int, Export> _exports = {}; + + OffsetMap(this.uri); + + void registerImport(Token importKeyword, Import import) { + assert(importKeyword.lexeme == 'import', + "Invalid token for import: $importKeyword."); + _imports[importKeyword.charOffset] = import; + } + + Import lookupImport(Token importKeyword) { + assert(importKeyword.lexeme == 'import', + "Invalid token for import: $importKeyword."); + return _checkDirective(_imports[importKeyword.charOffset], '<import>', + importKeyword.charOffset); + } + + void registerExport(Token exportKeyword, Export export) { + assert(exportKeyword.lexeme == 'export', + "Invalid token for export: $exportKeyword."); + _exports[exportKeyword.charOffset] = export; + } + + Export lookupExport(Token exportKeyword) { + assert(exportKeyword.lexeme == 'export', + "Invalid token for export: $exportKeyword."); + return _checkDirective(_exports[exportKeyword.charOffset], '<export>', + exportKeyword.charOffset); + } + + void registerPart(Token partKeyword, LibraryPart part) { + assert( + partKeyword.lexeme == 'part', "Invalid token for part: $partKeyword."); + _parts[partKeyword.charOffset] = part; + } + + LibraryPart lookupPart(Token partKeyword) { + assert( + partKeyword.lexeme == 'part', "Invalid token for part: $partKeyword."); + return _checkDirective( + _parts[partKeyword.charOffset], '<part>', partKeyword.charOffset); + } + + void registerNamedDeclaration( + Identifier identifier, DeclarationBuilder builder) { + _declarations[identifier.nameOffset] = builder; + } + + DeclarationBuilder lookupNamedDeclaration(Identifier identifier) { + return _checkBuilder(_declarations[identifier.nameOffset], identifier.name, + identifier.nameOffset); + } + + void registerUnnamedDeclaration( + Token beginToken, DeclarationBuilder builder) { + _declarations[beginToken.charOffset] = builder; + } + + DeclarationBuilder lookupUnnamedDeclaration(Token beginToken) { + return _checkBuilder(_declarations[beginToken.charOffset], + '<unnamed-declaration>', beginToken.charOffset); + } + + void registerField(Identifier identifier, SourceFieldBuilder builder) { + _fields[identifier.nameOffset] = builder; + } + + SourceFieldBuilder lookupField(Identifier identifier) { + return _checkBuilder( + _fields[identifier.nameOffset], identifier.name, identifier.nameOffset); + } + + void registerPrimaryConstructor( + Token beginToken, SourceFunctionBuilder builder) { + _constructors[beginToken.charOffset] = builder; + } + + SourceFunctionBuilder lookupPrimaryConstructor(Token beginToken) { + return _checkBuilder(_constructors[beginToken.charOffset], + '<primary-constructor>', beginToken.charOffset); + } + + void registerConstructor( + Identifier identifier, SourceFunctionBuilder builder) { + _constructors[identifier.nameOffset] = builder; + } + + SourceFunctionBuilder lookupConstructor(Identifier identifier) { + return _checkBuilder(_constructors[identifier.nameOffset], identifier.name, + identifier.nameOffset); + } + + void registerProcedure(Identifier identifier, SourceFunctionBuilder builder) { + _procedures[identifier.nameOffset] = builder; + } + + SourceFunctionBuilder lookupProcedure(Identifier identifier) { + return _checkBuilder(_procedures[identifier.nameOffset], identifier.name, + identifier.nameOffset); + } + + T _checkDirective<T>(T? directive, String name, int charOffset) { + if (directive == null) { + internalProblem( + templateInternalProblemNotFound.withArguments(name), charOffset, uri); + } + return directive; + } + + T _checkBuilder<T extends Builder>( + T? declaration, String name, int charOffset) { + if (declaration == null) { + internalProblem( + templateInternalProblemNotFound.withArguments(name), charOffset, uri); + } + if (uri != declaration.fileUri) { + unexpected("$uri", "${declaration.fileUri}", declaration.charOffset, + declaration.fileUri); + } + return declaration; + } +}
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 8d2d77e..ff08984 100644 --- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart +++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -70,6 +70,7 @@ staticMask; import '../operator.dart' show Operator; import '../problems.dart' show unhandled; +import 'offset_map.dart'; import 'source_enum_builder.dart'; import 'source_library_builder.dart' show @@ -537,10 +538,11 @@ bool get inFunctionType => _structuralParameterDepthLevel > 0 || _insideOfFormalParameterType; - OutlineBuilder(SourceLibraryBuilder library) - : libraryBuilder = library, - enableNative = - library.loader.target.backendTarget.enableNative(library.importUri); + OffsetMap _offsetMap; + + OutlineBuilder(this.libraryBuilder, this._offsetMap) + : enableNative = libraryBuilder.loader.target.backendTarget + .enableNative(libraryBuilder.importUri); DeclarationContext get declarationContext => _declarationContext.head; @@ -678,8 +680,8 @@ int uriOffset = popCharOffset(); String uri = pop() as String; List<MetadataBuilder>? metadata = pop() as List<MetadataBuilder>?; - libraryBuilder.addExport(metadata, uri, configurations, combinators, - exportKeyword.charOffset, uriOffset); + libraryBuilder.addExport(_offsetMap, exportKeyword, metadata, uri, + configurations, combinators, exportKeyword.charOffset, uriOffset); checkEmpty(exportKeyword.charOffset); } @@ -733,6 +735,8 @@ } bool isAugmentationImport = augmentToken != null; libraryBuilder.addImport( + offsetMap: _offsetMap, + importKeyword: importKeyword, metadata: metadata, isAugmentationImport: isAugmentationImport, uri: uri, @@ -811,7 +815,7 @@ int charOffset = popCharOffset(); String uri = pop() as String; List<MetadataBuilder>? metadata = pop() as List<MetadataBuilder>?; - libraryBuilder.addPart(metadata, uri, charOffset); + libraryBuilder.addPart(_offsetMap, partKeyword, metadata, uri, charOffset); checkEmpty(partKeyword.charOffset); } @@ -1365,9 +1369,10 @@ modifiers |= abstractMask; } libraryBuilder.addClass( + _offsetMap, metadata, modifiers, - identifier.name, + identifier, typeVariables, supertype, mixinApplication, @@ -1458,9 +1463,10 @@ } libraryBuilder.addMixinDeclaration( + _offsetMap, metadata, mixinDeclarationMask, - identifier.name, + identifier, typeVariables, supertypeConstraints, interfaces, @@ -1496,8 +1502,9 @@ List<NominalVariableBuilder>? typeVariables = pop() as List<NominalVariableBuilder>?; int offset = nameToken?.charOffset ?? extensionKeyword.charOffset; - push(nameToken?.lexeme ?? NullValues.Name); - push(offset); + push(nameToken != null + ? new SimpleIdentifier(nameToken) + : NullValues.Identifier); push(typeVariables ?? NullValues.NominalVariables); libraryBuilder.currentTypeParameterScopeBuilder .markAsExtensionDeclaration(nameToken?.lexeme, offset, typeVariables); @@ -1509,8 +1516,7 @@ assert(checkState(extensionKeyword, [ unionOfKinds([ValueKinds.ParserRecovery, ValueKinds.TypeBuilder]), ValueKinds.NominalVariableListOrNull, - ValueKinds.Integer, - ValueKinds.NameOrNull, + ValueKinds.IdentifierOrNull, ValueKinds.MetadataListOrNull ])); debugEvent("endExtensionDeclaration"); @@ -1523,11 +1529,8 @@ } List<NominalVariableBuilder>? typeVariables = pop(NullValues.NominalVariables) as List<NominalVariableBuilder>?; - int nameOffset = popCharOffset(); - String? name = pop(NullValues.Name) as String?; - if (name == null) { - nameOffset = extensionKeyword.charOffset; - } + Identifier? name = pop(NullValues.Identifier) as Identifier?; + int nameOffset = name?.nameOffset ?? extensionKeyword.charOffset; List<MetadataBuilder>? metadata = pop(NullValues.Metadata) as List<MetadataBuilder>?; checkEmpty(extensionKeyword.charOffset); @@ -1535,6 +1538,8 @@ ? extensionKeyword.charOffset : metadata.first.charOffset; libraryBuilder.addExtensionDeclaration( + _offsetMap, + beginToken, metadata, // TODO(johnniwinther): Support modifiers on extensions? 0, @@ -1559,8 +1564,7 @@ pop() as List<NominalVariableBuilder>?; String name = nameToken.lexeme; int offset = nameToken.charOffset; - push(name); - push(offset); + push(new SimpleIdentifier(nameToken)); push(typeVariables ?? NullValues.NominalVariables); libraryBuilder.currentTypeParameterScopeBuilder .markAsExtensionTypeDeclaration(name, offset, typeVariables); @@ -1574,8 +1578,7 @@ assert(checkState(extensionKeyword, [ ValueKinds.TypeBuilderListOrNull, ValueKinds.NominalVariableListOrNull, - ValueKinds.Integer, - ValueKinds.Name, + ValueKinds.Identifier, ValueKinds.MetadataListOrNull, ])); reportIfNotEnabled(libraryFeatures.inlineClass, typeKeyword.charOffset, @@ -1585,8 +1588,7 @@ pop(NullValues.TypeBuilderList) as List<TypeBuilder>?; List<NominalVariableBuilder>? typeVariables = pop(NullValues.NominalVariables) as List<NominalVariableBuilder>?; - int nameOffset = popCharOffset(); - String name = pop() as String; + Identifier identifier = pop() as Identifier; List<MetadataBuilder>? metadata = pop(NullValues.Metadata) as List<MetadataBuilder>?; checkEmpty(extensionKeyword.charOffset); @@ -1597,14 +1599,14 @@ ? extensionKeyword.charOffset : metadata.first.charOffset; libraryBuilder.addExtensionTypeDeclaration( + _offsetMap, metadata, // TODO(johnniwinther): Support modifiers on extension types? 0, - name, + identifier, typeVariables, interfaces, startOffset, - nameOffset, endToken.charOffset); libraryBuilder.endIndexedContainer(); @@ -1731,6 +1733,8 @@ scopeBuilder.resolveNamedTypes(typeVariables, libraryBuilder); libraryBuilder.addPrimaryConstructor( + offsetMap: _offsetMap, + beginToken: beginToken, constructorName: constructorName == "new" ? "" : constructorName, charOffset: charOffset, formals: formals, @@ -1814,9 +1818,11 @@ final int startCharOffset = metadata == null ? beginToken.charOffset : metadata.first.charOffset; libraryBuilder.addProcedure( + _offsetMap, metadata, modifiers, returnType, + identifier, identifier.name, typeVariables, formals, @@ -2343,9 +2349,10 @@ final int startCharOffset = metadata == null ? beginToken.charOffset : metadata.first.charOffset; libraryBuilder.addConstructor( + _offsetMap, metadata, modifiers, - name, + identifier, constructorName, typeVariables, formals, @@ -2369,9 +2376,11 @@ bool isExtensionTypeMember = methodKind == _MethodKind.extensionTypeMethod; libraryBuilder.addProcedure( + _offsetMap, metadata, modifiers, returnType, + identifier, name, typeVariables, formals, @@ -3063,14 +3072,14 @@ } libraryBuilder.addEnum( + _offsetMap, metadata, - identifier.name, + identifier, typeVariables, mixinBuilder, interfaces, enumConstantInfos, startCharOffset, - identifier.nameOffset, endCharOffset); } else { libraryBuilder @@ -3369,6 +3378,7 @@ List<MetadataBuilder>? metadata = pop(NullValues.Metadata) as List<MetadataBuilder>?; checkEmpty(typedefKeyword.charOffset); + libraryBuilder.addFunctionTypeAlias(metadata, identifier.name, typeVariables, aliasedType, identifier.nameOffset); popDeclarationContext(DeclarationContext.Typedef); @@ -3472,8 +3482,8 @@ List<MetadataBuilder>? metadata = pop() as List<MetadataBuilder>?; checkEmpty(beginToken.charOffset); if (fieldInfos != null) { - libraryBuilder.addFields( - metadata, modifiers, /* isTopLevel = */ true, type, fieldInfos); + libraryBuilder.addFields(_offsetMap, metadata, modifiers, + /* isTopLevel = */ true, type, fieldInfos); } popDeclarationContext(); } @@ -3535,8 +3545,8 @@ } List<MetadataBuilder>? metadata = pop() as List<MetadataBuilder>?; if (fieldInfos != null) { - libraryBuilder.addFields( - metadata, modifiers, /* isTopLevel = */ false, type, fieldInfos); + libraryBuilder.addFields(_offsetMap, metadata, modifiers, + /* isTopLevel = */ false, type, fieldInfos); } popDeclarationContext(); } @@ -3810,6 +3820,7 @@ TypeParameterScopeKind.factoryMethod, "<syntax-error>"); } else { libraryBuilder.addFactoryMethod( + _offsetMap, metadata, modifiers, name,
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 1672f47..7e60e542 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
@@ -105,6 +105,7 @@ import '../util/helpers.dart'; import 'class_declaration.dart'; import 'name_scheme.dart'; +import 'offset_map.dart'; import 'source_class_builder.dart' show SourceClassBuilder; import 'source_constructor_builder.dart'; import 'source_enum_builder.dart'; @@ -124,15 +125,18 @@ @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; + final TypeParameterScopeBuilder _libraryTypeParameterScopeBuilder; final List<ConstructorReferenceBuilder> constructorReferences = <ConstructorReferenceBuilder>[]; - final List<LibraryBuilder> parts = <LibraryBuilder>[]; - - // Can I use library.parts instead? See SourceLibraryBuilder.addPart. - final List<int> partOffsets = <int>[]; + final List<Part> parts = []; final List<Import> imports = <Import>[]; @@ -353,6 +357,24 @@ "'${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); @@ -740,6 +762,8 @@ } void addExport( + OffsetMap offsetMap, + Token exportKeyword, List<MetadataBuilder>? metadata, String uri, List<Configuration>? configurations, @@ -760,11 +784,15 @@ resolve(this.importUri, uri, uriOffset), charOffset, accessor: this); exportedLibrary.addExporter(this, combinators, charOffset); - exports.add(new Export(this, exportedLibrary, combinators, charOffset)); + Export export = new Export(this, exportedLibrary, combinators, charOffset); + exports.add(export); + offsetMap.registerExport(exportKeyword, export); } void addImport( - {required List<MetadataBuilder>? metadata, + {OffsetMap? offsetMap, + Token? importKeyword, + required List<MetadataBuilder>? metadata, required bool isAugmentationImport, required String uri, required List<Configuration>? configurations, @@ -810,7 +838,7 @@ referencesFromIndex: isAugmentationImport ? indexedLibrary : null); } - imports.add(new Import( + Import import = new Import( this, builder, isAugmentationImport, @@ -821,10 +849,13 @@ charOffset, prefixCharOffset, importIndex, - nativeImportPath: nativePath)); + nativeImportPath: nativePath); + imports.add(import); + offsetMap?.registerImport(importKeyword!, import); } - void addPart(List<MetadataBuilder>? metadata, String uri, int charOffset) { + 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 @@ -833,17 +864,18 @@ resolve(fileUri, uri, charOffset); // TODO(johnniwinther): Add a LibraryPartBuilder instead of using // [LibraryBuilder] to represent both libraries and parts. - parts.add(loader.read(resolvedUri, charOffset, + LibraryBuilder builder = loader.read(resolvedUri, charOffset, origin: isAugmenting ? origin : null, fileUri: newFileUri, accessor: this, - isPatch: isAugmenting)); - partOffsets.add(charOffset); + isPatch: isAugmenting); + parts.add(new Part(charOffset, builder)); // 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, @@ -868,8 +900,13 @@ _scriptTokenOffset ??= charOffset; } - void addFields(List<MetadataBuilder>? metadata, int modifiers, - bool isTopLevel, TypeBuilder? type, List<FieldInfo> fieldInfos) { + 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; @@ -886,22 +923,24 @@ new Token.eof(startToken.previous!.offset).setNext(startToken); } bool hasInitializer = info.initializerToken != null; - addField( - metadata, - modifiers, - isTopLevel, - type ?? addInferableType(), - info.identifier.name, - info.identifier.nameOffset, - info.charEndOffset, - startToken, - hasInitializer, - constInitializerToken: - potentiallyNeedInitializerInOutline ? startToken : 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, + Builder addBuilder(String name, Builder declaration, int charOffset, {Reference? getterReference, Reference? setterReference}) { // TODO(ahe): Set the parent correctly here. Could then change the // implementation of MemberBuilder.isTopLevel to test explicitly for a @@ -948,7 +987,7 @@ : currentTypeParameterScopeBuilder.members!); Builder? existing = members[name]; - if (existing == declaration) return existing; + if (existing == declaration) return declaration; if (declaration.next != null && declaration.next != existing) { unexpected( @@ -1171,13 +1210,13 @@ List<LocatedMessage> context = <LocatedMessage>[ messagePartInPartLibraryContext.withLocation(library.fileUri, -1, 1), ]; - for (int offset in partOffsets) { - addProblem(messagePartInPart, offset, noLength, fileUri, + for (Part part in parts) { + addProblem(messagePartInPart, part.offset, noLength, fileUri, context: context); } - for (LibraryBuilder part in parts) { + for (Part part in parts) { // Mark this part as used so we don't report it as orphaned. - usedParts!.add(part.importUri); + usedParts!.add(part.builder.importUri); } } parts.clear(); @@ -1206,32 +1245,43 @@ void includeParts(Set<Uri> usedParts) { Set<Uri> seenParts = new Set<Uri>(); - for (int i = 0; i < parts.length; i++) { - LibraryBuilder part = parts[i]; - int partOffset = partOffsets[i]; - if (part == this) { + int index = 0; + while (index < parts.length) { + Part part = parts[index]; + bool keepPart = true; + // TODO(johnniwinther): Use [part.offset] in messages. + if (part.builder == this) { addProblem(messagePartOfSelf, -1, noLength, fileUri); - } else if (seenParts.add(part.fileUri)) { - if (part.partOfLibrary != null) { - addProblem(messagePartOfTwoLibraries, -1, noLength, part.fileUri, + keepPart = false; + } else if (seenParts.add(part.builder.fileUri)) { + if (part.builder.partOfLibrary != null) { + addProblem( + messagePartOfTwoLibraries, -1, noLength, part.builder.fileUri, context: [ messagePartOfTwoLibrariesContext.withLocation( - part.partOfLibrary!.fileUri, -1, noLength), + part.builder.partOfLibrary!.fileUri, -1, noLength), messagePartOfTwoLibrariesContext.withLocation( this.fileUri, -1, noLength) ]); + keepPart = false; } else { - usedParts.add(part.importUri); - includePart(part, usedParts, partOffset); + usedParts.add(part.builder.importUri); + keepPart = _includePart(part.builder, usedParts, part.offset); } } else { - addProblem(templatePartTwice.withArguments(part.fileUri), -1, noLength, - fileUri); + addProblem(templatePartTwice.withArguments(part.builder.fileUri), -1, + noLength, fileUri); + keepPart = false; + } + if (keepPart) { + index++; + } else { + parts.removeAt(index); } } } - bool includePart(LibraryBuilder part, Set<Uri> usedParts, int partOffset) { + bool _includePart(LibraryBuilder part, Set<Uri> usedParts, int partOffset) { if (part is SourceLibraryBuilder) { if (part.partOfUri != null) { if (uriIsValid(part.partOfUri!) && part.partOfUri != importUri) { @@ -1902,9 +1952,10 @@ } void addClass( + OffsetMap offsetMap, List<MetadataBuilder>? metadata, int modifiers, - String className, + Identifier identifier, List<NominalVariableBuilder>? typeVariables, TypeBuilder? supertype, MixinApplicationBuilder? mixins, @@ -1921,10 +1972,11 @@ required bool isAugmentation, required bool isMixinClass}) { _addClass( + offsetMap, TypeParameterScopeKind.classDeclaration, metadata, modifiers, - className, + identifier, typeVariables, supertype, mixins, @@ -1943,9 +1995,10 @@ } void addMixinDeclaration( + OffsetMap offsetMap, List<MetadataBuilder>? metadata, int modifiers, - String className, + Identifier identifier, List<NominalVariableBuilder>? typeVariables, List<TypeBuilder>? supertypeConstraints, List<TypeBuilder>? interfaces, @@ -1967,10 +2020,11 @@ } } _addClass( + offsetMap, TypeParameterScopeKind.mixinDeclaration, metadata, modifiers, - className, + identifier, typeVariables, supertype, mixinApplication, @@ -1989,10 +2043,11 @@ } void _addClass( + OffsetMap offsetMap, TypeParameterScopeKind kind, List<MetadataBuilder>? metadata, int modifiers, - String className, + Identifier identifier, List<NominalVariableBuilder>? typeVariables, TypeBuilder? supertype, MixinApplicationBuilder? mixins, @@ -2008,6 +2063,7 @@ required bool isFinal, required bool isAugmentation, required bool isMixinClass}) { + String className = identifier.name; // Nested declaration began in `OutlineBuilder.beginClassDeclaration`. TypeParameterScopeBuilder declaration = endNestedDeclaration(kind, className) @@ -2106,6 +2162,7 @@ setters.forEach(setParentAndCheckConflicts); addBuilder(className, classBuilder, nameOffset, getterReference: _indexedContainer?.reference); + offsetMap.registerNamedDeclaration(identifier, classBuilder); } Map<String, NominalVariableBuilder>? checkTypeVariables( @@ -2279,14 +2336,17 @@ } void addExtensionDeclaration( + OffsetMap offsetMap, + Token beginToken, List<MetadataBuilder>? metadata, int modifiers, - String? name, + 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 = @@ -2355,17 +2415,23 @@ 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, - String name, + Identifier identifier, List<NominalVariableBuilder>? typeVariables, List<TypeBuilder>? interfaces, int startOffset, - int nameOffset, int endOffset) { + String name = identifier.name; // Nested declaration began in `OutlineBuilder.beginExtensionDeclaration`. TypeParameterScopeBuilder declaration = endNestedDeclaration( TypeParameterScopeKind.extensionTypeDeclaration, name) @@ -2414,7 +2480,7 @@ this, new List<ConstructorReferenceBuilder>.of(constructorReferences), startOffset, - nameOffset, + identifier.nameOffset, endOffset, indexedContainer, representationFieldBuilder); @@ -2449,8 +2515,10 @@ constructors.forEach(setParentAndCheckConflicts); setters.forEach(setParentAndCheckConflicts); addBuilder(extensionTypeDeclarationBuilder.name, - extensionTypeDeclarationBuilder, nameOffset, + extensionTypeDeclarationBuilder, identifier.nameOffset, getterReference: indexedContainer?.reference); + offsetMap.registerNamedDeclaration( + identifier, extensionTypeDeclarationBuilder); } TypeBuilder? _applyMixins( @@ -2986,15 +3054,16 @@ } void addPrimaryConstructor( - {required String constructorName, + {required OffsetMap offsetMap, + required Token beginToken, + required String constructorName, required List<NominalVariableBuilder>? typeVariables, required List<FormalParameterBuilder>? formals, required int charOffset, required bool isConst}) { - addConstructor( + SourceFunctionBuilder builder = _addConstructor( null, isConst ? constMask : 0, - null, constructorName, typeVariables, formals, @@ -3004,12 +3073,43 @@ /* charEndOffset = */ charOffset, /* nativeMethodName = */ null, forAbstractClassOrMixin: false); + offsetMap.registerPrimaryConstructor(beginToken, builder); } void addConstructor( + OffsetMap offsetMap, List<MetadataBuilder>? metadata, int modifiers, - final Object? name, + 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, @@ -3103,12 +3203,15 @@ 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, @@ -3197,9 +3300,11 @@ if (nativeMethodName != null) { addNativeMethod(procedureBuilder); } + offsetMap.registerProcedure(identifier, procedureBuilder); } void addFactoryMethod( + OffsetMap offsetMap, List<MetadataBuilder>? metadata, int modifiers, Identifier identifier, @@ -3352,18 +3457,22 @@ if (nativeMethodName != null) { addNativeMethod(procedureBuilder); } + offsetMap.registerConstructor(identifier, procedureBuilder); } void addEnum( + OffsetMap offsetMap, List<MetadataBuilder>? metadata, - String name, + Identifier identifier, List<NominalVariableBuilder>? typeVariables, MixinApplicationBuilder? supertypeBuilder, List<TypeBuilder>? interfaceBuilders, List<EnumConstantInfo?>? enumConstantInfos, int startCharOffset, - int charOffset, int charEndOffset) { + String name = identifier.name; + int charOffset = identifier.nameOffset; + IndexedClass? referencesFromIndexedClass; if (indexedLibrary != null) { referencesFromIndexedClass = indexedLibrary!.lookupIndexedClass(name); @@ -3448,6 +3557,8 @@ setters.forEach(setParentAndCheckConflicts); addBuilder(name, enumBuilder, charOffset, getterReference: referencesFromIndexedClass?.cls.reference); + + offsetMap.registerNamedDeclaration(identifier, enumBuilder); } void addFunctionTypeAlias( @@ -3736,29 +3847,35 @@ continue; } + LibraryDependency libraryDependency; if (import.deferred && import.prefixBuilder?.dependency != null) { - library.addDependency(import.prefixBuilder!.dependency!); + libraryDependency = import.prefixBuilder!.dependency!; } else { LibraryBuilder imported = import.imported!.origin; Library targetLibrary = imported.library; - library.addDependency(new LibraryDependency.import(targetLibrary, + libraryDependency = new LibraryDependency.import(targetLibrary, name: import.prefix, combinators: toKernelCombinators(import.combinators)) - ..fileOffset = import.charOffset); + ..fileOffset = import.charOffset; } + library.addDependency(libraryDependency); + import.libraryDependency = libraryDependency; } else { // Add export Export export = exports[exportIndex++]; - library.addDependency(new LibraryDependency.export( + LibraryDependency libraryDependency = new LibraryDependency.export( export.exported.library, combinators: toKernelCombinators(export.combinators)) - ..fileOffset = export.charOffset); + ..fileOffset = export.charOffset; + library.addDependency(libraryDependency); + export.libraryDependency = libraryDependency; } } - for (LibraryBuilder part in parts) { - if (part is SourceLibraryBuilder) { - part.addDependencies(library, seen); + for (Part part in parts) { + LibraryBuilder builder = part.builder; + if (builder is SourceLibraryBuilder) { + builder.addDependencies(library, seen); } } } @@ -6187,3 +6304,18 @@ @override String get name => _iterator?.name ?? (throw new StateError('No element')); } + +class Part { + final int offset; + final LibraryBuilder builder; + + Part(this.offset, this.builder); + + OffsetMap get offsetMap { + if (builder is SourceLibraryBuilder) { + return (builder as SourceLibraryBuilder).offsetMap; + } + assert(false, "No offset map for $builder."); + return new OffsetMap(builder.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 7e8fae6..7f42382 100644 --- a/pkg/front_end/lib/src/fasta/source/source_loader.dart +++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -81,6 +81,7 @@ import 'diet_listener.dart' show DietListener; import 'diet_parser.dart' show DietParser, useImplicitCreationExpressionInCfe; import 'name_scheme.dart'; +import 'offset_map.dart'; import 'outline_builder.dart' show OutlineBuilder; import 'source_class_builder.dart' show SourceClassBuilder; import 'source_constructor_builder.dart'; @@ -92,6 +93,7 @@ InvalidLanguageVersion, LanguageVersion, LibraryAccess, + Part, SourceLibraryBuilder; import 'source_procedure_builder.dart'; import 'stack_listener_impl.dart' show offsetForToken; @@ -1122,10 +1124,12 @@ Future<Null> buildOutline(SourceLibraryBuilder library) async { Token tokens = await tokenize(library); - OutlineBuilder listener = new OutlineBuilder(library); + OffsetMap offsetMap = new OffsetMap(library.fileUri); + OutlineBuilder listener = new OutlineBuilder(library, offsetMap); new ClassMemberParser(listener, allowPatterns: library.libraryFeatures.patterns.isEnabled) .parseUnit(tokens); + library.offsetMap = offsetMap; } /// Builds all the method bodies found in the given [library]. @@ -1172,18 +1176,18 @@ } } - DietListener listener = createDietListener(library); + DietListener listener = createDietListener(library, library.offsetMap); DietParser parser = new DietParser(listener, allowPatterns: library.libraryFeatures.patterns.isEnabled); parser.parseUnit(tokens); - for (LibraryBuilder part in library.parts) { - if (part.partOfLibrary != library) { - // Part was included in multiple libraries. Skip it here. - continue; - } - Token tokens = await tokenize(part as SourceLibraryBuilder, + for (Part part in library.parts) { + assert(part.builder.partOfLibrary == library, + "Part ${part.builder} is not part of ${library}."); + Token tokens = await tokenize(part.builder as SourceLibraryBuilder, suppressLexicalErrors: true); - listener.uri = part.fileUri; + DietListener listener = createDietListener(library, part.offsetMap); + DietParser parser = new DietParser(listener, + allowPatterns: library.libraryFeatures.patterns.isEnabled); parser.parseUnit(tokens); } } @@ -1195,7 +1199,11 @@ FunctionNode parameters, VariableDeclaration? extensionThis) async { Token token = await tokenize(libraryBuilder, suppressLexicalErrors: false); - DietListener dietListener = createDietListener(libraryBuilder); + DietListener dietListener = createDietListener( + libraryBuilder, + // Expression compilation doesn't build an outline, and thus doesn't + // support members from source, so we provide an empty [DeclarationMap]. + new OffsetMap(libraryBuilder.fileUri)); Builder parent = libraryBuilder; if (enclosingClassOrExtension != null) { @@ -1271,8 +1279,10 @@ parameters); } - DietListener createDietListener(SourceLibraryBuilder library) { - return new DietListener(library, hierarchy, coreTypes, typeInferenceEngine); + DietListener createDietListener( + SourceLibraryBuilder library, OffsetMap offsetMap) { + return new DietListener( + library, hierarchy, coreTypes, typeInferenceEngine, offsetMap); } void resolveParts() {
diff --git a/pkg/front_end/test/compiler_test_helper.dart b/pkg/front_end/test/compiler_test_helper.dart index e6be3e5..6c28995 100644 --- a/pkg/front_end/test/compiler_test_helper.dart +++ b/pkg/front_end/test/compiler_test_helper.dart
@@ -19,10 +19,10 @@ import 'package:front_end/src/fasta/kernel/kernel_target.dart'; import 'package:front_end/src/fasta/scope.dart'; import 'package:front_end/src/fasta/source/diet_listener.dart'; +import 'package:front_end/src/fasta/source/offset_map.dart'; import 'package:front_end/src/fasta/source/source_library_builder.dart'; import 'package:front_end/src/fasta/source/source_loader.dart'; import 'package:front_end/src/fasta/ticker.dart'; -import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart'; import 'package:front_end/src/fasta/type_inference/type_inferrer.dart'; import 'package:front_end/src/fasta/uri_translator.dart'; import 'package:kernel/class_hierarchy.dart'; @@ -214,9 +214,10 @@ : super(fileSystem, includeComments, target); @override - DietListener createDietListener(SourceLibraryBuilder library) { - return new DietListenerTest( - library, hierarchy, coreTypes, typeInferenceEngine, bodyBuilderCreator); + DietListener createDietListener( + SourceLibraryBuilder library, OffsetMap offsetMap) { + return new DietListenerTest(library, hierarchy, coreTypes, + typeInferenceEngine, offsetMap, bodyBuilderCreator); } @override @@ -246,13 +247,8 @@ class DietListenerTest extends DietListener { final BodyBuilderCreator bodyBuilderCreator; - DietListenerTest( - SourceLibraryBuilder library, - ClassHierarchy hierarchy, - CoreTypes coreTypes, - TypeInferenceEngine typeInferenceEngine, - this.bodyBuilderCreator) - : super(library, hierarchy, coreTypes, typeInferenceEngine); + DietListenerTest(super.library, super.hierarchy, super.coreTypes, + super.typeInferenceEngine, super.offsetMap, this.bodyBuilderCreator); @override BodyBuilder createListenerInternal(
diff --git a/pkg/front_end/test/coverage_suite.dart b/pkg/front_end/test/coverage_suite.dart index 0788206..6dc69d8 100644 --- a/pkg/front_end/test/coverage_suite.dart +++ b/pkg/front_end/test/coverage_suite.dart
@@ -97,7 +97,7 @@ 78.42227378190255, "package:front_end/src/fasta/builder/void_type_declaration_builder.dart": 100.0, - "package:front_end/src/fasta/builder_graph.dart": 55.769230769230774, + "package:front_end/src/fasta/builder_graph.dart": 54.0, "package:front_end/src/fasta/codes/fasta_codes_cfe_generated.dart": 73.0892742453436, "package:front_end/src/fasta/codes/type_labeler.dart": 83.68336025848141, @@ -205,10 +205,10 @@ "package:front_end/src/fasta/modifier.dart": 100.0, "package:front_end/src/fasta/operator.dart": 100.0, "package:front_end/src/fasta/problems.dart": 0.0, - "package:front_end/src/fasta/scope.dart": 80.14256619144604, + "package:front_end/src/fasta/scope.dart": 79.0, "package:front_end/src/fasta/source/class_declaration.dart": 80.29556650246306, - "package:front_end/src/fasta/source/diet_listener.dart": 91.22807017543859, + "package:front_end/src/fasta/source/diet_listener.dart": 89.0, "package:front_end/src/fasta/source/diet_parser.dart": 100.0, "package:front_end/src/fasta/source/name_scheme.dart": 93.19148936170212, "package:front_end/src/fasta/source/outline_builder.dart": 91.54411764705883,
diff --git a/pkg/front_end/testcases/general/part_of_multiple.dart b/pkg/front_end/testcases/general/part_of_multiple.dart new file mode 100644 index 0000000..5e76378 --- /dev/null +++ b/pkg/front_end/testcases/general/part_of_multiple.dart
@@ -0,0 +1,6 @@ +// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'part_of_multiple_lib1.dart'; +import 'part_of_multiple_lib2.dart';
diff --git a/pkg/front_end/testcases/general/part_of_multiple.dart.strong.expect b/pkg/front_end/testcases/general/part_of_multiple.dart.strong.expect new file mode 100644 index 0000000..0a4a719 --- /dev/null +++ b/pkg/front_end/testcases/general/part_of_multiple.dart.strong.expect
@@ -0,0 +1,24 @@ +library; +import self as self; + +import "org-dartlang-testcase:///part_of_multiple_lib1.dart"; +import "org-dartlang-testcase:///part_of_multiple_lib2.dart"; + + +library part_of_multiple; +import self as self2; + +part part_of_multiple_part.dart; + +library part_of_multiple; +// +// Problems in library: +// +// pkg/front_end/testcases/general/part_of_multiple_part.dart: Error: A file can't be part of more than one library. +// Try moving the shared declarations into the libraries, or into a new library. +// pkg/front_end/testcases/general/part_of_multiple_lib1.dart: Context: Used as a part in this library. +// pkg/front_end/testcases/general/part_of_multiple_lib2.dart: Context: Used as a part in this library. +// +import self as self3; + +part part_of_multiple_part.dart;
diff --git a/pkg/front_end/testcases/general/part_of_multiple.dart.strong.modular.expect b/pkg/front_end/testcases/general/part_of_multiple.dart.strong.modular.expect new file mode 100644 index 0000000..0a4a719 --- /dev/null +++ b/pkg/front_end/testcases/general/part_of_multiple.dart.strong.modular.expect
@@ -0,0 +1,24 @@ +library; +import self as self; + +import "org-dartlang-testcase:///part_of_multiple_lib1.dart"; +import "org-dartlang-testcase:///part_of_multiple_lib2.dart"; + + +library part_of_multiple; +import self as self2; + +part part_of_multiple_part.dart; + +library part_of_multiple; +// +// Problems in library: +// +// pkg/front_end/testcases/general/part_of_multiple_part.dart: Error: A file can't be part of more than one library. +// Try moving the shared declarations into the libraries, or into a new library. +// pkg/front_end/testcases/general/part_of_multiple_lib1.dart: Context: Used as a part in this library. +// pkg/front_end/testcases/general/part_of_multiple_lib2.dart: Context: Used as a part in this library. +// +import self as self3; + +part part_of_multiple_part.dart;
diff --git a/pkg/front_end/testcases/general/part_of_multiple.dart.strong.outline.expect b/pkg/front_end/testcases/general/part_of_multiple.dart.strong.outline.expect new file mode 100644 index 0000000..0a4a719 --- /dev/null +++ b/pkg/front_end/testcases/general/part_of_multiple.dart.strong.outline.expect
@@ -0,0 +1,24 @@ +library; +import self as self; + +import "org-dartlang-testcase:///part_of_multiple_lib1.dart"; +import "org-dartlang-testcase:///part_of_multiple_lib2.dart"; + + +library part_of_multiple; +import self as self2; + +part part_of_multiple_part.dart; + +library part_of_multiple; +// +// Problems in library: +// +// pkg/front_end/testcases/general/part_of_multiple_part.dart: Error: A file can't be part of more than one library. +// Try moving the shared declarations into the libraries, or into a new library. +// pkg/front_end/testcases/general/part_of_multiple_lib1.dart: Context: Used as a part in this library. +// pkg/front_end/testcases/general/part_of_multiple_lib2.dart: Context: Used as a part in this library. +// +import self as self3; + +part part_of_multiple_part.dart;
diff --git a/pkg/front_end/testcases/general/part_of_multiple.dart.strong.transformed.expect b/pkg/front_end/testcases/general/part_of_multiple.dart.strong.transformed.expect new file mode 100644 index 0000000..0a4a719 --- /dev/null +++ b/pkg/front_end/testcases/general/part_of_multiple.dart.strong.transformed.expect
@@ -0,0 +1,24 @@ +library; +import self as self; + +import "org-dartlang-testcase:///part_of_multiple_lib1.dart"; +import "org-dartlang-testcase:///part_of_multiple_lib2.dart"; + + +library part_of_multiple; +import self as self2; + +part part_of_multiple_part.dart; + +library part_of_multiple; +// +// Problems in library: +// +// pkg/front_end/testcases/general/part_of_multiple_part.dart: Error: A file can't be part of more than one library. +// Try moving the shared declarations into the libraries, or into a new library. +// pkg/front_end/testcases/general/part_of_multiple_lib1.dart: Context: Used as a part in this library. +// pkg/front_end/testcases/general/part_of_multiple_lib2.dart: Context: Used as a part in this library. +// +import self as self3; + +part part_of_multiple_part.dart;
diff --git a/pkg/front_end/testcases/general/part_of_multiple.dart.textual_outline.expect b/pkg/front_end/testcases/general/part_of_multiple.dart.textual_outline.expect new file mode 100644 index 0000000..0370ff6 --- /dev/null +++ b/pkg/front_end/testcases/general/part_of_multiple.dart.textual_outline.expect
@@ -0,0 +1,3 @@ +import 'part_of_multiple_lib1.dart'; + +import 'part_of_multiple_lib2.dart';
diff --git a/pkg/front_end/testcases/general/part_of_multiple.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/part_of_multiple.dart.textual_outline_modelled.expect new file mode 100644 index 0000000..03c393e --- /dev/null +++ b/pkg/front_end/testcases/general/part_of_multiple.dart.textual_outline_modelled.expect
@@ -0,0 +1,2 @@ +import 'part_of_multiple_lib1.dart'; +import 'part_of_multiple_lib2.dart';
diff --git a/pkg/front_end/testcases/general/part_of_multiple_lib1.dart b/pkg/front_end/testcases/general/part_of_multiple_lib1.dart new file mode 100644 index 0000000..4322291 --- /dev/null +++ b/pkg/front_end/testcases/general/part_of_multiple_lib1.dart
@@ -0,0 +1,7 @@ +// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library part_of_multiple; + +part 'part_of_multiple_part.dart';
diff --git a/pkg/front_end/testcases/general/part_of_multiple_lib2.dart b/pkg/front_end/testcases/general/part_of_multiple_lib2.dart new file mode 100644 index 0000000..4322291 --- /dev/null +++ b/pkg/front_end/testcases/general/part_of_multiple_lib2.dart
@@ -0,0 +1,7 @@ +// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +library part_of_multiple; + +part 'part_of_multiple_part.dart';
diff --git a/pkg/front_end/testcases/general/part_of_multiple_part.dart b/pkg/front_end/testcases/general/part_of_multiple_part.dart new file mode 100644 index 0000000..8d76ba4 --- /dev/null +++ b/pkg/front_end/testcases/general/part_of_multiple_part.dart
@@ -0,0 +1,5 @@ +// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of part_of_multiple;
diff --git a/pkg/front_end/testcases/general/part_self.dart b/pkg/front_end/testcases/general/part_self.dart new file mode 100644 index 0000000..dc0f39a --- /dev/null +++ b/pkg/front_end/testcases/general/part_self.dart
@@ -0,0 +1,5 @@ +// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part 'part_self.dart';
diff --git a/pkg/front_end/testcases/general/part_self.dart.strong.expect b/pkg/front_end/testcases/general/part_self.dart.strong.expect new file mode 100644 index 0000000..d591432 --- /dev/null +++ b/pkg/front_end/testcases/general/part_self.dart.strong.expect
@@ -0,0 +1,9 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/general/part_self.dart: Error: A file can't be a part of itself. +// +import self as self; + +part part_self.dart;
diff --git a/pkg/front_end/testcases/general/part_self.dart.strong.modular.expect b/pkg/front_end/testcases/general/part_self.dart.strong.modular.expect new file mode 100644 index 0000000..d591432 --- /dev/null +++ b/pkg/front_end/testcases/general/part_self.dart.strong.modular.expect
@@ -0,0 +1,9 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/general/part_self.dart: Error: A file can't be a part of itself. +// +import self as self; + +part part_self.dart;
diff --git a/pkg/front_end/testcases/general/part_self.dart.strong.outline.expect b/pkg/front_end/testcases/general/part_self.dart.strong.outline.expect new file mode 100644 index 0000000..d591432 --- /dev/null +++ b/pkg/front_end/testcases/general/part_self.dart.strong.outline.expect
@@ -0,0 +1,9 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/general/part_self.dart: Error: A file can't be a part of itself. +// +import self as self; + +part part_self.dart;
diff --git a/pkg/front_end/testcases/general/part_self.dart.strong.transformed.expect b/pkg/front_end/testcases/general/part_self.dart.strong.transformed.expect new file mode 100644 index 0000000..d591432 --- /dev/null +++ b/pkg/front_end/testcases/general/part_self.dart.strong.transformed.expect
@@ -0,0 +1,9 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/general/part_self.dart: Error: A file can't be a part of itself. +// +import self as self; + +part part_self.dart;
diff --git a/pkg/front_end/testcases/general/part_self.dart.textual_outline.expect b/pkg/front_end/testcases/general/part_self.dart.textual_outline.expect new file mode 100644 index 0000000..347608e --- /dev/null +++ b/pkg/front_end/testcases/general/part_self.dart.textual_outline.expect
@@ -0,0 +1 @@ +part 'part_self.dart';
diff --git a/pkg/front_end/testcases/general/part_self.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/part_self.dart.textual_outline_modelled.expect new file mode 100644 index 0000000..347608e --- /dev/null +++ b/pkg/front_end/testcases/general/part_self.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@ +part 'part_self.dart';
diff --git a/pkg/front_end/testcases/general/part_twice.dart b/pkg/front_end/testcases/general/part_twice.dart new file mode 100644 index 0000000..8ce116f --- /dev/null +++ b/pkg/front_end/testcases/general/part_twice.dart
@@ -0,0 +1,6 @@ +// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part 'part_twice_part.dart'; +part 'part_twice_part.dart';
diff --git a/pkg/front_end/testcases/general/part_twice.dart.strong.expect b/pkg/front_end/testcases/general/part_twice.dart.strong.expect new file mode 100644 index 0000000..1402ce5 --- /dev/null +++ b/pkg/front_end/testcases/general/part_twice.dart.strong.expect
@@ -0,0 +1,10 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/general/part_twice.dart: Error: Can't use 'pkg/front_end/testcases/general/part_twice_part.dart' as a part more than once. +// +import self as self; + +part part_twice_part.dart; +part part_twice_part.dart;
diff --git a/pkg/front_end/testcases/general/part_twice.dart.strong.modular.expect b/pkg/front_end/testcases/general/part_twice.dart.strong.modular.expect new file mode 100644 index 0000000..1402ce5 --- /dev/null +++ b/pkg/front_end/testcases/general/part_twice.dart.strong.modular.expect
@@ -0,0 +1,10 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/general/part_twice.dart: Error: Can't use 'pkg/front_end/testcases/general/part_twice_part.dart' as a part more than once. +// +import self as self; + +part part_twice_part.dart; +part part_twice_part.dart;
diff --git a/pkg/front_end/testcases/general/part_twice.dart.strong.outline.expect b/pkg/front_end/testcases/general/part_twice.dart.strong.outline.expect new file mode 100644 index 0000000..1402ce5 --- /dev/null +++ b/pkg/front_end/testcases/general/part_twice.dart.strong.outline.expect
@@ -0,0 +1,10 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/general/part_twice.dart: Error: Can't use 'pkg/front_end/testcases/general/part_twice_part.dart' as a part more than once. +// +import self as self; + +part part_twice_part.dart; +part part_twice_part.dart;
diff --git a/pkg/front_end/testcases/general/part_twice.dart.strong.transformed.expect b/pkg/front_end/testcases/general/part_twice.dart.strong.transformed.expect new file mode 100644 index 0000000..1402ce5 --- /dev/null +++ b/pkg/front_end/testcases/general/part_twice.dart.strong.transformed.expect
@@ -0,0 +1,10 @@ +library; +// +// Problems in library: +// +// pkg/front_end/testcases/general/part_twice.dart: Error: Can't use 'pkg/front_end/testcases/general/part_twice_part.dart' as a part more than once. +// +import self as self; + +part part_twice_part.dart; +part part_twice_part.dart;
diff --git a/pkg/front_end/testcases/general/part_twice.dart.textual_outline.expect b/pkg/front_end/testcases/general/part_twice.dart.textual_outline.expect new file mode 100644 index 0000000..1819cdd6 --- /dev/null +++ b/pkg/front_end/testcases/general/part_twice.dart.textual_outline.expect
@@ -0,0 +1,3 @@ +part 'part_twice_part.dart'; + +part 'part_twice_part.dart';
diff --git a/pkg/front_end/testcases/general/part_twice.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/part_twice.dart.textual_outline_modelled.expect new file mode 100644 index 0000000..1819cdd6 --- /dev/null +++ b/pkg/front_end/testcases/general/part_twice.dart.textual_outline_modelled.expect
@@ -0,0 +1,3 @@ +part 'part_twice_part.dart'; + +part 'part_twice_part.dart';
diff --git a/pkg/front_end/testcases/general/part_twice_part.dart b/pkg/front_end/testcases/general/part_twice_part.dart new file mode 100644 index 0000000..93a8918 --- /dev/null +++ b/pkg/front_end/testcases/general/part_twice_part.dart
@@ -0,0 +1,5 @@ +// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +part of 'part_twice.dart';
diff --git a/pkg/front_end/testcases/macros/multiple_imports.dart.strong.expect b/pkg/front_end/testcases/macros/multiple_imports.dart.strong.expect index b7fd881..b6f612e 100644 --- a/pkg/front_end/testcases/macros/multiple_imports.dart.strong.expect +++ b/pkg/front_end/testcases/macros/multiple_imports.dart.strong.expect
@@ -5,12 +5,12 @@ import "dart:convert" as con; @#C2 -@#C4 import "dart:math"; -@#C6 -@#C8 +@#C4 import "dart:convert"; +@#C6 import "dart:async"; +@#C8 import "org-dartlang-testcase:///multiple_imports.dart"; class Const extends core::Object /*hasConstConstructor*/ { // from org-dartlang-testcase:///multiple_imports_lib.dart @@ -30,9 +30,9 @@ constants { #C1 = 0 #C2 = self::Const {field:#C1} - #C3 = 2 + #C3 = 1 #C4 = self::Const {field:#C3} - #C5 = 1 + #C5 = 2 #C6 = self::Const {field:#C5} #C7 = 3 #C8 = self::Const {field:#C7}
diff --git a/pkg/front_end/testcases/macros/multiple_imports.dart.strong.modular.expect b/pkg/front_end/testcases/macros/multiple_imports.dart.strong.modular.expect index b7fd881..b6f612e 100644 --- a/pkg/front_end/testcases/macros/multiple_imports.dart.strong.modular.expect +++ b/pkg/front_end/testcases/macros/multiple_imports.dart.strong.modular.expect
@@ -5,12 +5,12 @@ import "dart:convert" as con; @#C2 -@#C4 import "dart:math"; -@#C6 -@#C8 +@#C4 import "dart:convert"; +@#C6 import "dart:async"; +@#C8 import "org-dartlang-testcase:///multiple_imports.dart"; class Const extends core::Object /*hasConstConstructor*/ { // from org-dartlang-testcase:///multiple_imports_lib.dart @@ -30,9 +30,9 @@ constants { #C1 = 0 #C2 = self::Const {field:#C1} - #C3 = 2 + #C3 = 1 #C4 = self::Const {field:#C3} - #C5 = 1 + #C5 = 2 #C6 = self::Const {field:#C5} #C7 = 3 #C8 = self::Const {field:#C7}
diff --git a/pkg/front_end/testcases/macros/multiple_imports.dart.strong.transformed.expect b/pkg/front_end/testcases/macros/multiple_imports.dart.strong.transformed.expect index b7fd881..b6f612e 100644 --- a/pkg/front_end/testcases/macros/multiple_imports.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/macros/multiple_imports.dart.strong.transformed.expect
@@ -5,12 +5,12 @@ import "dart:convert" as con; @#C2 -@#C4 import "dart:math"; -@#C6 -@#C8 +@#C4 import "dart:convert"; +@#C6 import "dart:async"; +@#C8 import "org-dartlang-testcase:///multiple_imports.dart"; class Const extends core::Object /*hasConstConstructor*/ { // from org-dartlang-testcase:///multiple_imports_lib.dart @@ -30,9 +30,9 @@ constants { #C1 = 0 #C2 = self::Const {field:#C1} - #C3 = 2 + #C3 = 1 #C4 = self::Const {field:#C3} - #C5 = 1 + #C5 = 2 #C6 = self::Const {field:#C5} #C7 = 3 #C8 = self::Const {field:#C7}