blob: fa2e5f33e1e0a2da6bc99b406b2b30802c58725c [file] [log] [blame]
// Copyright (c) 2016, 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:kernel/ast.dart' show LibraryDependency;
import '../base/combinator.dart';
import '../base/messages.dart';
import '../base/name_space.dart';
import '../base/scope.dart';
import '../base/uri_offset.dart';
import '../kernel/load_library_builder.dart' show LoadLibraryBuilder;
import '../kernel/utils.dart';
import '../source/source_library_builder.dart';
import 'builder.dart';
import 'declaration_builders.dart';
import 'library_builder.dart';
class PrefixBuilder extends BuilderImpl {
final String name;
final NameSpace _prefixNameSpace = new NameSpaceImpl();
late final LookupScope _prefixScope =
new NameSpaceLookupScope(_prefixNameSpace, ScopeKind.library, "top");
@override
final SourceLibraryBuilder parent;
final bool deferred;
@override
final Uri fileUri;
@override
final int fileOffset;
final LoadLibraryBuilder? loadLibraryBuilder;
final bool isWildcard;
PrefixBuilder(this.name, this.deferred, this.parent, this.loadLibraryBuilder,
{required this.fileUri,
required int prefixOffset,
required int importOffset})
: fileOffset = prefixOffset,
isWildcard = name == '_' {
assert(deferred == (loadLibraryBuilder != null),
"LoadLibraryBuilder must be provided iff prefix is deferred.");
if (loadLibraryBuilder != null) {
addToPrefixScope('loadLibrary', loadLibraryBuilder!,
importOffset: importOffset, prefixOffset: prefixOffset);
}
}
LookupScope get prefixScope => _prefixScope;
void forEachExtension(void Function(ExtensionBuilder) f) {
_prefixNameSpace.forEachLocalExtension(f);
}
LibraryDependency? get dependency => loadLibraryBuilder?.importDependency;
/// Lookup a member with [name] in the export scope.
Builder? lookup(String name, int charOffset, Uri fileUri) {
return _prefixScope.lookupGetable(name, charOffset, fileUri);
}
void addToPrefixScope(String name, Builder member,
{required int importOffset, required int prefixOffset}) {
if (deferred && member is ExtensionBuilder) {
parent.addProblem(templateDeferredExtensionImport.withArguments(name),
importOffset, noLength, fileUri);
}
Builder? existing =
_prefixNameSpace.lookupLocalMember(name, setter: member.isSetter);
Builder result;
if (existing != null) {
result = computeAmbiguousDeclarationForImport(
parent, name, existing, member,
uriOffset: new UriOffset(fileUri, prefixOffset));
} else {
result = member;
}
_prefixNameSpace.addLocalMember(name, result, setter: member.isSetter);
if (member is ExtensionBuilder) {
_prefixNameSpace.addExtension(member);
}
}
@override
// Coverage-ignore(suite): Not run.
String get fullNameForErrors => name;
}
class PrefixFragment {
final String name;
final SourceCompilationUnit importer;
final CompilationUnit? imported;
final List<CombinatorBuilder>? combinators;
final bool deferred;
final Uri fileUri;
final int importOffset;
final int prefixOffset;
PrefixBuilder? _builder;
PrefixFragment({
required this.name,
required this.importer,
required this.imported,
required this.combinators,
required this.deferred,
required this.fileUri,
required this.importOffset,
required this.prefixOffset,
});
PrefixBuilder createPrefixBuilder() {
LoadLibraryBuilder? loadLibraryBuilder;
if (deferred) {
loadLibraryBuilder = new LoadLibraryBuilder(
importer.libraryBuilder,
prefixOffset,
imported!,
name,
importOffset,
toCombinators(combinators));
}
return builder = new PrefixBuilder(
name, deferred, importer.libraryBuilder, loadLibraryBuilder,
fileUri: fileUri,
prefixOffset: prefixOffset,
importOffset: importOffset);
}
PrefixBuilder get builder {
assert(_builder != null, "Builder has not been computed for $this.");
return _builder!;
}
void set builder(PrefixBuilder value) {
assert(_builder == null, "Builder has already been computed for $this.");
_builder = value;
}
@override
String toString() => '$runtimeType($name,$fileUri,$importOffset)';
}