| // 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/parser/formal_parameter_kind.dart'; |
| import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token; |
| import 'package:_fe_analyzer_shared/src/util/resolve_relative_uri.dart' |
| show resolveRelativeUri; |
| import 'package:kernel/ast.dart' hide Combinator, MapLiteralEntry; |
| import 'package:kernel/names.dart' show indexSetName; |
| import 'package:kernel/reference_from_index.dart' show IndexedLibrary; |
| |
| import '../api_prototype/experimental_flags.dart'; |
| import '../api_prototype/lowering_predicates.dart'; |
| import '../base/combinator.dart' show CombinatorBuilder; |
| import '../base/configuration.dart' show Configuration; |
| import '../base/export.dart' show Export; |
| import '../base/identifiers.dart' show Identifier, QualifiedNameIdentifier; |
| import '../base/import.dart' show Import; |
| import '../base/messages.dart'; |
| import '../base/modifiers.dart' show Modifiers; |
| import '../base/problems.dart' show internalProblem; |
| import '../base/scope.dart'; |
| import '../base/uri_offset.dart'; |
| import '../base/uris.dart'; |
| import '../builder/compilation_unit.dart'; |
| import '../builder/constructor_reference_builder.dart'; |
| import '../builder/declaration_builders.dart'; |
| import '../builder/formal_parameter_builder.dart'; |
| import '../builder/function_type_builder.dart'; |
| import '../builder/metadata_builder.dart'; |
| import '../builder/named_type_builder.dart'; |
| import '../builder/nullability_builder.dart'; |
| import '../builder/omitted_type_builder.dart'; |
| import '../builder/type_builder.dart'; |
| import '../builder/void_type_builder.dart'; |
| import '../fragment/fragment.dart'; |
| import '../util/local_stack.dart'; |
| import 'fragment_factory.dart'; |
| import 'name_space_builder.dart'; |
| import 'native_method_registry.dart'; |
| import 'nominal_parameter_name_space.dart'; |
| import 'offset_map.dart'; |
| import 'source_library_builder.dart'; |
| import 'source_loader.dart' show SourceLoader; |
| import 'source_type_parameter_builder.dart'; |
| import 'type_parameter_factory.dart'; |
| import 'type_scope.dart'; |
| |
| abstract class CompilationUnitRegistry { |
| void registerLibraryDirective({ |
| required String? libraryName, |
| required List<MetadataBuilder>? metadata, |
| }); |
| void registerPartOf({required String? name, required Uri? resolvedUri}); |
| void registerPart(Part part); |
| void registerLibraryPart(LibraryPart libraryPart); |
| void registerImport(Import import); |
| void registerExport(Export export); |
| } |
| |
| class FragmentFactoryImpl implements FragmentFactory { |
| final SourceCompilationUnit _compilationUnit; |
| |
| final ProblemReporting _problemReporting; |
| |
| /// The object used as the root for creating augmentation libraries. |
| // TODO(johnniwinther): Remove this once parts support augmentations. |
| final SourceCompilationUnit _augmentationRoot; |
| |
| final LibraryNameSpaceBuilder _libraryNameSpaceBuilder; |
| |
| /// Index of the library we use references for. |
| final IndexedLibrary? _indexedLibrary; |
| |
| final TypeParameterFactory _typeParameterFactory; |
| |
| final LookupScope _compilationUnitScope; |
| |
| /// Index for building unique lowered names for wildcard variables. |
| int wildcardVariableIndex = 0; |
| |
| final LocalStack<TypeScope> _typeScopes; |
| |
| final LocalStack<NominalParameterNameSpace> _nominalParameterNameSpaces = |
| new LocalStack([]); |
| |
| final LocalStack<Map<String, StructuralParameterBuilder>> |
| _structuralParameterScopes = new LocalStack([]); |
| |
| final LocalStack<DeclarationFragmentImpl> _declarationFragments = |
| new LocalStack([]); |
| |
| final CompilationUnitRegistry _compilationUnitRegistry; |
| |
| final NativeMethodRegistry _nativeMethodRegistry; |
| |
| FragmentFactoryImpl({ |
| required SourceCompilationUnit compilationUnit, |
| required SourceCompilationUnit augmentationRoot, |
| required LibraryNameSpaceBuilder libraryNameSpaceBuilder, |
| required ProblemReporting problemReporting, |
| required LookupScope scope, |
| required IndexedLibrary? indexedLibrary, |
| required TypeParameterFactory typeParameterFactory, |
| required TypeScope typeScope, |
| required CompilationUnitRegistry compilationUnitRegistry, |
| required NativeMethodRegistry nativeMethodRegistry, |
| }) : _compilationUnit = compilationUnit, |
| _augmentationRoot = augmentationRoot, |
| _libraryNameSpaceBuilder = libraryNameSpaceBuilder, |
| _problemReporting = problemReporting, |
| _compilationUnitScope = scope, |
| _typeParameterFactory = typeParameterFactory, |
| _indexedLibrary = indexedLibrary, |
| _typeScopes = new LocalStack([typeScope]), |
| _compilationUnitRegistry = compilationUnitRegistry, |
| _nativeMethodRegistry = nativeMethodRegistry; |
| |
| SourceLoader get loader => _compilationUnit.loader; |
| |
| LibraryFeatures get libraryFeatures => _compilationUnit.libraryFeatures; |
| |
| final List<ConstructorReferenceBuilder> _constructorReferences = []; |
| |
| @override |
| void beginClassOrNamedMixinApplicationHeader() { |
| NominalParameterNameSpace nominalParameterNameSpace = |
| new NominalParameterNameSpace(); |
| _nominalParameterNameSpaces.push(nominalParameterNameSpace); |
| _typeScopes.push( |
| new TypeScope( |
| TypeScopeKind.declarationTypeParameters, |
| new NominalParameterScope( |
| _typeScopes.current.lookupScope, |
| nominalParameterNameSpace, |
| ), |
| _typeScopes.current, |
| ), |
| ); |
| } |
| |
| @override |
| void beginClassDeclaration( |
| String name, |
| int nameOffset, |
| List<TypeParameterFragment>? typeParameters, |
| ) { |
| _declarationFragments.push( |
| new ClassFragment( |
| name: name, |
| fileUri: _compilationUnit.fileUri, |
| nameOffset: nameOffset, |
| typeParameters: typeParameters, |
| enclosingScope: _compilationUnitScope, |
| typeParameterScope: _typeScopes.current.lookupScope, |
| nominalParameterNameSpace: _nominalParameterNameSpaces.current, |
| enclosingCompilationUnit: _compilationUnit, |
| ), |
| ); |
| } |
| |
| @override |
| void beginClassBody() { |
| _typeScopes.push( |
| new TypeScope( |
| TypeScopeKind.classDeclaration, |
| _declarationFragments.current.bodyScope, |
| _typeScopes.current, |
| ), |
| ); |
| } |
| |
| @override |
| ClassFragment endClassDeclaration() { |
| TypeScope bodyScope = _typeScopes.pop(); |
| assert( |
| bodyScope.kind == TypeScopeKind.classDeclaration, |
| "Unexpected type scope: $bodyScope.", |
| ); |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.declarationTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| ClassFragment declarationFragment = |
| _declarationFragments.pop() as ClassFragment; |
| _nominalParameterNameSpaces.pop(); |
| return declarationFragment; |
| } |
| |
| void _popNominalParametersForRecovery( |
| List<TypeParameterFragment>? typeParameters, |
| ) { |
| _nominalParameterNameSpaces.pop().addTypeParameters( |
| _problemReporting, |
| _typeParameterFactory.createNominalParameterBuilders(typeParameters), |
| ownerName: null, |
| allowNameConflict: true, |
| ); |
| } |
| |
| @override |
| // Coverage-ignore(suite): Not run. |
| void endClassDeclarationForParserRecovery( |
| List<TypeParameterFragment>? typeParameters, |
| ) { |
| TypeScope bodyScope = _typeScopes.pop(); |
| assert( |
| bodyScope.kind == TypeScopeKind.classDeclaration, |
| "Unexpected type scope: $bodyScope.", |
| ); |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.declarationTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| |
| _declarationFragments.pop(); |
| _popNominalParametersForRecovery(typeParameters); |
| } |
| |
| @override |
| void beginMixinDeclaration( |
| String name, |
| int nameOffset, |
| List<TypeParameterFragment>? typeParameters, |
| ) { |
| _declarationFragments.push( |
| new MixinFragment( |
| name: name, |
| fileUri: _compilationUnit.fileUri, |
| nameOffset: nameOffset, |
| typeParameters: typeParameters, |
| enclosingScope: _compilationUnitScope, |
| typeParameterScope: _typeScopes.current.lookupScope, |
| nominalParameterNameSpace: _nominalParameterNameSpaces.current, |
| enclosingCompilationUnit: _compilationUnit, |
| ), |
| ); |
| } |
| |
| @override |
| void beginMixinBody() { |
| _typeScopes.push( |
| new TypeScope( |
| TypeScopeKind.mixinDeclaration, |
| _declarationFragments.current.bodyScope, |
| _typeScopes.current, |
| ), |
| ); |
| } |
| |
| @override |
| MixinFragment endMixinDeclaration() { |
| TypeScope bodyScope = _typeScopes.pop(); |
| assert( |
| bodyScope.kind == TypeScopeKind.mixinDeclaration, |
| "Unexpected type scope: $bodyScope.", |
| ); |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.declarationTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| MixinFragment declarationFragment = |
| _declarationFragments.pop() as MixinFragment; |
| _nominalParameterNameSpaces.pop(); |
| return declarationFragment; |
| } |
| |
| @override |
| // Coverage-ignore(suite): Not run. |
| void endMixinDeclarationForParserRecovery( |
| List<TypeParameterFragment>? typeParameters, |
| ) { |
| TypeScope bodyScope = _typeScopes.pop(); |
| assert( |
| bodyScope.kind == TypeScopeKind.mixinDeclaration, |
| "Unexpected type scope: $bodyScope.", |
| ); |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.declarationTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| |
| _declarationFragments.pop(); |
| _popNominalParametersForRecovery(typeParameters); |
| } |
| |
| @override |
| void beginNamedMixinApplication( |
| String name, |
| int charOffset, |
| List<TypeParameterFragment>? typeParameters, |
| ) {} |
| |
| @override |
| LookupScope endNamedMixinApplication(String name) { |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.declarationTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| return typeParameterScope.lookupScope; |
| } |
| |
| @override |
| void endNamedMixinApplicationForParserRecovery( |
| List<TypeParameterFragment>? typeParameters, |
| ) { |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.declarationTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| _popNominalParametersForRecovery(typeParameters); |
| } |
| |
| @override |
| void beginEnumDeclarationHeader(String name) { |
| NominalParameterNameSpace nominalParameterNameSpace = |
| new NominalParameterNameSpace(); |
| _nominalParameterNameSpaces.push(nominalParameterNameSpace); |
| _typeScopes.push( |
| new TypeScope( |
| TypeScopeKind.declarationTypeParameters, |
| new NominalParameterScope( |
| _typeScopes.current.lookupScope, |
| nominalParameterNameSpace, |
| ), |
| _typeScopes.current, |
| ), |
| ); |
| } |
| |
| @override |
| void beginEnumDeclaration( |
| String name, |
| int nameOffset, |
| List<TypeParameterFragment>? typeParameters, |
| ) { |
| _declarationFragments.push( |
| new EnumFragment( |
| name: name, |
| fileUri: _compilationUnit.fileUri, |
| nameOffset: nameOffset, |
| typeParameters: typeParameters, |
| enclosingScope: _compilationUnitScope, |
| typeParameterScope: _typeScopes.current.lookupScope, |
| nominalParameterNameSpace: _nominalParameterNameSpaces.current, |
| enclosingCompilationUnit: _compilationUnit, |
| ), |
| ); |
| } |
| |
| @override |
| void beginEnumBody() { |
| _typeScopes.push( |
| new TypeScope( |
| TypeScopeKind.enumDeclaration, |
| _declarationFragments.current.bodyScope, |
| _typeScopes.current, |
| ), |
| ); |
| } |
| |
| @override |
| EnumFragment endEnumDeclaration() { |
| TypeScope bodyScope = _typeScopes.pop(); |
| assert( |
| bodyScope.kind == TypeScopeKind.enumDeclaration, |
| "Unexpected type scope: $bodyScope.", |
| ); |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.declarationTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| EnumFragment declarationFragment = |
| _declarationFragments.pop() as EnumFragment; |
| _nominalParameterNameSpaces.pop(); |
| return declarationFragment; |
| } |
| |
| @override |
| void endEnumDeclarationForParserRecovery( |
| List<TypeParameterFragment>? typeParameters, |
| ) { |
| TypeScope bodyScope = _typeScopes.pop(); |
| assert( |
| bodyScope.kind == TypeScopeKind.enumDeclaration, |
| "Unexpected type scope: $bodyScope.", |
| ); |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.declarationTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| |
| _declarationFragments.pop(); |
| _popNominalParametersForRecovery(typeParameters); |
| } |
| |
| @override |
| void beginExtensionOrExtensionTypeHeader() { |
| NominalParameterNameSpace nominalParameterNameSpace = |
| new NominalParameterNameSpace(); |
| _nominalParameterNameSpaces.push(nominalParameterNameSpace); |
| _typeScopes.push( |
| new TypeScope( |
| TypeScopeKind.declarationTypeParameters, |
| new NominalParameterScope( |
| _typeScopes.current.lookupScope, |
| nominalParameterNameSpace, |
| ), |
| _typeScopes.current, |
| ), |
| ); |
| } |
| |
| @override |
| void beginExtensionDeclaration( |
| String? name, |
| int nameOrExtensionOffset, |
| List<TypeParameterFragment>? typeParameters, |
| ) { |
| _declarationFragments.push( |
| new ExtensionFragment( |
| name: name, |
| fileUri: _compilationUnit.fileUri, |
| nameOrExtensionOffset: nameOrExtensionOffset, |
| typeParameters: typeParameters, |
| enclosingScope: _compilationUnitScope, |
| typeParameterScope: _typeScopes.current.lookupScope, |
| nominalParameterNameSpace: _nominalParameterNameSpaces.current, |
| enclosingCompilationUnit: _compilationUnit, |
| ), |
| ); |
| } |
| |
| @override |
| void beginExtensionBody() { |
| ExtensionFragment declarationFragment = |
| _declarationFragments.current as ExtensionFragment; |
| _typeScopes.push( |
| new TypeScope( |
| TypeScopeKind.extensionDeclaration, |
| declarationFragment.bodyScope, |
| _typeScopes.current, |
| ), |
| ); |
| } |
| |
| @override |
| ExtensionFragment endExtensionDeclaration() { |
| TypeScope bodyScope = _typeScopes.pop(); |
| assert( |
| bodyScope.kind == TypeScopeKind.extensionDeclaration, |
| "Unexpected type scope: $bodyScope.", |
| ); |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.declarationTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| |
| ExtensionFragment declarationFragment = |
| _declarationFragments.pop() as ExtensionFragment; |
| _nominalParameterNameSpaces.pop(); |
| return declarationFragment; |
| } |
| |
| @override |
| void beginExtensionTypeDeclaration( |
| String name, |
| int nameOffset, |
| List<TypeParameterFragment>? typeParameters, |
| ) { |
| _declarationFragments.push( |
| new ExtensionTypeFragment( |
| name: name, |
| fileUri: _compilationUnit.fileUri, |
| nameOffset: nameOffset, |
| typeParameters: typeParameters, |
| enclosingScope: _compilationUnitScope, |
| typeParameterScope: _typeScopes.current.lookupScope, |
| nominalParameterNameSpace: _nominalParameterNameSpaces.current, |
| enclosingCompilationUnit: _compilationUnit, |
| ), |
| ); |
| } |
| |
| @override |
| void beginExtensionTypeBody() { |
| _typeScopes.push( |
| new TypeScope( |
| TypeScopeKind.extensionTypeDeclaration, |
| _declarationFragments.current.bodyScope, |
| _typeScopes.current, |
| ), |
| ); |
| } |
| |
| @override |
| ExtensionTypeFragment endExtensionTypeDeclaration() { |
| TypeScope bodyScope = _typeScopes.pop(); |
| assert( |
| bodyScope.kind == TypeScopeKind.extensionTypeDeclaration, |
| "Unexpected type scope: $bodyScope.", |
| ); |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.declarationTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| ExtensionTypeFragment declarationFragment = |
| _declarationFragments.pop() as ExtensionTypeFragment; |
| _nominalParameterNameSpaces.pop(); |
| return declarationFragment; |
| } |
| |
| @override |
| void beginFactoryMethod() { |
| NominalParameterNameSpace nominalParameterNameSpace = |
| new NominalParameterNameSpace(); |
| _nominalParameterNameSpaces.push(nominalParameterNameSpace); |
| _typeScopes.push( |
| new TypeScope( |
| TypeScopeKind.memberTypeParameters, |
| new NominalParameterScope( |
| _typeScopes.current.lookupScope, |
| nominalParameterNameSpace, |
| ), |
| _typeScopes.current, |
| ), |
| ); |
| } |
| |
| @override |
| // Coverage-ignore(suite): Not run. |
| void endFactoryMethodForParserRecovery() { |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.memberTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| _popNominalParametersForRecovery(null); |
| } |
| |
| @override |
| void beginConstructor() { |
| NominalParameterNameSpace nominalParameterNameSpace = |
| new NominalParameterNameSpace(); |
| _nominalParameterNameSpaces.push(nominalParameterNameSpace); |
| _typeScopes.push( |
| new TypeScope( |
| TypeScopeKind.memberTypeParameters, |
| new NominalParameterScope( |
| _typeScopes.current.lookupScope, |
| nominalParameterNameSpace, |
| ), |
| _typeScopes.current, |
| ), |
| ); |
| } |
| |
| @override |
| void endConstructorForParserRecovery( |
| List<TypeParameterFragment>? typeParameters, |
| ) { |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.memberTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| _popNominalParametersForRecovery(typeParameters); |
| } |
| |
| @override |
| void beginStaticMethod() { |
| NominalParameterNameSpace nominalParameterNameSpace = |
| new NominalParameterNameSpace(); |
| _nominalParameterNameSpaces.push(nominalParameterNameSpace); |
| _typeScopes.push( |
| new TypeScope( |
| TypeScopeKind.memberTypeParameters, |
| new NominalParameterScope( |
| _typeScopes.current.lookupScope, |
| nominalParameterNameSpace, |
| ), |
| _typeScopes.current, |
| ), |
| ); |
| } |
| |
| @override |
| // Coverage-ignore(suite): Not run. |
| void endStaticMethodForParserRecovery( |
| List<TypeParameterFragment>? typeParameters, |
| ) { |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.memberTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| _popNominalParametersForRecovery(typeParameters); |
| } |
| |
| @override |
| void beginInstanceMethod() { |
| NominalParameterNameSpace nominalParameterNameSpace = |
| new NominalParameterNameSpace(); |
| _nominalParameterNameSpaces.push(nominalParameterNameSpace); |
| _typeScopes.push( |
| new TypeScope( |
| TypeScopeKind.memberTypeParameters, |
| new NominalParameterScope( |
| _typeScopes.current.lookupScope, |
| nominalParameterNameSpace, |
| ), |
| _typeScopes.current, |
| ), |
| ); |
| } |
| |
| @override |
| void endInstanceMethodForParserRecovery( |
| List<TypeParameterFragment>? typeParameters, |
| ) { |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.memberTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| _popNominalParametersForRecovery(typeParameters); |
| } |
| |
| @override |
| void beginTopLevelMethod() { |
| NominalParameterNameSpace nominalParameterNameSpace = |
| new NominalParameterNameSpace(); |
| _nominalParameterNameSpaces.push(nominalParameterNameSpace); |
| _typeScopes.push( |
| new TypeScope( |
| TypeScopeKind.memberTypeParameters, |
| new NominalParameterScope( |
| _typeScopes.current.lookupScope, |
| nominalParameterNameSpace, |
| ), |
| _typeScopes.current, |
| ), |
| ); |
| } |
| |
| @override |
| void endTopLevelMethodForParserRecovery( |
| List<TypeParameterFragment>? typeParameters, |
| ) { |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.memberTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| _popNominalParametersForRecovery(typeParameters); |
| } |
| |
| @override |
| void beginTypedef() { |
| NominalParameterNameSpace nominalParameterNameSpace = |
| new NominalParameterNameSpace(); |
| _nominalParameterNameSpaces.push(nominalParameterNameSpace); |
| _typeScopes.push( |
| new TypeScope( |
| TypeScopeKind.declarationTypeParameters, |
| new NominalParameterScope( |
| _typeScopes.current.lookupScope, |
| nominalParameterNameSpace, |
| ), |
| _typeScopes.current, |
| ), |
| ); |
| } |
| |
| @override |
| void endTypedef() { |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.declarationTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| } |
| |
| @override |
| // Coverage-ignore(suite): Not run. |
| void endTypedefForParserRecovery( |
| List<TypeParameterFragment>? typeParameters, |
| ) { |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.declarationTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| _popNominalParametersForRecovery(typeParameters); |
| } |
| |
| @override |
| void beginFunctionType() { |
| Map<String, StructuralParameterBuilder> structuralParameterScope = {}; |
| _structuralParameterScopes.push(structuralParameterScope); |
| _typeScopes.push( |
| new TypeScope( |
| TypeScopeKind.functionTypeParameters, |
| new TypeParameterScope( |
| _typeScopes.current.lookupScope, |
| structuralParameterScope, |
| ), |
| _typeScopes.current, |
| ), |
| ); |
| } |
| |
| @override |
| void endFunctionType() { |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.functionTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| } |
| |
| @override |
| void checkStacks() { |
| assert( |
| _typeScopes.isSingular, |
| "Unexpected type scope stack: " |
| "$_typeScopes.", |
| ); |
| assert( |
| _declarationFragments.isEmpty, |
| "Unexpected declaration fragment stack: " |
| "$_declarationFragments.", |
| ); |
| assert( |
| _nominalParameterNameSpaces.isEmpty, |
| "Unexpected nominal parameter name space stack : " |
| "$_nominalParameterNameSpaces.", |
| ); |
| assert( |
| _structuralParameterScopes.isEmpty, |
| "Unexpected structural parameter scope stack : " |
| "$_structuralParameterScopes.", |
| ); |
| } |
| |
| Uri _resolve(Uri baseUri, String? uri, int uriOffset, {isPart = false}) { |
| if (uri == null) { |
| // Coverage-ignore-block(suite): Not run. |
| _problemReporting.addProblem( |
| codeExpectedUri, |
| uriOffset, |
| noLength, |
| _compilationUnit.fileUri, |
| ); |
| return new Uri(scheme: MALFORMED_URI_SCHEME); |
| } |
| Uri parsedUri; |
| try { |
| parsedUri = Uri.parse(uri); |
| } on FormatException catch (e) { |
| // Point to position in string indicated by the exception, |
| // or to the initial quote if no position is given. |
| // (Assumes the directive is using a single-line string.) |
| _problemReporting.addProblem( |
| codeCouldNotParseUri.withArgumentsOld(uri, e.message), |
| uriOffset + |
| 1 + |
| (e.offset ?? // Coverage-ignore(suite): Not run. |
| -1), |
| 1, |
| _compilationUnit.fileUri, |
| ); |
| return new Uri( |
| scheme: MALFORMED_URI_SCHEME, |
| query: Uri.encodeQueryComponent(uri), |
| ); |
| } |
| if (isPart && baseUri.isScheme("dart")) { |
| // Coverage-ignore-block(suite): Not run. |
| // Resolve using special rules for dart: URIs |
| return resolveRelativeUri(baseUri, parsedUri); |
| } else { |
| return baseUri.resolveUri(parsedUri); |
| } |
| } |
| |
| @override |
| void addPart( |
| OffsetMap offsetMap, |
| Token partKeyword, |
| List<MetadataBuilder>? metadata, |
| String uri, |
| int charOffset, |
| ) { |
| Uri resolvedUri = _resolve( |
| _compilationUnit.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(_compilationUnit.fileUri, uri, charOffset); |
| CompilationUnit compilationUnit = loader.read( |
| resolvedUri, |
| charOffset, |
| origin: _compilationUnit.isAugmenting ? _augmentationRoot : null, |
| originImportUri: _compilationUnit.originImportUri, |
| fileUri: newFileUri, |
| accessor: _compilationUnit, |
| isPatch: _compilationUnit.isAugmenting, |
| referencesFromIndex: _indexedLibrary, |
| referenceIsPartOwner: _indexedLibrary != null, |
| ); |
| _compilationUnitRegistry.registerPart( |
| new Part( |
| fileUri: _compilationUnit.fileUri, |
| fileOffset: charOffset, |
| compilationUnit: compilationUnit, |
| ), |
| ); |
| |
| // TODO(ahe): [metadata] should be stored, evaluated, and added to [part]. |
| LibraryPart part = new LibraryPart(<Expression>[], uri) |
| ..fileOffset = charOffset; |
| _compilationUnitRegistry.registerLibraryPart(part); |
| offsetMap.registerPart(partKeyword, part); |
| } |
| |
| @override |
| void addPartOf( |
| List<MetadataBuilder>? metadata, |
| String? name, |
| String? uri, |
| int uriOffset, |
| ) { |
| Uri? resolvedUri; |
| if (uri != null) { |
| resolvedUri = _resolve(_compilationUnit.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(_compilationUnit.fileUri, uri, uriOffset); |
| loader.read( |
| resolvedUri, |
| uriOffset, |
| fileUri: newFileUri, |
| accessor: _compilationUnit, |
| ); |
| } |
| _compilationUnitRegistry.registerPartOf( |
| name: name, |
| resolvedUri: resolvedUri, |
| ); |
| if (_scriptTokenOffset != null) { |
| _problemReporting.addProblem( |
| codeScriptTagInPartFile, |
| _scriptTokenOffset!, |
| noLength, |
| _compilationUnit.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, |
| }) { |
| 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)) { |
| _problemReporting.addProblem( |
| codeUnsupportedDartExt, |
| charOffset, |
| noLength, |
| _compilationUnit.fileUri, |
| ); |
| String strippedUri = uri.substring(nativeExtensionScheme.length); |
| if (strippedUri.startsWith("package")) { |
| // Coverage-ignore-block(suite): Not run. |
| resolvedUri = _resolve( |
| _compilationUnit.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(_compilationUnit.importUri, uri, uriOffset); |
| compilationUnit = loader.read( |
| resolvedUri, |
| uriOffset, |
| origin: isAugmentationImport |
| ? |
| // Coverage-ignore(suite): Not run. |
| _augmentationRoot |
| : null, |
| accessor: _compilationUnit, |
| isAugmentation: isAugmentationImport, |
| referencesFromIndex: isAugmentationImport |
| ? |
| // Coverage-ignore(suite): Not run. |
| _indexedLibrary |
| : null, |
| ); |
| } |
| |
| Import import = new Import( |
| _compilationUnit, |
| compilationUnit, |
| isAugmentationImport, |
| deferred, |
| prefix, |
| combinators, |
| configurations, |
| _compilationUnit.fileUri, |
| charOffset, |
| prefixCharOffset, |
| nativeImportPath: nativePath, |
| ); |
| _compilationUnitRegistry.registerImport(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) { |
| // Coverage-ignore-block(suite): Not run. |
| for (Configuration config in configurations) { |
| if (loader.getLibrarySupportValue(config.dottedName) == |
| config.condition) { |
| uri = config.importUri; |
| break; |
| } |
| } |
| } |
| |
| CompilationUnit exportedLibrary = loader.read( |
| _resolve(_compilationUnit.importUri, uri, uriOffset), |
| charOffset, |
| accessor: _compilationUnit, |
| ); |
| exportedLibrary.addExporter(_compilationUnit, combinators, charOffset); |
| Export export = new Export( |
| _compilationUnit, |
| exportedLibrary, |
| combinators, |
| charOffset, |
| ); |
| _compilationUnitRegistry.registerExport(export); |
| offsetMap.registerExport(exportKeyword, export); |
| } |
| |
| @override |
| void addClass({ |
| required OffsetMap offsetMap, |
| required List<MetadataBuilder>? metadata, |
| required Modifiers modifiers, |
| required Identifier identifier, |
| required List<TypeParameterFragment>? typeParameters, |
| required TypeBuilder? supertype, |
| required List<TypeBuilder>? mixins, |
| required List<TypeBuilder>? interfaces, |
| required int startOffset, |
| required int nameOffset, |
| required int endOffset, |
| required int supertypeOffset, |
| }) { |
| ClassFragment declarationFragment = endClassDeclaration(); |
| |
| if (declarationFragment.declaresConstConstructor) { |
| modifiers |= Modifiers.DeclaresConstConstructor; |
| } |
| |
| bool isPatch = |
| _compilationUnit.forPatchLibrary && _hasPatchAnnotation(metadata); |
| if (isPatch) { |
| modifiers |= Modifiers.Augment; |
| } |
| declarationFragment.metadata = metadata; |
| declarationFragment.modifiers = modifiers; |
| declarationFragment.supertype = supertype; |
| declarationFragment.mixins = mixins; |
| declarationFragment.interfaces = interfaces; |
| declarationFragment.constructorReferences = |
| new List<ConstructorReferenceBuilder>.of(_constructorReferences); |
| declarationFragment.startOffset = startOffset; |
| declarationFragment.endOffset = endOffset; |
| |
| _constructorReferences.clear(); |
| |
| _addFragment(declarationFragment); |
| offsetMap.registerNamedDeclarationFragment(identifier, declarationFragment); |
| } |
| |
| @override |
| void addEnum({ |
| required OffsetMap offsetMap, |
| required List<MetadataBuilder>? metadata, |
| required Identifier identifier, |
| required List<TypeParameterFragment>? typeParameters, |
| required List<TypeBuilder>? mixins, |
| required List<TypeBuilder>? interfaces, |
| required int startOffset, |
| required int endOffset, |
| }) { |
| EnumFragment declarationFragment = endEnumDeclaration(); |
| |
| declarationFragment.compilationUnitScope = _compilationUnitScope; |
| declarationFragment.metadata = metadata; |
| declarationFragment.mixins = mixins; |
| declarationFragment.interfaces = interfaces; |
| declarationFragment.constructorReferences = |
| new List<ConstructorReferenceBuilder>.of(_constructorReferences); |
| declarationFragment.startOffset = startOffset; |
| declarationFragment.endOffset = endOffset; |
| |
| _constructorReferences.clear(); |
| |
| _addFragment(declarationFragment); |
| |
| offsetMap.registerNamedDeclarationFragment(identifier, declarationFragment); |
| } |
| |
| @override |
| void addEnumElement({ |
| required List<MetadataBuilder>? metadata, |
| required String name, |
| required int nameOffset, |
| required ConstructorReferenceBuilder? constructorReferenceBuilder, |
| required Token? argumentsBeginToken, |
| }) { |
| DeclarationFragmentImpl enclosingDeclaration = |
| _declarationFragments.current; |
| EnumElementFragment fragment = new EnumElementFragment( |
| metadata: metadata, |
| name: name, |
| nameOffset: nameOffset, |
| fileUri: _compilationUnit.fileUri, |
| constructorReferenceBuilder: constructorReferenceBuilder, |
| argumentsBeginToken: argumentsBeginToken, |
| enclosingScope: enclosingDeclaration.bodyScope, |
| enclosingDeclaration: enclosingDeclaration, |
| enclosingCompilationUnit: _compilationUnit, |
| ); |
| enclosingDeclaration.addEnumElement(fragment); |
| |
| _addFragment(fragment); |
| } |
| |
| @override |
| void addMixinDeclaration({ |
| required OffsetMap offsetMap, |
| required List<MetadataBuilder>? metadata, |
| required Modifiers modifiers, |
| required Identifier identifier, |
| required List<TypeParameterFragment>? typeParameters, |
| required List<TypeBuilder>? supertypeConstraints, |
| required List<TypeBuilder>? interfaces, |
| required int startOffset, |
| required int nameOffset, |
| required int endOffset, |
| }) { |
| TypeBuilder? supertype; |
| List<TypeBuilder>? mixins; |
| if (supertypeConstraints != null && supertypeConstraints.isNotEmpty) { |
| supertype = supertypeConstraints.first; |
| if (supertypeConstraints.length > 1) { |
| mixins = supertypeConstraints.skip(1).toList(); |
| } |
| } |
| |
| MixinFragment declarationFragment = endMixinDeclaration(); |
| |
| modifiers |= Modifiers.Abstract; |
| if (declarationFragment.declaresConstConstructor) { |
| modifiers |= Modifiers.DeclaresConstConstructor; |
| } |
| |
| declarationFragment.metadata = metadata; |
| declarationFragment.modifiers = modifiers; |
| declarationFragment.supertype = supertype; |
| declarationFragment.mixins = mixins; |
| declarationFragment.interfaces = interfaces; |
| declarationFragment.constructorReferences = |
| new List<ConstructorReferenceBuilder>.of(_constructorReferences); |
| declarationFragment.startOffset = startOffset; |
| declarationFragment.endOffset = endOffset; |
| |
| _constructorReferences.clear(); |
| |
| _addFragment(declarationFragment); |
| |
| offsetMap.registerNamedDeclarationFragment(identifier, declarationFragment); |
| } |
| |
| @override |
| void addNamedMixinApplication({ |
| required List<MetadataBuilder>? metadata, |
| required String name, |
| required List<TypeParameterFragment>? typeParameters, |
| required Modifiers modifiers, |
| required TypeBuilder? supertype, |
| required List<TypeBuilder> mixins, |
| required List<TypeBuilder>? interfaces, |
| required int startOffset, |
| required int nameOffset, |
| required int endOffset, |
| }) { |
| LookupScope typeParameterScope = endNamedMixinApplication(name); |
| |
| NominalParameterNameSpace nominalParameterNameSpace = |
| _nominalParameterNameSpaces.pop(); |
| |
| _addFragment( |
| new NamedMixinApplicationFragment( |
| name: name, |
| fileUri: _compilationUnit.fileUri, |
| startOffset: startOffset, |
| nameOffset: nameOffset, |
| endOffset: endOffset, |
| modifiers: modifiers, |
| metadata: metadata, |
| typeParameters: typeParameters, |
| typeParameterScope: typeParameterScope, |
| nominalParameterNameSpace: nominalParameterNameSpace, |
| supertype: supertype, |
| mixins: mixins, |
| interfaces: interfaces, |
| enclosingScope: _compilationUnitScope, |
| enclosingCompilationUnit: _compilationUnit, |
| ), |
| ); |
| } |
| |
| @override |
| void addExtensionDeclaration({ |
| required OffsetMap offsetMap, |
| required Token beginToken, |
| required List<MetadataBuilder>? metadata, |
| required Modifiers modifiers, |
| required Identifier? identifier, |
| required List<TypeParameterFragment>? typeParameters, |
| required TypeBuilder onType, |
| required int startOffset, |
| required int endOffset, |
| }) { |
| ExtensionFragment declarationFragment = endExtensionDeclaration(); |
| |
| bool isPatch = |
| _compilationUnit.forPatchLibrary && _hasPatchAnnotation(metadata); |
| if (isPatch) { |
| modifiers |= Modifiers.Augment; |
| } |
| |
| declarationFragment.metadata = metadata; |
| declarationFragment.modifiers = modifiers; |
| declarationFragment.onType = onType; |
| declarationFragment.startOffset = startOffset; |
| declarationFragment.endOffset = endOffset; |
| |
| _constructorReferences.clear(); |
| |
| _addFragment(declarationFragment); |
| |
| if (identifier != null) { |
| offsetMap.registerNamedDeclarationFragment( |
| identifier, |
| declarationFragment, |
| ); |
| } else { |
| offsetMap.registerUnnamedDeclaration(beginToken, declarationFragment); |
| } |
| } |
| |
| @override |
| void addExtensionTypeDeclaration({ |
| required OffsetMap offsetMap, |
| required List<MetadataBuilder>? metadata, |
| required Modifiers modifiers, |
| required Identifier identifier, |
| required List<TypeParameterFragment>? typeParameters, |
| required List<TypeBuilder>? interfaces, |
| required int startOffset, |
| required int endOffset, |
| }) { |
| ExtensionTypeFragment declarationFragment = endExtensionTypeDeclaration(); |
| |
| declarationFragment.metadata = metadata; |
| declarationFragment.modifiers = modifiers; |
| declarationFragment.interfaces = interfaces; |
| declarationFragment.constructorReferences = |
| new List<ConstructorReferenceBuilder>.of(_constructorReferences); |
| declarationFragment.startOffset = startOffset; |
| declarationFragment.endOffset = endOffset; |
| |
| _constructorReferences.clear(); |
| |
| _addFragment(declarationFragment); |
| offsetMap.registerNamedDeclarationFragment(identifier, declarationFragment); |
| } |
| |
| @override |
| void addFunctionTypeAlias( |
| List<MetadataBuilder>? metadata, |
| String name, |
| List<TypeParameterFragment>? typeParameters, |
| TypeBuilder type, |
| int nameOffset, |
| ) { |
| NominalParameterNameSpace nominalParameterNameSpace = |
| _nominalParameterNameSpaces.pop(); |
| LookupScope typeParameterScope = _typeScopes.current.lookupScope; |
| |
| // Nested declaration began in `OutlineBuilder.beginFunctionTypeAlias`. |
| endTypedef(); |
| TypedefFragment fragment = new TypedefFragment( |
| metadata: metadata, |
| name: name, |
| typeParameters: typeParameters, |
| type: type, |
| fileUri: _compilationUnit.fileUri, |
| nameOffset: nameOffset, |
| typeParameterScope: typeParameterScope, |
| nominalParameterNameSpace: nominalParameterNameSpace, |
| enclosingScope: _compilationUnitScope, |
| enclosingCompilationUnit: _compilationUnit, |
| ); |
| _addFragment(fragment); |
| } |
| |
| @override |
| void addClassMethod({ |
| required OffsetMap offsetMap, |
| required List<MetadataBuilder>? metadata, |
| required Identifier identifier, |
| required String name, |
| required TypeBuilder? returnType, |
| required List<FormalParameterBuilder>? formals, |
| required List<TypeParameterFragment>? typeParameters, |
| required Token? beginInitializers, |
| required int startOffset, |
| required int endOffset, |
| required int nameOffset, |
| required int formalsOffset, |
| required Modifiers modifiers, |
| required bool inConstructor, |
| required bool isStatic, |
| required bool isConstructor, |
| required bool forAbstractClassOrMixin, |
| required bool isExtensionMember, |
| required bool isExtensionTypeMember, |
| required AsyncMarker asyncModifier, |
| required String? nativeMethodName, |
| required ProcedureKind? kind, |
| }) { |
| DeclarationFragmentImpl declarationFragment = _declarationFragments.current; |
| // TODO(johnniwinther): Avoid discrepancy between [inConstructor] and |
| // [isConstructor]. The former is based on the enclosing declaration name |
| // and get/set keyword. The latter also takes initializers into account. |
| |
| if (isConstructor) { |
| switch (declarationFragment) { |
| case ExtensionFragment(): |
| case ExtensionTypeFragment(): |
| // Discard type parameters declared on the constructor. It's not |
| // allowed, an error has already been issued and it will cause |
| // crashes later if they are kept/added to the ones from the parent. |
| // TODO(johnniwinther): This will cause us issuing errors about not |
| // knowing the names of what we discard here. Is there a way to |
| // preserve them? |
| typeParameters = null; |
| case ClassFragment(): |
| case MixinFragment(): |
| case EnumFragment(): |
| } |
| ConstructorName constructorName = computeAndValidateConstructorName( |
| declarationFragment, |
| identifier, |
| ); |
| addConstructor( |
| offsetMap: offsetMap, |
| metadata: metadata, |
| modifiers: modifiers, |
| identifier: identifier, |
| constructorName: constructorName, |
| typeParameters: typeParameters, |
| formals: formals, |
| startOffset: startOffset, |
| formalsOffset: formalsOffset, |
| endOffset: endOffset, |
| nativeMethodName: nativeMethodName, |
| beginInitializers: beginInitializers, |
| forAbstractClassOrMixin: forAbstractClassOrMixin, |
| ); |
| } else { |
| switch (kind!) { |
| case ProcedureKind.Method: |
| case ProcedureKind.Operator: |
| addMethod( |
| offsetMap: offsetMap, |
| metadata: metadata, |
| modifiers: modifiers, |
| returnType: returnType, |
| identifier: identifier, |
| name: name, |
| typeParameters: typeParameters, |
| formals: formals, |
| isOperator: kind == ProcedureKind.Operator, |
| startOffset: startOffset, |
| nameOffset: nameOffset, |
| formalsOffset: formalsOffset, |
| endOffset: endOffset, |
| nativeMethodName: nativeMethodName, |
| asyncModifier: asyncModifier, |
| isInstanceMember: !isStatic, |
| isExtensionMember: isExtensionMember, |
| isExtensionTypeMember: isExtensionTypeMember, |
| ); |
| case ProcedureKind.Getter: |
| addGetter( |
| offsetMap: offsetMap, |
| metadata: metadata, |
| modifiers: modifiers, |
| returnType: returnType, |
| identifier: identifier, |
| name: name, |
| typeParameters: typeParameters, |
| formals: formals, |
| startOffset: startOffset, |
| nameOffset: nameOffset, |
| formalsOffset: formalsOffset, |
| endOffset: endOffset, |
| nativeMethodName: nativeMethodName, |
| asyncModifier: asyncModifier, |
| isInstanceMember: !isStatic, |
| isExtensionMember: isExtensionMember, |
| isExtensionTypeMember: isExtensionTypeMember, |
| ); |
| case ProcedureKind.Setter: |
| addSetter( |
| offsetMap: offsetMap, |
| metadata: metadata, |
| modifiers: modifiers, |
| returnType: returnType, |
| identifier: identifier, |
| name: name, |
| typeParameters: typeParameters, |
| formals: formals, |
| startOffset: startOffset, |
| nameOffset: nameOffset, |
| formalsOffset: formalsOffset, |
| endOffset: endOffset, |
| nativeMethodName: nativeMethodName, |
| asyncModifier: asyncModifier, |
| isInstanceMember: !isStatic, |
| isExtensionMember: isExtensionMember, |
| isExtensionTypeMember: isExtensionTypeMember, |
| ); |
| // Coverage-ignore(suite): Not run. |
| case ProcedureKind.Factory: |
| throw new UnsupportedError("Unexpected procedure kind: $kind"); |
| } |
| } |
| } |
| |
| @override |
| void addPrimaryConstructor({ |
| required OffsetMap offsetMap, |
| required Token beginToken, |
| required String? name, |
| required List<FormalParameterBuilder>? formals, |
| required int startOffset, |
| required int? nameOffset, |
| required int formalsOffset, |
| required bool isConst, |
| }) { |
| DeclarationFragmentImpl enclosingDeclaration = |
| _declarationFragments.current; |
| |
| NominalParameterNameSpace nominalParameterNameSpace = |
| new NominalParameterNameSpace(); |
| _nominalParameterNameSpaces.push(nominalParameterNameSpace); |
| _typeScopes.push( |
| new TypeScope( |
| TypeScopeKind.memberTypeParameters, |
| new NominalParameterScope( |
| _typeScopes.current.lookupScope, |
| nominalParameterNameSpace, |
| ), |
| _typeScopes.current, |
| ), |
| ); |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.memberTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| |
| ConstructorName constructorName; |
| String declarationName = enclosingDeclaration.name; |
| if (name == 'new') { |
| constructorName = new ConstructorName( |
| name: '', |
| nameOffset: nameOffset!, |
| fullName: declarationName, |
| fullNameOffset: nameOffset, |
| fullNameLength: noLength, |
| ); |
| } else if (name != null) { |
| constructorName = new ConstructorName( |
| name: name, |
| nameOffset: nameOffset!, |
| fullName: '$declarationName.$name', |
| fullNameOffset: nameOffset, |
| fullNameLength: noLength, |
| ); |
| } else { |
| constructorName = new ConstructorName( |
| name: '', |
| nameOffset: null, |
| fullName: declarationName, |
| fullNameOffset: formalsOffset, |
| fullNameLength: noLength, |
| ); |
| } |
| NominalParameterNameSpace typeParameterNameSpace = |
| _nominalParameterNameSpaces.pop(); |
| |
| PrimaryConstructorFragment fragment = new PrimaryConstructorFragment( |
| constructorName: constructorName, |
| fileUri: _compilationUnit.fileUri, |
| startOffset: startOffset, |
| formalsOffset: formalsOffset, |
| modifiers: isConst ? Modifiers.Const : Modifiers.empty, |
| returnType: addInferableType(), |
| typeParameterNameSpace: typeParameterNameSpace, |
| typeParameterScope: typeParameterScope.lookupScope, |
| formals: formals, |
| forAbstractClassOrMixin: false, |
| enclosingDeclaration: enclosingDeclaration, |
| enclosingCompilationUnit: _compilationUnit, |
| beginInitializers: 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. |
| // TODO(johnniwinther): Avoid using a dummy token to ensure building |
| // of constant constructors in the outline phase. |
| ? new Token.eof(-1) |
| : null, |
| ); |
| |
| _addFragment(fragment); |
| if (isConst) { |
| enclosingDeclaration.declaresConstConstructor = true; |
| } |
| |
| offsetMap.registerPrimaryConstructor(beginToken, fragment); |
| } |
| |
| @override |
| void addConstructor({ |
| required OffsetMap offsetMap, |
| required List<MetadataBuilder>? metadata, |
| required Modifiers modifiers, |
| required Identifier identifier, |
| required ConstructorName constructorName, |
| required List<TypeParameterFragment>? typeParameters, |
| required List<FormalParameterBuilder>? formals, |
| required int startOffset, |
| required int formalsOffset, |
| required int endOffset, |
| required String? nativeMethodName, |
| required Token? beginInitializers, |
| required bool forAbstractClassOrMixin, |
| }) { |
| DeclarationFragmentImpl enclosingDeclaration = |
| _declarationFragments.current; |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.memberTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| NominalParameterNameSpace typeParameterNameSpace = |
| _nominalParameterNameSpaces.pop(); |
| |
| bool isPatch = |
| _compilationUnit.forPatchLibrary && _hasPatchAnnotation(metadata); |
| if (isPatch) { |
| modifiers |= Modifiers.Augment; |
| } |
| ConstructorFragment fragment = new ConstructorFragment( |
| constructorName: constructorName, |
| fileUri: _compilationUnit.fileUri, |
| startOffset: startOffset, |
| formalsOffset: formalsOffset, |
| endOffset: endOffset, |
| modifiers: modifiers - Modifiers.Abstract, |
| metadata: metadata, |
| returnType: addInferableType(), |
| typeParameters: typeParameters, |
| typeParameterNameSpace: typeParameterNameSpace, |
| enclosingScope: _declarationFragments.current.bodyScope, |
| typeParameterScope: typeParameterScope.lookupScope, |
| formals: formals, |
| nativeMethodName: nativeMethodName, |
| forAbstractClassOrMixin: forAbstractClassOrMixin, |
| enclosingDeclaration: enclosingDeclaration, |
| enclosingCompilationUnit: _compilationUnit, |
| beginInitializers: |
| modifiers.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. |
| // TODO(johnniwinther): Avoid using a dummy token to ensure building |
| // of constant constructors in the outline phase. |
| ? (beginInitializers ?? new Token.eof(-1)) |
| : null, |
| ); |
| |
| _addFragment(fragment); |
| if (nativeMethodName != null) { |
| _nativeMethodRegistry.registerNativeConstructorFragment(fragment); |
| } |
| if (modifiers.isConst) { |
| enclosingDeclaration.declaresConstConstructor = true; |
| } |
| offsetMap.registerConstructorFragment(identifier, fragment); |
| } |
| |
| @override |
| void addPrimaryConstructorField({ |
| required List<MetadataBuilder>? metadata, |
| required TypeBuilder type, |
| required String name, |
| required int nameOffset, |
| }) { |
| _declarationFragments.current.addPrimaryConstructorField( |
| _addPrimaryConstructorField( |
| metadata: metadata, |
| type: type, |
| name: name, |
| nameOffset: nameOffset, |
| ), |
| ); |
| } |
| |
| @override |
| void addFactoryMethod({ |
| required OffsetMap offsetMap, |
| required List<MetadataBuilder>? metadata, |
| required Modifiers modifiers, |
| required Identifier identifier, |
| required List<FormalParameterBuilder>? formals, |
| required ConstructorReferenceBuilder? redirectionTarget, |
| required int startOffset, |
| required int nameOffset, |
| required int formalsOffset, |
| required int endOffset, |
| required String? nativeMethodName, |
| required AsyncMarker asyncModifier, |
| }) { |
| DeclarationFragmentImpl enclosingDeclaration = |
| _declarationFragments.current; |
| |
| ConstructorName constructorName = computeAndValidateConstructorName( |
| enclosingDeclaration, |
| identifier, |
| isFactory: true, |
| ); |
| |
| NominalParameterNameSpace typeParameterNameSpace = |
| _nominalParameterNameSpaces.pop(); |
| |
| bool isPatch = |
| _compilationUnit.forPatchLibrary && _hasPatchAnnotation(metadata); |
| if (isPatch) { |
| modifiers |= Modifiers.Augment; |
| } |
| FactoryFragment fragment = new FactoryFragment( |
| constructorName: constructorName, |
| fileUri: _compilationUnit.fileUri, |
| startOffset: startOffset, |
| formalsOffset: formalsOffset, |
| endOffset: endOffset, |
| modifiers: modifiers, |
| metadata: metadata, |
| typeParameterNameSpace: typeParameterNameSpace, |
| enclosingScope: _declarationFragments.current.bodyScope, |
| typeParameterScope: _typeScopes.current.lookupScope, |
| formals: formals, |
| asyncModifier: asyncModifier, |
| nativeMethodName: nativeMethodName, |
| redirectionTarget: redirectionTarget, |
| enclosingDeclaration: enclosingDeclaration, |
| enclosingCompilationUnit: _compilationUnit, |
| ); |
| |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.memberTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| |
| _addFragment(fragment); |
| if (nativeMethodName != null) { |
| _nativeMethodRegistry.registerNativeFactoryFragment(fragment); |
| } |
| offsetMap.registerFactoryFragment(identifier, fragment); |
| } |
| |
| @override |
| ConstructorReferenceBuilder addConstructorReference( |
| TypeName name, |
| List<TypeBuilder>? typeArguments, |
| String? suffix, |
| int charOffset, |
| ) { |
| ConstructorReferenceBuilder ref = new ConstructorReferenceBuilder( |
| name, |
| typeArguments, |
| suffix, |
| _compilationUnit.fileUri, |
| charOffset, |
| ); |
| _constructorReferences.add(ref); |
| return ref; |
| } |
| |
| @override |
| ConstructorReferenceBuilder? addUnnamedConstructorReference( |
| List<TypeBuilder>? typeArguments, |
| Identifier? suffix, |
| int charOffset, |
| ) { |
| // At the moment, the name of the type in a constructor reference can be |
| // omitted only within an enum element declaration. |
| DeclarationFragmentImpl enclosingDeclaration = |
| _declarationFragments.current; |
| if (enclosingDeclaration.kind == DeclarationFragmentKind.enumDeclaration) { |
| if (libraryFeatures.enhancedEnums.isEnabled) { |
| int constructorNameOffset = suffix?.nameOffset ?? charOffset; |
| return addConstructorReference( |
| new SyntheticTypeName( |
| enclosingDeclaration.name, |
| constructorNameOffset, |
| ), |
| typeArguments, |
| suffix?.name, |
| constructorNameOffset, |
| ); |
| } else { |
| // Coverage-ignore-block(suite): Not run. |
| // For entries that consist of their name only, all of the elements |
| // of the constructor reference should be null. |
| if (typeArguments != null || suffix != null) { |
| _compilationUnit.reportFeatureNotEnabled( |
| libraryFeatures.enhancedEnums, |
| _compilationUnit.fileUri, |
| charOffset, |
| noLength, |
| ); |
| } |
| return null; |
| } |
| } else { |
| internalProblem( |
| codeInternalProblemOmittedTypeNameInConstructorReference, |
| charOffset, |
| _compilationUnit.fileUri, |
| ); |
| } |
| } |
| |
| @override |
| ConstructorName computeAndValidateConstructorName( |
| DeclarationFragmentImpl enclosingDeclaration, |
| Identifier identifier, { |
| isFactory = false, |
| }) { |
| String className = enclosingDeclaration.name; |
| String prefix; |
| String? suffix; |
| int? suffixOffset; |
| String fullName; |
| int fullNameOffset; |
| int fullNameLength; |
| int charOffset; |
| if (identifier is QualifiedNameIdentifier) { |
| Identifier qualifier = identifier.qualifier; |
| prefix = qualifier.name; |
| suffix = identifier.name; |
| suffixOffset = identifier.nameOffset; |
| charOffset = qualifier.nameOffset; |
| String prefixAndSuffix = '${prefix}.${suffix}'; |
| fullNameOffset = qualifier.nameOffset; |
| // If the there is no space between the prefix and suffix we use the full |
| // length as the name length. Otherwise the full name has no length. |
| fullNameLength = fullNameOffset + prefix.length + 1 == suffixOffset |
| ? prefixAndSuffix.length |
| : noLength; |
| if (suffix == "new") { |
| // Normalize `Class.new` to `Class`. |
| suffix = ''; |
| fullName = className; |
| } else { |
| fullName = '$className.$suffix'; |
| } |
| } else { |
| prefix = identifier.name; |
| suffix = null; |
| suffixOffset = null; |
| charOffset = identifier.nameOffset; |
| fullName = prefix; |
| fullNameOffset = identifier.nameOffset; |
| fullNameLength = prefix.length; |
| } |
| |
| if (prefix == className) { |
| return new ConstructorName( |
| name: suffix ?? '', |
| nameOffset: suffixOffset, |
| fullName: fullName, |
| fullNameOffset: fullNameOffset, |
| fullNameLength: fullNameLength, |
| ); |
| } else if (suffix == null) { |
| // Normalize `foo` in `Class` to `Class.foo`. |
| fullName = '$className.$prefix'; |
| } |
| if (suffix == null && !isFactory) { |
| // This method is called because the syntax indicated that this is a |
| // constructor, either because it had qualified name or because the method |
| // had an initializer list. |
| // |
| // In either case this is reported elsewhere, and since the name is a |
| // legal name for a regular method, we don't remove an error on the name. |
| } else { |
| _problemReporting.addProblem( |
| codeConstructorWithWrongName, |
| charOffset, |
| prefix.length, |
| _compilationUnit.fileUri, |
| context: [ |
| codeConstructorWithWrongNameContext |
| .withArgumentsOld(enclosingDeclaration.name) |
| .withLocation2(enclosingDeclaration.uriOffset), |
| ], |
| ); |
| } |
| |
| return new ConstructorName( |
| name: suffix ?? prefix, |
| nameOffset: suffixOffset, |
| fullName: fullName, |
| fullNameOffset: fullNameOffset, |
| fullNameLength: fullNameLength, |
| ); |
| } |
| |
| @override |
| void addGetter({ |
| required OffsetMap offsetMap, |
| required List<MetadataBuilder>? metadata, |
| required Modifiers modifiers, |
| required TypeBuilder? returnType, |
| required Identifier identifier, |
| required String name, |
| required List<TypeParameterFragment>? typeParameters, |
| required List<FormalParameterBuilder>? formals, |
| required int startOffset, |
| required int nameOffset, |
| required int formalsOffset, |
| required int endOffset, |
| required String? nativeMethodName, |
| required AsyncMarker asyncModifier, |
| required bool isInstanceMember, |
| required bool isExtensionMember, |
| required bool isExtensionTypeMember, |
| }) { |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.memberTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| |
| DeclarationFragmentImpl? enclosingDeclaration = |
| _declarationFragments.currentOrNull; |
| assert( |
| !isExtensionMember || |
| enclosingDeclaration?.kind == |
| DeclarationFragmentKind.extensionDeclaration, |
| ); |
| assert( |
| !isExtensionTypeMember || |
| enclosingDeclaration?.kind == |
| DeclarationFragmentKind.extensionTypeDeclaration, |
| ); |
| |
| NominalParameterNameSpace typeParameterNameSpace = |
| _nominalParameterNameSpaces.pop(); |
| |
| bool isPatch = |
| _compilationUnit.forPatchLibrary && _hasPatchAnnotation(metadata); |
| if (isPatch) { |
| modifiers |= Modifiers.Augment; |
| } |
| GetterFragment fragment = new GetterFragment( |
| name: name, |
| fileUri: _compilationUnit.fileUri, |
| startOffset: startOffset, |
| nameOffset: nameOffset, |
| formalsOffset: formalsOffset, |
| endOffset: endOffset, |
| isTopLevel: enclosingDeclaration == null, |
| metadata: metadata, |
| modifiers: modifiers, |
| returnType: returnType ?? addInferableType(), |
| declaredTypeParameters: typeParameters, |
| typeParameterNameSpace: typeParameterNameSpace, |
| enclosingScope: enclosingDeclaration?.bodyScope ?? _compilationUnitScope, |
| typeParameterScope: typeParameterScope.lookupScope, |
| declaredFormals: formals, |
| asyncModifier: asyncModifier, |
| nativeMethodName: nativeMethodName, |
| enclosingCompilationUnit: _compilationUnit, |
| enclosingDeclaration: enclosingDeclaration, |
| ); |
| _addFragment(fragment); |
| if (nativeMethodName != null) { |
| _nativeMethodRegistry.registerNativeGetterFragment(fragment); |
| } |
| offsetMap.registerGetter(identifier, fragment); |
| } |
| |
| @override |
| void addSetter({ |
| required OffsetMap offsetMap, |
| required List<MetadataBuilder>? metadata, |
| required Modifiers modifiers, |
| required TypeBuilder? returnType, |
| required Identifier identifier, |
| required String name, |
| required List<TypeParameterFragment>? typeParameters, |
| required List<FormalParameterBuilder>? formals, |
| required int startOffset, |
| required int nameOffset, |
| required int formalsOffset, |
| required int endOffset, |
| required String? nativeMethodName, |
| required AsyncMarker asyncModifier, |
| required bool isInstanceMember, |
| required bool isExtensionMember, |
| required bool isExtensionTypeMember, |
| }) { |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.memberTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| |
| DeclarationFragmentImpl? enclosingDeclaration = |
| _declarationFragments.currentOrNull; |
| assert( |
| !isExtensionMember || |
| enclosingDeclaration?.kind == |
| DeclarationFragmentKind.extensionDeclaration, |
| ); |
| assert( |
| !isExtensionTypeMember || |
| enclosingDeclaration?.kind == |
| DeclarationFragmentKind.extensionTypeDeclaration, |
| ); |
| |
| if (returnType == null) { |
| returnType = addVoidType(nameOffset); |
| } |
| |
| NominalParameterNameSpace typeParameterNameSpace = |
| _nominalParameterNameSpaces.pop(); |
| |
| bool isPatch = |
| _compilationUnit.forPatchLibrary && _hasPatchAnnotation(metadata); |
| if (isPatch) { |
| modifiers |= Modifiers.Augment; |
| } |
| SetterFragment fragment = new SetterFragment( |
| name: name, |
| fileUri: _compilationUnit.fileUri, |
| startOffset: startOffset, |
| nameOffset: nameOffset, |
| formalsOffset: formalsOffset, |
| endOffset: endOffset, |
| isTopLevel: enclosingDeclaration == null, |
| metadata: metadata, |
| modifiers: modifiers, |
| returnType: returnType, |
| declaredTypeParameters: typeParameters, |
| typeParameterNameSpace: typeParameterNameSpace, |
| enclosingScope: enclosingDeclaration?.bodyScope ?? _compilationUnitScope, |
| typeParameterScope: typeParameterScope.lookupScope, |
| declaredFormals: formals, |
| asyncModifier: asyncModifier, |
| nativeMethodName: nativeMethodName, |
| enclosingDeclaration: enclosingDeclaration, |
| enclosingCompilationUnit: _compilationUnit, |
| ); |
| _addFragment(fragment); |
| if (nativeMethodName != null) { |
| _nativeMethodRegistry.registerNativeSetterFragment(fragment); |
| } |
| offsetMap.registerSetter(identifier, fragment); |
| } |
| |
| @override |
| void addMethod({ |
| required OffsetMap offsetMap, |
| required List<MetadataBuilder>? metadata, |
| required Modifiers modifiers, |
| required TypeBuilder? returnType, |
| required Identifier identifier, |
| required String name, |
| required List<TypeParameterFragment>? typeParameters, |
| required List<FormalParameterBuilder>? formals, |
| required int startOffset, |
| required int nameOffset, |
| required int formalsOffset, |
| required int endOffset, |
| required String? nativeMethodName, |
| required AsyncMarker asyncModifier, |
| required bool isInstanceMember, |
| required bool isExtensionMember, |
| required bool isExtensionTypeMember, |
| required bool isOperator, |
| }) { |
| TypeScope typeParameterScope = _typeScopes.pop(); |
| assert( |
| typeParameterScope.kind == TypeScopeKind.memberTypeParameters, |
| "Unexpected type scope: $typeParameterScope.", |
| ); |
| |
| DeclarationFragmentImpl? enclosingDeclaration = |
| _declarationFragments.currentOrNull; |
| assert( |
| !isExtensionMember || |
| enclosingDeclaration?.kind == |
| DeclarationFragmentKind.extensionDeclaration, |
| ); |
| assert( |
| !isExtensionTypeMember || |
| enclosingDeclaration?.kind == |
| DeclarationFragmentKind.extensionTypeDeclaration, |
| ); |
| |
| if (returnType == null) { |
| if (isOperator && identical(name, indexSetName.text)) { |
| returnType = addVoidType(nameOffset); |
| } |
| } |
| |
| NominalParameterNameSpace typeParameterNameSpace = |
| _nominalParameterNameSpaces.pop(); |
| |
| bool isPatch = |
| _compilationUnit.forPatchLibrary && _hasPatchAnnotation(metadata); |
| if (isPatch) { |
| modifiers |= Modifiers.Augment; |
| } |
| MethodFragment fragment = new MethodFragment( |
| name: name, |
| fileUri: _compilationUnit.fileUri, |
| startOffset: startOffset, |
| nameOffset: nameOffset, |
| formalsOffset: formalsOffset, |
| endOffset: endOffset, |
| isTopLevel: enclosingDeclaration == null, |
| metadata: metadata, |
| modifiers: modifiers, |
| returnType: returnType ?? addInferableType(), |
| declaredTypeParameters: typeParameters, |
| typeParameterNameSpace: typeParameterNameSpace, |
| enclosingScope: enclosingDeclaration?.bodyScope ?? _compilationUnitScope, |
| typeParameterScope: typeParameterScope.lookupScope, |
| declaredFormals: formals, |
| isOperator: isOperator, |
| asyncModifier: asyncModifier, |
| nativeMethodName: nativeMethodName, |
| enclosingDeclaration: enclosingDeclaration, |
| enclosingCompilationUnit: _compilationUnit, |
| ); |
| _addFragment(fragment); |
| if (nativeMethodName != null) { |
| _nativeMethodRegistry.registerNativeMethodFragment(fragment); |
| } |
| offsetMap.registerMethod(identifier, fragment); |
| } |
| |
| @override |
| void addFields( |
| OffsetMap offsetMap, |
| List<MetadataBuilder>? metadata, |
| Modifiers modifiers, |
| bool isTopLevel, |
| TypeBuilder? type, |
| List<FieldInfo> fieldInfos, |
| ) { |
| for (FieldInfo info in fieldInfos) { |
| bool isConst = modifiers.isConst; |
| bool isFinal = modifiers.isFinal; |
| 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: metadata, |
| modifiers: modifiers, |
| isTopLevel: isTopLevel, |
| type: type ?? addInferableType(), |
| name: info.identifier.name, |
| nameOffset: info.identifier.nameOffset, |
| endOffset: info.endOffset, |
| initializerToken: startToken, |
| hasInitializer: hasInitializer, |
| constInitializerToken: potentiallyNeedInitializerInOutline |
| ? startToken |
| : null, |
| ), |
| ); |
| } |
| } |
| |
| FieldFragment _addField({ |
| required List<MetadataBuilder>? metadata, |
| required Modifiers modifiers, |
| required bool isTopLevel, |
| required TypeBuilder type, |
| required String name, |
| required int nameOffset, |
| required int endOffset, |
| required Token? initializerToken, |
| required bool hasInitializer, |
| Token? constInitializerToken, |
| }) { |
| DeclarationFragmentImpl? enclosingDeclaration = |
| _declarationFragments.currentOrNull; |
| if (hasInitializer) { |
| modifiers |= Modifiers.HasInitializer; |
| } |
| FieldFragment fragment = new FieldFragment( |
| name: name, |
| fileUri: _compilationUnit.fileUri, |
| nameOffset: nameOffset, |
| endOffset: endOffset, |
| initializerToken: initializerToken, |
| constInitializerToken: constInitializerToken, |
| metadata: metadata, |
| type: type, |
| isTopLevel: isTopLevel, |
| modifiers: modifiers, |
| enclosingScope: enclosingDeclaration?.bodyScope ?? _compilationUnitScope, |
| enclosingDeclaration: enclosingDeclaration, |
| enclosingCompilationUnit: _compilationUnit, |
| ); |
| _addFragment(fragment); |
| return fragment; |
| } |
| |
| PrimaryConstructorFieldFragment _addPrimaryConstructorField({ |
| required List<MetadataBuilder>? metadata, |
| required TypeBuilder type, |
| required String name, |
| required int nameOffset, |
| }) { |
| DeclarationFragmentImpl enclosingDeclaration = |
| _declarationFragments.current; |
| PrimaryConstructorFieldFragment fragment = |
| new PrimaryConstructorFieldFragment( |
| name: name, |
| fileUri: _compilationUnit.fileUri, |
| nameOffset: nameOffset, |
| metadata: metadata, |
| type: type, |
| enclosingScope: enclosingDeclaration.bodyScope, |
| enclosingDeclaration: enclosingDeclaration, |
| enclosingCompilationUnit: _compilationUnit, |
| ); |
| _addFragment(fragment); |
| return fragment; |
| } |
| |
| @override |
| FormalParameterBuilder addFormalParameter( |
| List<MetadataBuilder>? metadata, |
| FormalParameterKind kind, |
| Modifiers modifiers, |
| TypeBuilder type, |
| String name, |
| bool hasThis, |
| bool hasSuper, |
| int charOffset, |
| Token? initializerToken, { |
| bool lowerWildcard = false, |
| }) { |
| assert( |
| !hasThis || !hasSuper, |
| "Formal parameter '${name}' has both 'this' and 'super' prefixes.", |
| ); |
| if (hasThis) { |
| modifiers |= Modifiers.InitializingFormal; |
| } |
| if (hasSuper) { |
| modifiers |= Modifiers.SuperInitializingFormal; |
| } |
| String formalName = name; |
| bool isWildcard = |
| libraryFeatures.wildcardVariables.isEnabled && formalName == '_'; |
| if (isWildcard && lowerWildcard) { |
| formalName = createWildcardFormalParameterName(wildcardVariableIndex); |
| wildcardVariableIndex++; |
| } |
| FormalParameterBuilder formal = new FormalParameterBuilder( |
| kind, |
| modifiers, |
| type, |
| formalName, |
| charOffset, |
| fileUri: _compilationUnit.fileUri, |
| hasImmediatelyDeclaredInitializer: initializerToken != null, |
| isWildcard: isWildcard, |
| )..initializerToken = initializerToken; |
| return formal; |
| } |
| |
| @override |
| TypeBuilder addNamedType( |
| TypeName typeName, |
| NullabilityBuilder nullabilityBuilder, |
| List<TypeBuilder>? arguments, |
| int charOffset, { |
| required InstanceTypeParameterAccessState instanceTypeParameterAccess, |
| }) { |
| return _registerUnresolvedNamedType( |
| new NamedTypeBuilderImpl( |
| typeName, |
| nullabilityBuilder, |
| arguments: arguments, |
| fileUri: _compilationUnit.fileUri, |
| charOffset: charOffset, |
| instanceTypeParameterAccess: instanceTypeParameterAccess, |
| ), |
| ); |
| } |
| |
| NamedTypeBuilder _registerUnresolvedNamedType(NamedTypeBuilder type) { |
| _typeScopes.current.registerUnresolvedNamedType(type); |
| return type; |
| } |
| |
| @override |
| FunctionTypeBuilder addFunctionType( |
| TypeBuilder returnType, |
| List<SourceStructuralParameterBuilder>? 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, |
| ); |
| _checkStructuralParameters(structuralVariableBuilders); |
| if (structuralVariableBuilders != null) { |
| for (SourceStructuralParameterBuilder builder |
| in structuralVariableBuilders) { |
| if (builder.metadata != null) { |
| if (!libraryFeatures.genericMetadata.isEnabled) { |
| _problemReporting.addProblem( |
| codeAnnotationOnFunctionTypeTypeParameter, |
| builder.fileOffset, |
| builder.name.length, |
| builder.fileUri, |
| ); |
| } |
| } |
| } |
| } |
| // Nested declaration began in `OutlineBuilder.beginFunctionType` or |
| // `OutlineBuilder.beginFunctionTypedFormalParameter`. |
| endFunctionType(); |
| return builder; |
| } |
| |
| void _checkStructuralParameters( |
| List<StructuralParameterBuilder>? typeParameters, |
| ) { |
| Map<String, StructuralParameterBuilder> typeParametersByName = |
| _structuralParameterScopes.pop(); |
| if (typeParameters == null || typeParameters.isEmpty) return null; |
| for (StructuralParameterBuilder tv in typeParameters) { |
| if (tv.isWildcard) continue; |
| StructuralParameterBuilder? existing = typeParametersByName[tv.name]; |
| if (existing != null) { |
| // Coverage-ignore-block(suite): Not run. |
| _problemReporting.addProblem( |
| codeTypeParameterDuplicatedName, |
| tv.fileOffset, |
| tv.name.length, |
| _compilationUnit.fileUri, |
| context: [ |
| codeTypeParameterDuplicatedNameCause |
| .withArgumentsOld(tv.name) |
| .withLocation( |
| _compilationUnit.fileUri, |
| existing.fileOffset, |
| existing.name.length, |
| ), |
| ], |
| ); |
| } else { |
| typeParametersByName[tv.name] = tv; |
| } |
| } |
| } |
| |
| @override |
| TypeBuilder addVoidType(int charOffset) { |
| return new VoidTypeBuilder(_compilationUnit.fileUri, charOffset); |
| } |
| |
| @override |
| TypeParameterFragment addNominalParameter({ |
| required List<MetadataBuilder>? metadata, |
| required String name, |
| required int nameOffset, |
| required Uri fileUri, |
| required TypeParameterKind kind, |
| }) { |
| String variableName = name; |
| bool isWildcard = |
| libraryFeatures.wildcardVariables.isEnabled && variableName == '_'; |
| if (isWildcard) { |
| variableName = createWildcardTypeParameterName(wildcardVariableIndex); |
| wildcardVariableIndex++; |
| } |
| TypeParameterFragment fragment = new TypeParameterFragment( |
| metadata: metadata, |
| name: name, |
| nameOffset: nameOffset, |
| fileUri: fileUri, |
| kind: kind, |
| isWildcard: isWildcard, |
| variableName: variableName, |
| typeParameterScope: _typeScopes.current.lookupScope, |
| ); |
| return fragment; |
| } |
| |
| @override |
| StructuralParameterBuilder addStructuralParameter({ |
| required List<MetadataBuilder>? metadata, |
| required String name, |
| required int nameOffset, |
| required Uri fileUri, |
| }) { |
| String variableName = name; |
| bool isWildcard = |
| libraryFeatures.wildcardVariables.isEnabled && variableName == '_'; |
| if (isWildcard) { |
| variableName = createWildcardTypeParameterName(wildcardVariableIndex); |
| wildcardVariableIndex++; |
| } |
| return _typeParameterFactory.createStructuralParameterBuilder( |
| new RegularStructuralParameterDeclaration( |
| metadata: metadata, |
| name: variableName, |
| fileOffset: nameOffset, |
| fileUri: fileUri, |
| isWildcard: isWildcard, |
| ), |
| metadata: metadata, |
| ); |
| } |
| |
| @override |
| void addLibraryDirective({ |
| required String? libraryName, |
| required List<MetadataBuilder>? metadata, |
| required bool isAugment, |
| }) { |
| _compilationUnitRegistry.registerLibraryDirective( |
| libraryName: libraryName, |
| metadata: metadata, |
| ); |
| } |
| |
| @override |
| InferableTypeBuilder addInferableType() { |
| return _compilationUnit.loader.inferableTypes.addInferableType(); |
| } |
| |
| void _addFragment(Fragment fragment) { |
| if (_declarationFragments.isEmpty) { |
| _libraryNameSpaceBuilder.addFragment(fragment); |
| } else { |
| _declarationFragments.current.addFragment(fragment); |
| } |
| } |
| } |
| |
| bool _hasPatchAnnotation(Iterable<MetadataBuilder>? metadata) { |
| if (metadata == null) { |
| return false; |
| } |
| for (MetadataBuilder metadataBuilder in metadata) { |
| if (metadataBuilder.hasPatch) { |
| return true; |
| } |
| } |
| return false; |
| } |