mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 08:51:21 +00:00
[cfe] Split Dill/SourceLoader and Dill/KernelTarget
This moves all implementation code from Loader and TargetImplementation down to the concrete subclasses, Dill/SourceLoader and Dill/KernelTarget, respectively, and removes all unneeded code. Since TargetImplementation is now only an interface, it replaces the role of its supertype Target. Change-Id: I8a556ac5bc559432dbd19a6a48151469a2cb0238 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/214020 Commit-Queue: Johnni Winther <johnniwinther@google.com> Reviewed-by: Jens Johansen <jensj@google.com>
This commit is contained in:
parent
6dd77ca4cc
commit
e2a689bafd
|
@ -22,7 +22,7 @@ import '../kernel/utils.dart'
|
|||
show isRedirectingGenerativeConstructorImplementation;
|
||||
import '../kernel/kernel_helper.dart' show SynthesizedFunctionNode;
|
||||
|
||||
import '../loader.dart' show Loader;
|
||||
import '../source/source_loader.dart' show SourceLoader;
|
||||
|
||||
import '../messages.dart'
|
||||
show
|
||||
|
@ -90,7 +90,7 @@ abstract class ConstructorBuilder implements FunctionBuilder {
|
|||
Set<FieldBuilder>? takeInitializedFields();
|
||||
}
|
||||
|
||||
class ConstructorBuilderImpl extends FunctionBuilderImpl
|
||||
class SourceConstructorBuilder extends FunctionBuilderImpl
|
||||
implements ConstructorBuilder {
|
||||
final Constructor _constructor;
|
||||
final Procedure? _constructorTearOff;
|
||||
|
@ -114,7 +114,7 @@ class ConstructorBuilderImpl extends FunctionBuilderImpl
|
|||
@override
|
||||
Constructor get actualConstructor => _constructor;
|
||||
|
||||
ConstructorBuilderImpl(
|
||||
SourceConstructorBuilder(
|
||||
List<MetadataBuilder>? metadata,
|
||||
int modifiers,
|
||||
TypeBuilder? returnType,
|
||||
|
@ -146,6 +146,10 @@ class ConstructorBuilderImpl extends FunctionBuilderImpl
|
|||
@override
|
||||
SourceLibraryBuilder get library => super.library as SourceLibraryBuilder;
|
||||
|
||||
@override
|
||||
SourceClassBuilder get classBuilder =>
|
||||
super.classBuilder as SourceClassBuilder;
|
||||
|
||||
@override
|
||||
Member? get readTarget => _constructorTearOff ?? _constructor;
|
||||
|
||||
|
@ -213,7 +217,7 @@ class ConstructorBuilderImpl extends FunctionBuilderImpl
|
|||
|
||||
if (_constructorTearOff != null) {
|
||||
buildConstructorTearOffProcedure(_constructorTearOff!, _constructor,
|
||||
classBuilder!.cls, libraryBuilder);
|
||||
classBuilder.cls, libraryBuilder);
|
||||
}
|
||||
|
||||
_hasBeenBuilt = true;
|
||||
|
@ -243,7 +247,7 @@ class ConstructorBuilderImpl extends FunctionBuilderImpl
|
|||
if (formals != null) {
|
||||
for (FormalParameterBuilder formal in formals!) {
|
||||
if (formal.type == null && formal.isInitializingFormal) {
|
||||
formal.finalizeInitializingFormal(classBuilder!);
|
||||
formal.finalizeInitializingFormal(classBuilder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -270,7 +274,7 @@ class ConstructorBuilderImpl extends FunctionBuilderImpl
|
|||
if (isConst && beginInitializers != null) {
|
||||
BodyBuilder bodyBuilder = library.loader
|
||||
.createBodyBuilderForOutlineExpression(
|
||||
library, classBuilder!, this, classBuilder!.scope, fileUri);
|
||||
library, classBuilder, this, classBuilder.scope, fileUri);
|
||||
bodyBuilder.constantContext = ConstantContext.required;
|
||||
bodyBuilder.parseInitializers(beginInitializers!);
|
||||
bodyBuilder.performBacklogComputations(delayedActionPerformers);
|
||||
|
@ -287,7 +291,7 @@ class ConstructorBuilderImpl extends FunctionBuilderImpl
|
|||
// According to the specification §9.3 the return type of a constructor
|
||||
// function is its enclosing class.
|
||||
super.buildFunction(library);
|
||||
Class enclosingClass = classBuilder!.cls;
|
||||
Class enclosingClass = classBuilder.cls;
|
||||
List<DartType> typeParameterTypes = <DartType>[];
|
||||
for (int i = 0; i < enclosingClass.typeParameters.length; i++) {
|
||||
TypeParameter typeParameter = enclosingClass.typeParameters[i];
|
||||
|
@ -426,14 +430,14 @@ class ConstructorBuilderImpl extends FunctionBuilderImpl
|
|||
}
|
||||
|
||||
@override
|
||||
void becomeNative(Loader loader) {
|
||||
void becomeNative(SourceLoader loader) {
|
||||
_constructor.isExternal = true;
|
||||
super.becomeNative(loader);
|
||||
}
|
||||
|
||||
@override
|
||||
void applyPatch(Builder patch) {
|
||||
if (patch is ConstructorBuilderImpl) {
|
||||
if (patch is SourceConstructorBuilder) {
|
||||
if (checkPatch(patch)) {
|
||||
patch.actualOrigin = this;
|
||||
dataForTesting?.patchForTesting = patch;
|
||||
|
|
|
@ -217,7 +217,7 @@ class EnumBuilder extends SourceClassBuilder {
|
|||
referencesFromIndexed.lookupSetterReference(valuesName);
|
||||
}
|
||||
|
||||
ConstructorBuilder constructorBuilder = new ConstructorBuilderImpl(
|
||||
ConstructorBuilder constructorBuilder = new SourceConstructorBuilder(
|
||||
/* metadata = */ null,
|
||||
constMask,
|
||||
/* returnType = */ null,
|
||||
|
@ -410,8 +410,8 @@ class EnumBuilder extends SourceClassBuilder {
|
|||
SourceFieldBuilder valuesBuilder =
|
||||
firstMemberNamed("values") as SourceFieldBuilder;
|
||||
valuesBuilder.build(libraryBuilder);
|
||||
ConstructorBuilderImpl constructorBuilder =
|
||||
constructorScopeBuilder[""] as ConstructorBuilderImpl;
|
||||
SourceConstructorBuilder constructorBuilder =
|
||||
constructorScopeBuilder[""] as SourceConstructorBuilder;
|
||||
Constructor constructor = constructorBuilder.build(libraryBuilder);
|
||||
ClassBuilder objectClass = objectType.declaration as ClassBuilder;
|
||||
ClassBuilder enumClass = supertypeBuilder.declaration as ClassBuilder;
|
||||
|
@ -459,8 +459,8 @@ class EnumBuilder extends SourceClassBuilder {
|
|||
coreTypes,
|
||||
new ListLiteral(values,
|
||||
typeArgument: rawType(library.nonNullable), isConst: true));
|
||||
ConstructorBuilderImpl constructorBuilder =
|
||||
constructorScopeBuilder[""] as ConstructorBuilderImpl;
|
||||
SourceConstructorBuilder constructorBuilder =
|
||||
constructorScopeBuilder[""] as SourceConstructorBuilder;
|
||||
Constructor constructor = constructorBuilder.constructor;
|
||||
int index = 0;
|
||||
if (enumConstantInfos != null) {
|
||||
|
|
|
@ -16,7 +16,7 @@ import '../kernel/kernel_helper.dart';
|
|||
import '../kernel/redirecting_factory_body.dart'
|
||||
show getRedirectingFactoryBody, RedirectingFactoryBody;
|
||||
|
||||
import '../loader.dart' show Loader;
|
||||
import '../source/source_loader.dart' show SourceLoader;
|
||||
|
||||
import '../messages.dart'
|
||||
show messageConstFactoryRedirectionToNonConst, noLength;
|
||||
|
@ -199,7 +199,7 @@ class SourceFactoryBuilder extends FunctionBuilderImpl {
|
|||
throw new UnsupportedError('${runtimeType}.localSetters');
|
||||
|
||||
@override
|
||||
void becomeNative(Loader loader) {
|
||||
void becomeNative(SourceLoader loader) {
|
||||
_procedureInternal.isExternal = true;
|
||||
super.becomeNative(loader);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import '../scope.dart';
|
|||
import '../kernel/internal_ast.dart' show VariableDeclarationImpl;
|
||||
import '../kernel/kernel_helper.dart';
|
||||
|
||||
import '../loader.dart' show Loader;
|
||||
import '../source/source_loader.dart' show SourceLoader;
|
||||
|
||||
import '../messages.dart'
|
||||
show
|
||||
|
@ -129,7 +129,7 @@ abstract class FunctionBuilder implements MemberBuilder {
|
|||
/// members.
|
||||
List<TypeParameter>? get extensionTypeParameters;
|
||||
|
||||
void becomeNative(Loader loader);
|
||||
void becomeNative(SourceLoader loader);
|
||||
|
||||
bool checkPatch(FunctionBuilder patch);
|
||||
|
||||
|
@ -526,7 +526,7 @@ abstract class FunctionBuilderImpl extends MemberBuilderImpl
|
|||
Member build(SourceLibraryBuilder library);
|
||||
|
||||
@override
|
||||
void becomeNative(Loader loader) {
|
||||
void becomeNative(SourceLoader loader) {
|
||||
MemberBuilder constructor = loader.getNativeAnnotation();
|
||||
Arguments arguments =
|
||||
new Arguments(<Expression>[new StringLiteral(nativeMethodName!)]);
|
||||
|
|
|
@ -8,9 +8,8 @@ import 'package:kernel/type_algebra.dart';
|
|||
import '../kernel/class_hierarchy_builder.dart';
|
||||
import '../kernel/member_covariance.dart';
|
||||
|
||||
import '../loader.dart' show Loader;
|
||||
|
||||
import '../source/name_scheme.dart';
|
||||
import '../source/source_loader.dart' show SourceLoader;
|
||||
import '../source/source_library_builder.dart' show SourceLibraryBuilder;
|
||||
|
||||
import 'builder.dart';
|
||||
|
@ -477,7 +476,7 @@ class SourceProcedureBuilder extends FunctionBuilderImpl
|
|||
: const <ClassMember>[];
|
||||
|
||||
@override
|
||||
void becomeNative(Loader loader) {
|
||||
void becomeNative(SourceLoader loader) {
|
||||
_procedure.isExternal = true;
|
||||
super.becomeNative(loader);
|
||||
}
|
||||
|
|
|
@ -4,35 +4,251 @@
|
|||
|
||||
library fasta.dill_loader;
|
||||
|
||||
import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
|
||||
|
||||
import 'package:kernel/ast.dart' show Class, Component, DartType, Library;
|
||||
|
||||
import '../builder/class_builder.dart';
|
||||
import '../builder/library_builder.dart';
|
||||
import '../builder/type_builder.dart';
|
||||
|
||||
import '../crash.dart' show firstSourceUri;
|
||||
|
||||
import '../fasta_codes.dart'
|
||||
show SummaryTemplate, Template, templateDillOutlineSummary;
|
||||
|
||||
import '../kernel/type_builder_computer.dart' show TypeBuilderComputer;
|
||||
|
||||
import '../loader.dart' show Loader;
|
||||
import '../loader.dart';
|
||||
|
||||
import '../problems.dart' show unhandled;
|
||||
import '../messages.dart'
|
||||
show
|
||||
FormattedMessage,
|
||||
LocatedMessage,
|
||||
Message,
|
||||
noLength,
|
||||
SummaryTemplate,
|
||||
Template,
|
||||
messagePlatformPrivateLibraryAccess,
|
||||
templateInternalProblemContextSeverity;
|
||||
|
||||
import '../problems.dart' show internalProblem, unhandled;
|
||||
|
||||
import '../source/source_loader.dart' show SourceLoader;
|
||||
|
||||
import '../target_implementation.dart' show TargetImplementation;
|
||||
import '../ticker.dart' show Ticker;
|
||||
|
||||
import 'dill_library_builder.dart' show DillLibraryBuilder;
|
||||
|
||||
import 'dill_target.dart' show DillTarget;
|
||||
|
||||
import 'dart:collection' show Queue;
|
||||
|
||||
class DillLoader extends Loader {
|
||||
SourceLoader? currentSourceLoader;
|
||||
|
||||
DillLoader(TargetImplementation target) : super(target);
|
||||
@override
|
||||
final Map<Uri, DillLibraryBuilder> builders = <Uri, DillLibraryBuilder>{};
|
||||
|
||||
final Queue<DillLibraryBuilder> _unparsedLibraries =
|
||||
new Queue<DillLibraryBuilder>();
|
||||
|
||||
final List<Library> libraries = <Library>[];
|
||||
|
||||
@override
|
||||
final DillTarget target;
|
||||
|
||||
/// List of all handled compile-time errors seen so far by libraries loaded
|
||||
/// by this loader.
|
||||
///
|
||||
/// A handled error is an error that has been added to the generated AST
|
||||
/// already, for example, as a throw expression.
|
||||
final List<LocatedMessage> handledErrors = <LocatedMessage>[];
|
||||
|
||||
/// List of all unhandled compile-time errors seen so far by libraries loaded
|
||||
/// by this loader.
|
||||
///
|
||||
/// An unhandled error is an error that hasn't been handled, see
|
||||
/// [handledErrors].
|
||||
final List<LocatedMessage> unhandledErrors = <LocatedMessage>[];
|
||||
|
||||
final Set<String> seenMessages = new Set<String>();
|
||||
|
||||
LibraryBuilder? _coreLibrary;
|
||||
|
||||
/// The first library loaded by this [DillLoader].
|
||||
// TODO(johnniwinther): Do we need this?
|
||||
LibraryBuilder? first;
|
||||
|
||||
int byteCount = 0;
|
||||
|
||||
DillLoader(this.target);
|
||||
|
||||
@override
|
||||
LibraryBuilder get coreLibrary => _coreLibrary!;
|
||||
|
||||
void set coreLibrary(LibraryBuilder value) {
|
||||
_coreLibrary = value;
|
||||
}
|
||||
|
||||
Ticker get ticker => target.ticker;
|
||||
|
||||
/// Look up a library builder by the [uri], or if such doesn't exist, create
|
||||
/// one. The canonical URI of the library is [uri], and its actual location is
|
||||
/// [fileUri].
|
||||
///
|
||||
/// Canonical URIs have schemes like "dart", or "package", and the actual
|
||||
/// location is often a file URI.
|
||||
///
|
||||
/// The [accessor] is the library that's trying to import, export, or include
|
||||
/// as part [uri], and [charOffset] is the location of the corresponding
|
||||
/// directive. If [accessor] isn't allowed to access [uri], it's a
|
||||
/// compile-time error.
|
||||
DillLibraryBuilder read(Uri uri, int charOffset, {LibraryBuilder? accessor}) {
|
||||
DillLibraryBuilder builder = builders.putIfAbsent(uri, () {
|
||||
DillLibraryBuilder library = target.createLibraryBuilder(uri);
|
||||
assert(library.loader == this);
|
||||
if (uri.scheme == "dart") {
|
||||
if (uri.path == "core") {
|
||||
_coreLibrary = library;
|
||||
}
|
||||
}
|
||||
{
|
||||
// Add any additional logic after this block. Setting the
|
||||
// firstSourceUri and first library should be done as early as
|
||||
// possible.
|
||||
firstSourceUri ??= uri;
|
||||
first ??= library;
|
||||
}
|
||||
if (_coreLibrary == library) {
|
||||
target.loadExtraRequiredLibraries(this);
|
||||
}
|
||||
if (target.backendTarget.mayDefineRestrictedType(uri)) {
|
||||
library.mayImplementRestrictedTypes = true;
|
||||
}
|
||||
_unparsedLibraries.addLast(library);
|
||||
return library;
|
||||
});
|
||||
if (accessor != null) {
|
||||
builder.recordAccess(charOffset, noLength, accessor.fileUri);
|
||||
if (!accessor.isPatch &&
|
||||
!accessor.isPart &&
|
||||
!target.backendTarget
|
||||
.allowPlatformPrivateLibraryAccess(accessor.importUri, uri)) {
|
||||
accessor.addProblem(messagePlatformPrivateLibraryAccess, charOffset,
|
||||
noLength, accessor.fileUri);
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
void _ensureCoreLibrary() {
|
||||
if (_coreLibrary == null) {
|
||||
read(Uri.parse("dart:core"), 0, accessor: first);
|
||||
// TODO(askesc): When all backends support set literals, we no longer
|
||||
// need to index dart:collection, as it is only needed for desugaring of
|
||||
// const sets. We can remove it from this list at that time.
|
||||
read(Uri.parse("dart:collection"), 0, accessor: first);
|
||||
assert(_coreLibrary != null);
|
||||
}
|
||||
}
|
||||
|
||||
void buildOutlines() {
|
||||
_ensureCoreLibrary();
|
||||
while (_unparsedLibraries.isNotEmpty) {
|
||||
DillLibraryBuilder library = _unparsedLibraries.removeFirst();
|
||||
buildOutline(library);
|
||||
}
|
||||
_logSummary(outlineSummaryTemplate);
|
||||
}
|
||||
|
||||
void _logSummary(Template<SummaryTemplate> template) {
|
||||
ticker.log((Duration elapsed, Duration sinceStart) {
|
||||
int libraryCount = 0;
|
||||
for (DillLibraryBuilder library in builders.values) {
|
||||
assert(library.loader == this);
|
||||
libraryCount++;
|
||||
}
|
||||
double ms = elapsed.inMicroseconds / Duration.microsecondsPerMillisecond;
|
||||
Message message = template.withArguments(
|
||||
libraryCount, byteCount, ms, byteCount / ms, ms / libraryCount);
|
||||
print("$sinceStart: ${message.message}");
|
||||
});
|
||||
}
|
||||
|
||||
/// Register [message] as a problem with a severity determined by the
|
||||
/// intrinsic severity of the message.
|
||||
// TODO(johnniwinther): Avoid the need for this. If this is ever used, it is
|
||||
// inconsistent with messages reported through the [SourceLoader] since they
|
||||
// each have their own list of unhandled/unhandled errors and seen messages,
|
||||
// and only those of the [SourceLoader] are used elsewhere. Use
|
||||
// [currentSourceLoader] to forward messages to the [SourceLoader] instead.
|
||||
@override
|
||||
FormattedMessage? addProblem(
|
||||
Message message, int charOffset, int length, Uri? fileUri,
|
||||
{bool wasHandled: false,
|
||||
List<LocatedMessage>? context,
|
||||
Severity? severity,
|
||||
bool problemOnLibrary: false,
|
||||
List<Uri>? involvedFiles}) {
|
||||
return _addMessage(message, charOffset, length, fileUri, severity,
|
||||
wasHandled: wasHandled,
|
||||
context: context,
|
||||
problemOnLibrary: problemOnLibrary,
|
||||
involvedFiles: involvedFiles);
|
||||
}
|
||||
|
||||
/// All messages reported by the compiler (errors, warnings, etc.) are routed
|
||||
/// through this method.
|
||||
///
|
||||
/// Returns a FormattedMessage if the message is new, that is, not previously
|
||||
/// reported. This is important as some parser errors may be reported up to
|
||||
/// three times by `OutlineBuilder`, `DietListener`, and `BodyBuilder`.
|
||||
/// If the message is not new, [null] is reported.
|
||||
///
|
||||
/// If [severity] is `Severity.error`, the message is added to
|
||||
/// [handledErrors] if [wasHandled] is true or to [unhandledErrors] if
|
||||
/// [wasHandled] is false.
|
||||
FormattedMessage? _addMessage(Message message, int charOffset, int length,
|
||||
Uri? fileUri, Severity? severity,
|
||||
{bool wasHandled: false,
|
||||
List<LocatedMessage>? context,
|
||||
bool problemOnLibrary: false,
|
||||
List<Uri>? involvedFiles}) {
|
||||
severity ??= message.code.severity;
|
||||
if (severity == Severity.ignored) return null;
|
||||
String trace = """
|
||||
message: ${message.message}
|
||||
charOffset: $charOffset
|
||||
fileUri: $fileUri
|
||||
severity: $severity
|
||||
""";
|
||||
if (!seenMessages.add(trace)) return null;
|
||||
if (message.code.severity == Severity.context) {
|
||||
internalProblem(
|
||||
templateInternalProblemContextSeverity
|
||||
.withArguments(message.code.name),
|
||||
charOffset,
|
||||
fileUri);
|
||||
}
|
||||
target.context.report(
|
||||
fileUri != null
|
||||
? message.withLocation(fileUri, charOffset, length)
|
||||
: message.withoutLocation(),
|
||||
severity,
|
||||
context: context,
|
||||
involvedFiles: involvedFiles);
|
||||
if (severity == Severity.error) {
|
||||
(wasHandled ? handledErrors : unhandledErrors).add(fileUri != null
|
||||
? message.withLocation(fileUri, charOffset, length)
|
||||
: message.withoutLocation());
|
||||
}
|
||||
FormattedMessage formattedMessage = target.createFormattedMessage(
|
||||
message, charOffset, length, fileUri, context, severity,
|
||||
involvedFiles: involvedFiles);
|
||||
return formattedMessage;
|
||||
}
|
||||
|
||||
Template<SummaryTemplate> get outlineSummaryTemplate =>
|
||||
templateDillOutlineSummary;
|
||||
|
||||
|
@ -43,22 +259,19 @@ class DillLoader extends Loader {
|
|||
List<Library> componentLibraries = component.libraries;
|
||||
List<Uri> requestedLibraries = <Uri>[];
|
||||
List<Uri> requestedLibrariesFileUri = <Uri>[];
|
||||
DillTarget target = this.target as DillTarget;
|
||||
for (int i = 0; i < componentLibraries.length; i++) {
|
||||
Library library = componentLibraries[i];
|
||||
Uri uri = library.importUri;
|
||||
if (filter == null || filter(library.importUri)) {
|
||||
libraries.add(library);
|
||||
target.addLibrary(library);
|
||||
target.registerLibrary(library);
|
||||
requestedLibraries.add(uri);
|
||||
requestedLibrariesFileUri.add(library.fileUri);
|
||||
}
|
||||
}
|
||||
List<DillLibraryBuilder> result = <DillLibraryBuilder>[];
|
||||
for (int i = 0; i < requestedLibraries.length; i++) {
|
||||
result.add(
|
||||
read(requestedLibraries[i], -1, fileUri: requestedLibrariesFileUri[i])
|
||||
as DillLibraryBuilder);
|
||||
result.add(read(requestedLibraries[i], -1));
|
||||
}
|
||||
target.uriToSource.addAll(component.uriToSource);
|
||||
this.byteCount += byteCount;
|
||||
|
@ -74,29 +287,21 @@ class DillLoader extends Loader {
|
|||
libraries.add(library);
|
||||
|
||||
// Weird interaction begins.
|
||||
DillTarget target = this.target as DillTarget;
|
||||
//
|
||||
// Create dill library builder (adds it to a map where it's fetched
|
||||
// again momentarily).
|
||||
target.addLibrary(library);
|
||||
target.registerLibrary(library);
|
||||
// Set up the dill library builder (fetch it from the map again, add it to
|
||||
// another map and setup some auxiliary things).
|
||||
return read(library.importUri, -1, fileUri: library.fileUri)
|
||||
as DillLibraryBuilder;
|
||||
return read(library.importUri, -1);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Null> buildOutline(DillLibraryBuilder builder) {
|
||||
void buildOutline(DillLibraryBuilder builder) {
|
||||
// ignore: unnecessary_null_comparison
|
||||
if (builder.library == null) {
|
||||
unhandled("null", "builder.library", 0, builder.fileUri);
|
||||
}
|
||||
builder.markAsReadyToBuild();
|
||||
return new Future.value(null);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Null> buildBody(DillLibraryBuilder builder) {
|
||||
return buildOutline(builder);
|
||||
}
|
||||
|
||||
void finalizeExports({bool suppressFinalizationErrors: false}) {
|
||||
|
|
|
@ -2,92 +2,114 @@
|
|||
// 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 fasta.dill_target;
|
||||
import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
|
||||
|
||||
import 'package:kernel/ast.dart' show Library;
|
||||
import 'package:kernel/ast.dart' show Library, Source;
|
||||
|
||||
import 'package:kernel/target/targets.dart' show Target;
|
||||
|
||||
import '../builder/class_builder.dart';
|
||||
import '../../base/processed_options.dart' show ProcessedOptions;
|
||||
|
||||
import '../builder/library_builder.dart' show LibraryBuilder;
|
||||
import '../compiler_context.dart' show CompilerContext;
|
||||
|
||||
import '../problems.dart' show unsupported;
|
||||
|
||||
import '../source/source_library_builder.dart' show LanguageVersion;
|
||||
|
||||
import '../target_implementation.dart' show TargetImplementation;
|
||||
import '../messages.dart' show FormattedMessage, LocatedMessage, Message;
|
||||
|
||||
import '../ticker.dart' show Ticker;
|
||||
|
||||
import '../uri_translator.dart' show UriTranslator;
|
||||
|
||||
import '../target_implementation.dart' show TargetImplementation;
|
||||
|
||||
import 'dill_library_builder.dart' show DillLibraryBuilder;
|
||||
|
||||
import 'dill_loader.dart' show DillLoader;
|
||||
|
||||
class DillTarget extends TargetImplementation {
|
||||
final Map<Uri, DillLibraryBuilder> libraryBuilders =
|
||||
final Ticker ticker;
|
||||
|
||||
final Map<Uri, DillLibraryBuilder> _knownLibraryBuilders =
|
||||
<Uri, DillLibraryBuilder>{};
|
||||
|
||||
bool isLoaded = false;
|
||||
|
||||
late final DillLoader loader;
|
||||
|
||||
DillTarget(Ticker ticker, UriTranslator uriTranslator, Target backendTarget)
|
||||
: super(ticker, uriTranslator, backendTarget) {
|
||||
final UriTranslator uriTranslator;
|
||||
|
||||
@override
|
||||
final Target backendTarget;
|
||||
|
||||
@override
|
||||
final CompilerContext context = CompilerContext.current;
|
||||
|
||||
/// Shared with [CompilerContext].
|
||||
final Map<Uri, Source> uriToSource = CompilerContext.current.uriToSource;
|
||||
|
||||
DillTarget(this.ticker, this.uriTranslator, this.backendTarget)
|
||||
// ignore: unnecessary_null_comparison
|
||||
: assert(ticker != null),
|
||||
// ignore: unnecessary_null_comparison
|
||||
assert(uriTranslator != null),
|
||||
// ignore: unnecessary_null_comparison
|
||||
assert(backendTarget != null) {
|
||||
loader = new DillLoader(this);
|
||||
}
|
||||
|
||||
@override
|
||||
void addSourceInformation(
|
||||
Uri importUri, Uri fileUri, List<int> lineStarts, List<int> sourceCode) {
|
||||
unsupported("addSourceInformation", -1, null);
|
||||
void loadExtraRequiredLibraries(DillLoader loader) {
|
||||
for (String uri in backendTarget.extraRequiredLibraries) {
|
||||
loader.read(Uri.parse(uri), 0, accessor: loader.coreLibrary);
|
||||
}
|
||||
if (context.compilingPlatform) {
|
||||
for (String uri in backendTarget.extraRequiredLibrariesPlatform) {
|
||||
loader.read(Uri.parse(uri), 0, accessor: loader.coreLibrary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Null> buildComponent() {
|
||||
return new Future<Null>.sync(() => unsupported("buildComponent", -1, null));
|
||||
FormattedMessage createFormattedMessage(
|
||||
Message message,
|
||||
int charOffset,
|
||||
int length,
|
||||
Uri? fileUri,
|
||||
List<LocatedMessage>? messageContext,
|
||||
Severity severity,
|
||||
{List<Uri>? involvedFiles}) {
|
||||
ProcessedOptions processedOptions = context.options;
|
||||
return processedOptions.format(
|
||||
fileUri != null
|
||||
? message.withLocation(fileUri, charOffset, length)
|
||||
: message.withoutLocation(),
|
||||
severity,
|
||||
messageContext,
|
||||
involvedFiles: involvedFiles);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Null> buildOutlines({bool suppressFinalizationErrors: false}) async {
|
||||
void buildOutlines({bool suppressFinalizationErrors: false}) {
|
||||
if (loader.libraries.isNotEmpty) {
|
||||
await loader.buildOutlines();
|
||||
loader.buildOutlines();
|
||||
loader.finalizeExports(
|
||||
suppressFinalizationErrors: suppressFinalizationErrors);
|
||||
}
|
||||
isLoaded = true;
|
||||
}
|
||||
|
||||
@override
|
||||
DillLibraryBuilder createLibraryBuilder(
|
||||
Uri uri,
|
||||
Uri fileUri,
|
||||
Uri? packageUri,
|
||||
LanguageVersion packageLanguageVersion,
|
||||
LibraryBuilder? origin,
|
||||
Library? referencesFrom,
|
||||
bool? referenceIsPartOwner) {
|
||||
assert(origin == null);
|
||||
assert(referencesFrom == null);
|
||||
/// Returns the [DillLibraryBuilder] corresponding to [uri].
|
||||
///
|
||||
/// The [DillLibraryBuilder] is pulled from [_knownLibraryBuilders].
|
||||
DillLibraryBuilder createLibraryBuilder(Uri uri) {
|
||||
DillLibraryBuilder libraryBuilder =
|
||||
libraryBuilders.remove(uri) as DillLibraryBuilder;
|
||||
_knownLibraryBuilders.remove(uri) as DillLibraryBuilder;
|
||||
// ignore: unnecessary_null_comparison
|
||||
assert(libraryBuilder != null, "No library found for $uri.");
|
||||
return libraryBuilder;
|
||||
}
|
||||
|
||||
@override
|
||||
void breakCycle(ClassBuilder cls) {}
|
||||
|
||||
void addLibrary(Library library) {
|
||||
libraryBuilders[library.importUri] =
|
||||
void registerLibrary(Library library) {
|
||||
_knownLibraryBuilders[library.importUri] =
|
||||
new DillLibraryBuilder(library, loader);
|
||||
}
|
||||
|
||||
@override
|
||||
void releaseAncillaryResources() {
|
||||
libraryBuilders.clear();
|
||||
_knownLibraryBuilders.clear();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ Future<List<Uri>> getDependencies(Uri script,
|
|||
new KernelTarget(fileSystem, false, dillTarget, uriTranslator);
|
||||
|
||||
kernelTarget.setEntryPoints(<Uri>[script]);
|
||||
await dillTarget.buildOutlines();
|
||||
dillTarget.buildOutlines();
|
||||
await kernelTarget.loader.buildOutlines();
|
||||
return new List<Uri>.from(c.dependencies);
|
||||
});
|
||||
|
|
|
@ -288,7 +288,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
|
|||
|
||||
// For modular compilation we can be asked to load components and track
|
||||
// which libraries we actually use for the compilation. Set that up now.
|
||||
await loadEnsureLoadedComponents(reusedLibraries);
|
||||
loadEnsureLoadedComponents(reusedLibraries);
|
||||
resetTrackingOfUsedLibraries(hierarchy);
|
||||
|
||||
// For each computeDelta call we create a new userCode object which needs
|
||||
|
@ -373,7 +373,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
|
|||
dillLoadedData!.loader.currentSourceLoader = userCode!.loader;
|
||||
} else {
|
||||
previousSourceBuilders =
|
||||
await convertSourceLibraryBuildersToDill(experimentalInvalidation);
|
||||
convertSourceLibraryBuildersToDill(experimentalInvalidation);
|
||||
}
|
||||
|
||||
experimentalInvalidation = null;
|
||||
|
@ -409,8 +409,8 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
|
|||
/// source builders and they will thus be patched up here too.
|
||||
///
|
||||
/// Returns the set of Libraries that now has new (dill) builders.
|
||||
Future<Set<Library>> convertSourceLibraryBuildersToDill(
|
||||
ExperimentalInvalidation? experimentalInvalidation) async {
|
||||
Set<Library> convertSourceLibraryBuildersToDill(
|
||||
ExperimentalInvalidation? experimentalInvalidation) {
|
||||
bool changed = false;
|
||||
Set<Library> newDillLibraryBuilders = new Set<Library>();
|
||||
userBuilders ??= <Uri, LibraryBuilder>{};
|
||||
|
@ -438,7 +438,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
|
|||
if (changed) {
|
||||
// We suppress finalization errors because they have already been
|
||||
// reported.
|
||||
await dillLoadedData!.buildOutlines(suppressFinalizationErrors: true);
|
||||
dillLoadedData!.buildOutlines(suppressFinalizationErrors: true);
|
||||
assert(_checkEquivalentScopes(
|
||||
userCode!.loader.builders, dillLoadedData!.loader.builders));
|
||||
|
||||
|
@ -1284,7 +1284,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
|
|||
|
||||
// We suppress finalization errors because they will reported via
|
||||
// problemsAsJson fields (with better precision).
|
||||
await dillLoadedData!.buildOutlines(suppressFinalizationErrors: true);
|
||||
dillLoadedData!.buildOutlines(suppressFinalizationErrors: true);
|
||||
userBuilders = <Uri, LibraryBuilder>{};
|
||||
platformBuilders = <LibraryBuilder>[];
|
||||
dillLoadedData!.loader.builders.forEach((uri, builder) {
|
||||
|
@ -1420,8 +1420,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
|
|||
}
|
||||
|
||||
/// Internal method.
|
||||
Future<void> loadEnsureLoadedComponents(
|
||||
List<LibraryBuilder> reusedLibraries) async {
|
||||
void loadEnsureLoadedComponents(List<LibraryBuilder> reusedLibraries) {
|
||||
if (modulesToLoad != null) {
|
||||
bool loadedAnything = false;
|
||||
for (Component module in modulesToLoad!) {
|
||||
|
@ -1429,7 +1428,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
|
|||
for (Library lib in module.libraries) {
|
||||
if (!dillLoadedData!.loader.builders.containsKey(lib.importUri)) {
|
||||
dillLoadedData!.loader.libraries.add(lib);
|
||||
dillLoadedData!.addLibrary(lib);
|
||||
dillLoadedData!.registerLibrary(lib);
|
||||
reusedLibraries.add(dillLoadedData!.loader.read(lib.importUri, -1));
|
||||
usedComponent = true;
|
||||
}
|
||||
|
@ -1442,7 +1441,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
|
|||
if (loadedAnything) {
|
||||
// We suppress finalization errors because they will reported via
|
||||
// problemsAsJson fields (with better precision).
|
||||
await dillLoadedData!.buildOutlines(suppressFinalizationErrors: true);
|
||||
dillLoadedData!.buildOutlines(suppressFinalizationErrors: true);
|
||||
userBuilders = <Uri, LibraryBuilder>{};
|
||||
platformBuilders = <LibraryBuilder>[];
|
||||
dillLoadedData!.loader.builders.forEach((uri, builder) {
|
||||
|
|
|
@ -8,12 +8,12 @@ import '../builder/library_builder.dart';
|
|||
|
||||
import '../fasta_codes.dart' show LocatedMessage;
|
||||
|
||||
import '../loader.dart' show Loader;
|
||||
import '../source/source_loader.dart' show SourceLoader;
|
||||
|
||||
import 'constant_evaluator.dart' show ErrorReporter;
|
||||
|
||||
class KernelConstantErrorReporter extends ErrorReporter {
|
||||
final Loader loader;
|
||||
final SourceLoader loader;
|
||||
|
||||
KernelConstantErrorReporter(this.loader);
|
||||
|
||||
|
|
|
@ -4,21 +4,23 @@
|
|||
|
||||
library fasta.kernel_target;
|
||||
|
||||
import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
|
||||
import 'package:kernel/ast.dart';
|
||||
import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
|
||||
import 'package:kernel/core_types.dart';
|
||||
import 'package:kernel/reference_from_index.dart' show IndexedClass;
|
||||
import 'package:kernel/target/changed_structure_notifier.dart'
|
||||
show ChangedStructureNotifier;
|
||||
import 'package:kernel/target/targets.dart' show DiagnosticReporter;
|
||||
import 'package:kernel/target/targets.dart' show DiagnosticReporter, Target;
|
||||
import 'package:kernel/transformations/value_class.dart' as valueClass;
|
||||
import 'package:kernel/type_algebra.dart' show substitute;
|
||||
import 'package:kernel/type_environment.dart' show TypeEnvironment;
|
||||
import 'package:package_config/package_config.dart' hide LanguageVersion;
|
||||
|
||||
import '../../api_prototype/experimental_flags.dart' show ExperimentalFlag;
|
||||
import '../../api_prototype/file_system.dart' show FileSystem;
|
||||
import '../../api_prototype/experimental_flags.dart';
|
||||
import '../../base/nnbd_mode.dart';
|
||||
import '../../base/processed_options.dart' show ProcessedOptions;
|
||||
import '../builder/builder.dart';
|
||||
import '../builder/class_builder.dart';
|
||||
import '../builder/constructor_builder.dart';
|
||||
|
@ -38,15 +40,16 @@ import '../builder/type_variable_builder.dart';
|
|||
import '../builder/void_type_declaration_builder.dart';
|
||||
import '../compiler_context.dart' show CompilerContext;
|
||||
import '../crash.dart' show withCrashReporting;
|
||||
import '../dill/dill_member_builder.dart' show DillMemberBuilder;
|
||||
import '../dill/dill_library_builder.dart' show DillLibraryBuilder;
|
||||
import '../dill/dill_member_builder.dart' show DillMemberBuilder;
|
||||
import '../dill/dill_target.dart' show DillTarget;
|
||||
import '../fasta_codes.dart' show LocatedMessage, Message;
|
||||
import '../kernel/constructor_tearoff_lowering.dart';
|
||||
import '../loader.dart' show Loader;
|
||||
import '../messages.dart'
|
||||
show
|
||||
FormattedMessage,
|
||||
LocatedMessage,
|
||||
Message,
|
||||
messageAgnosticWithStrongDillLibrary,
|
||||
messageAgnosticWithWeakDillLibrary,
|
||||
messageConstConstructorLateFinalFieldCause,
|
||||
|
@ -73,6 +76,7 @@ import '../source/source_library_builder.dart'
|
|||
show LanguageVersion, SourceLibraryBuilder;
|
||||
import '../source/source_loader.dart' show SourceLoader;
|
||||
import '../target_implementation.dart' show TargetImplementation;
|
||||
import '../ticker.dart' show Ticker;
|
||||
import '../type_inference/type_schema.dart';
|
||||
import '../uri_translator.dart' show UriTranslator;
|
||||
import 'constant_evaluator.dart' as constants
|
||||
|
@ -87,6 +91,8 @@ import 'kernel_helper.dart';
|
|||
import 'verifier.dart' show verifyComponent, verifyGetStaticType;
|
||||
|
||||
class KernelTarget extends TargetImplementation {
|
||||
final Ticker ticker;
|
||||
|
||||
/// The [FileSystem] which should be used to access files.
|
||||
final FileSystem fileSystem;
|
||||
|
||||
|
@ -144,17 +150,161 @@ class KernelTarget extends TargetImplementation {
|
|||
final List<SynthesizedFunctionNode> synthesizedFunctionNodes =
|
||||
<SynthesizedFunctionNode>[];
|
||||
|
||||
final UriTranslator uriTranslator;
|
||||
|
||||
@override
|
||||
final Target backendTarget;
|
||||
|
||||
@override
|
||||
final CompilerContext context = CompilerContext.current;
|
||||
|
||||
/// Shared with [CompilerContext].
|
||||
final Map<Uri, Source> uriToSource = CompilerContext.current.uriToSource;
|
||||
|
||||
MemberBuilder? _cachedAbstractClassInstantiationError;
|
||||
MemberBuilder? _cachedCompileTimeError;
|
||||
MemberBuilder? _cachedDuplicatedFieldInitializerError;
|
||||
MemberBuilder? _cachedNativeAnnotation;
|
||||
|
||||
final ProcessedOptions _options;
|
||||
|
||||
KernelTarget(this.fileSystem, this.includeComments, DillTarget dillTarget,
|
||||
UriTranslator uriTranslator)
|
||||
this.uriTranslator)
|
||||
: dillTarget = dillTarget,
|
||||
super(dillTarget.ticker, uriTranslator, dillTarget.backendTarget) {
|
||||
backendTarget = dillTarget.backendTarget,
|
||||
_options = CompilerContext.current.options,
|
||||
ticker = dillTarget.ticker {
|
||||
loader = createLoader();
|
||||
}
|
||||
|
||||
bool isExperimentEnabledInLibrary(ExperimentalFlag flag, Uri importUri) {
|
||||
return _options.isExperimentEnabledInLibrary(flag, importUri);
|
||||
}
|
||||
|
||||
Version getExperimentEnabledVersionInLibrary(
|
||||
ExperimentalFlag flag, Uri importUri) {
|
||||
return _options.getExperimentEnabledVersionInLibrary(flag, importUri);
|
||||
}
|
||||
|
||||
bool isExperimentEnabledInLibraryByVersion(
|
||||
ExperimentalFlag flag, Uri importUri, Version version) {
|
||||
return _options.isExperimentEnabledInLibraryByVersion(
|
||||
flag, importUri, version);
|
||||
}
|
||||
|
||||
/// Returns `true` if the [flag] is enabled by default.
|
||||
bool isExperimentEnabledByDefault(ExperimentalFlag flag) {
|
||||
return _options.isExperimentEnabledByDefault(flag);
|
||||
}
|
||||
|
||||
/// Returns `true` if the [flag] is enabled globally.
|
||||
///
|
||||
/// This is `true` either if the [flag] is passed through an explicit
|
||||
/// `--enable-experiment` option or if the [flag] is expired and on by
|
||||
/// default.
|
||||
bool isExperimentEnabledGlobally(ExperimentalFlag flag) {
|
||||
return _options.isExperimentEnabledGlobally(flag);
|
||||
}
|
||||
|
||||
Uri? translateUri(Uri uri) => uriTranslator.translate(uri);
|
||||
|
||||
/// Returns a reference to the constructor of
|
||||
/// [AbstractClassInstantiationError] error. The constructor is expected to
|
||||
/// accept a single argument of type String, which is the name of the
|
||||
/// abstract class.
|
||||
MemberBuilder getAbstractClassInstantiationError(Loader loader) {
|
||||
return _cachedAbstractClassInstantiationError ??=
|
||||
loader.coreLibrary.getConstructor("AbstractClassInstantiationError");
|
||||
}
|
||||
|
||||
/// Returns a reference to the constructor used for creating a compile-time
|
||||
/// error. The constructor is expected to accept a single argument of type
|
||||
/// String, which is the compile-time error message.
|
||||
MemberBuilder getCompileTimeError(Loader loader) {
|
||||
return _cachedCompileTimeError ??= loader.coreLibrary
|
||||
.getConstructor("_CompileTimeError", bypassLibraryPrivacy: true);
|
||||
}
|
||||
|
||||
/// Returns a reference to the constructor used for creating a runtime error
|
||||
/// when a final field is initialized twice. The constructor is expected to
|
||||
/// accept a single argument which is the name of the field.
|
||||
MemberBuilder getDuplicatedFieldInitializerError(Loader loader) {
|
||||
return _cachedDuplicatedFieldInitializerError ??= loader.coreLibrary
|
||||
.getConstructor("_DuplicatedFieldInitializerError",
|
||||
bypassLibraryPrivacy: true);
|
||||
}
|
||||
|
||||
/// Returns a reference to the constructor used for creating `native`
|
||||
/// annotations. The constructor is expected to accept a single argument of
|
||||
/// type String, which is the name of the native method.
|
||||
MemberBuilder getNativeAnnotation(SourceLoader loader) {
|
||||
if (_cachedNativeAnnotation != null) return _cachedNativeAnnotation!;
|
||||
LibraryBuilder internal = loader.read(Uri.parse("dart:_internal"), -1,
|
||||
accessor: loader.coreLibrary);
|
||||
return _cachedNativeAnnotation = internal.getConstructor("ExternalName");
|
||||
}
|
||||
|
||||
void loadExtraRequiredLibraries(SourceLoader loader) {
|
||||
for (String uri in backendTarget.extraRequiredLibraries) {
|
||||
loader.read(Uri.parse(uri), 0, accessor: loader.coreLibrary);
|
||||
}
|
||||
if (context.compilingPlatform) {
|
||||
for (String uri in backendTarget.extraRequiredLibrariesPlatform) {
|
||||
loader.read(Uri.parse(uri), 0, accessor: loader.coreLibrary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FormattedMessage createFormattedMessage(
|
||||
Message message,
|
||||
int charOffset,
|
||||
int length,
|
||||
Uri? fileUri,
|
||||
List<LocatedMessage>? messageContext,
|
||||
Severity severity,
|
||||
{List<Uri>? involvedFiles}) {
|
||||
ProcessedOptions processedOptions = context.options;
|
||||
return processedOptions.format(
|
||||
fileUri != null
|
||||
? message.withLocation(fileUri, charOffset, length)
|
||||
: message.withoutLocation(),
|
||||
severity,
|
||||
messageContext,
|
||||
involvedFiles: involvedFiles);
|
||||
}
|
||||
|
||||
String get currentSdkVersionString {
|
||||
return CompilerContext.current.options.currentSdkVersion;
|
||||
}
|
||||
|
||||
Version? _currentSdkVersion;
|
||||
Version get currentSdkVersion {
|
||||
if (_currentSdkVersion == null) {
|
||||
_parseCurrentSdkVersion();
|
||||
}
|
||||
return _currentSdkVersion!;
|
||||
}
|
||||
|
||||
void _parseCurrentSdkVersion() {
|
||||
bool good = false;
|
||||
// ignore: unnecessary_null_comparison
|
||||
if (currentSdkVersionString != null) {
|
||||
List<String> dotSeparatedParts = currentSdkVersionString.split(".");
|
||||
if (dotSeparatedParts.length >= 2) {
|
||||
_currentSdkVersion = new Version(int.tryParse(dotSeparatedParts[0])!,
|
||||
int.tryParse(dotSeparatedParts[1])!);
|
||||
good = true;
|
||||
}
|
||||
}
|
||||
if (!good) {
|
||||
throw new StateError(
|
||||
"Unparsable sdk version given: $currentSdkVersionString");
|
||||
}
|
||||
}
|
||||
|
||||
SourceLoader createLoader() =>
|
||||
new SourceLoader(fileSystem, includeComments, this);
|
||||
|
||||
@override
|
||||
void addSourceInformation(
|
||||
Uri importUri, Uri fileUri, List<int> lineStarts, List<int> sourceCode) {
|
||||
uriToSource[fileUri] =
|
||||
|
@ -214,7 +364,30 @@ class KernelTarget extends TargetImplementation {
|
|||
return entryPoint;
|
||||
}
|
||||
|
||||
@override
|
||||
/// Creates a [LibraryBuilder] corresponding to [uri], if one doesn't exist
|
||||
/// already.
|
||||
///
|
||||
/// [fileUri] must not be null and is a URI that can be passed to FileSystem
|
||||
/// to locate the corresponding file.
|
||||
///
|
||||
/// [origin] is non-null if the created library is a patch to [origin].
|
||||
///
|
||||
/// [packageUri] is the base uri for the package which the library belongs to.
|
||||
/// For instance 'package:foo'.
|
||||
///
|
||||
/// This is used to associate libraries in for instance the 'bin' and 'test'
|
||||
/// folders of a package source with the package uri of the 'lib' folder.
|
||||
///
|
||||
/// If the [packageUri] is `null` the package association of this library is
|
||||
/// based on its [importUri].
|
||||
///
|
||||
/// For libraries with a 'package:' [importUri], the package path must match
|
||||
/// the path in the [importUri]. For libraries with a 'dart:' [importUri] the
|
||||
/// [packageUri] must be `null`.
|
||||
///
|
||||
/// [packageLanguageVersion] is the language version defined by the package
|
||||
/// which the library belongs to, or the current sdk version if the library
|
||||
/// doesn't belong to a package.
|
||||
LibraryBuilder createLibraryBuilder(
|
||||
Uri uri,
|
||||
Uri fileUri,
|
||||
|
@ -224,13 +397,13 @@ class KernelTarget extends TargetImplementation {
|
|||
Library? referencesFrom,
|
||||
bool? referenceIsPartOwner) {
|
||||
if (dillTarget.isLoaded) {
|
||||
LibraryBuilder? builder = dillTarget.loader.builders[uri];
|
||||
DillLibraryBuilder? builder = dillTarget.loader.builders[uri];
|
||||
if (builder != null) {
|
||||
if (!builder.isNonNullableByDefault &&
|
||||
(loader.nnbdMode == NnbdMode.Strong ||
|
||||
loader.nnbdMode == NnbdMode.Agnostic)) {
|
||||
loader.registerStrongOptOutLibrary(builder);
|
||||
} else if (builder is DillLibraryBuilder) {
|
||||
} else {
|
||||
NonNullableByDefaultCompiledMode libraryMode =
|
||||
builder.library.nonNullableByDefaultCompiledMode;
|
||||
if (libraryMode == NonNullableByDefaultCompiledMode.Invalid) {
|
||||
|
@ -292,7 +465,9 @@ class KernelTarget extends TargetImplementation {
|
|||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
/// The class [cls] is involved in a cyclic definition. This method should
|
||||
/// ensure that the cycle is broken, for example, by removing superclass and
|
||||
/// implemented interfaces.
|
||||
void breakCycle(ClassBuilder builder) {
|
||||
Class cls = builder.cls;
|
||||
cls.implementedTypes.clear();
|
||||
|
@ -309,7 +484,6 @@ class KernelTarget extends TargetImplementation {
|
|||
builder.mixedInTypeBuilder = null;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Component?> buildOutlines({CanonicalName? nameRoot}) async {
|
||||
if (loader.first == null) return null;
|
||||
return withCrashReporting<Component?>(() async {
|
||||
|
@ -363,7 +537,6 @@ class KernelTarget extends TargetImplementation {
|
|||
///
|
||||
/// If [verify], run the default kernel verification on the resulting
|
||||
/// component.
|
||||
@override
|
||||
Future<Component?> buildComponent({bool verify: false}) async {
|
||||
if (loader.first == null) return null;
|
||||
return withCrashReporting<Component?>(() async {
|
||||
|
@ -1362,7 +1535,6 @@ class KernelTarget extends TargetImplementation {
|
|||
return loader.libraries.contains(library);
|
||||
}
|
||||
|
||||
@override
|
||||
void readPatchFiles(SourceLibraryBuilder library) {
|
||||
assert(library.importUri.scheme == "dart");
|
||||
List<Uri>? patches = uriTranslator.getDartPatches(library.importUri.path);
|
||||
|
@ -1389,7 +1561,6 @@ class KernelTarget extends TargetImplementation {
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void releaseAncillaryResources() {
|
||||
component = null;
|
||||
}
|
||||
|
@ -1418,7 +1589,7 @@ Constructor? defaultSuperConstructor(Class cls) {
|
|||
|
||||
class KernelDiagnosticReporter
|
||||
extends DiagnosticReporter<Message, LocatedMessage> {
|
||||
final Loader loader;
|
||||
final SourceLoader loader;
|
||||
|
||||
KernelDiagnosticReporter(this.loader);
|
||||
|
||||
|
|
|
@ -4,330 +4,24 @@
|
|||
|
||||
library fasta.loader;
|
||||
|
||||
import 'dart:collection' show Queue;
|
||||
|
||||
import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
|
||||
|
||||
import 'package:kernel/ast.dart' show Class, DartType, Library, Version;
|
||||
import 'package:package_config/package_config.dart';
|
||||
|
||||
import 'scope.dart';
|
||||
import 'package:kernel/ast.dart' show Class, DartType;
|
||||
|
||||
import 'builder/class_builder.dart';
|
||||
import 'builder/declaration_builder.dart';
|
||||
import 'builder/library_builder.dart';
|
||||
import 'builder/member_builder.dart';
|
||||
import 'builder/modifier_builder.dart';
|
||||
import 'builder/type_builder.dart';
|
||||
|
||||
import 'crash.dart' show firstSourceUri;
|
||||
|
||||
import 'kernel/body_builder.dart' show BodyBuilder;
|
||||
|
||||
import 'messages.dart'
|
||||
show
|
||||
FormattedMessage,
|
||||
LocatedMessage,
|
||||
Message,
|
||||
noLength,
|
||||
SummaryTemplate,
|
||||
Template,
|
||||
messageLanguageVersionInvalidInDotPackages,
|
||||
messagePlatformPrivateLibraryAccess,
|
||||
templateInternalProblemContextSeverity,
|
||||
templateLanguageVersionTooHigh,
|
||||
templateSourceBodySummary;
|
||||
|
||||
import 'problems.dart' show internalProblem, unhandled;
|
||||
|
||||
import 'source/source_library_builder.dart' as src
|
||||
show
|
||||
LanguageVersion,
|
||||
InvalidLanguageVersion,
|
||||
ImplicitLanguageVersion,
|
||||
SourceLibraryBuilder;
|
||||
import 'messages.dart' show FormattedMessage, LocatedMessage, Message;
|
||||
|
||||
import 'target_implementation.dart' show TargetImplementation;
|
||||
|
||||
import 'ticker.dart' show Ticker;
|
||||
|
||||
const String untranslatableUriScheme = "org-dartlang-untranslatable-uri";
|
||||
|
||||
abstract class Loader {
|
||||
final Map<Uri, LibraryBuilder> builders = <Uri, LibraryBuilder>{};
|
||||
TargetImplementation get target;
|
||||
|
||||
final Queue<LibraryBuilder> unparsedLibraries = new Queue<LibraryBuilder>();
|
||||
|
||||
final List<Library> libraries = <Library>[];
|
||||
|
||||
final TargetImplementation target;
|
||||
|
||||
/// List of all handled compile-time errors seen so far by libraries loaded
|
||||
/// by this loader.
|
||||
///
|
||||
/// A handled error is an error that has been added to the generated AST
|
||||
/// already, for example, as a throw expression.
|
||||
final List<LocatedMessage> handledErrors = <LocatedMessage>[];
|
||||
|
||||
/// List of all unhandled compile-time errors seen so far by libraries loaded
|
||||
/// by this loader.
|
||||
///
|
||||
/// An unhandled error is an error that hasn't been handled, see
|
||||
/// [handledErrors].
|
||||
final List<LocatedMessage> unhandledErrors = <LocatedMessage>[];
|
||||
|
||||
/// List of all problems seen so far by libraries loaded by this loader that
|
||||
/// does not belong directly to a library.
|
||||
final List<FormattedMessage> allComponentProblems = <FormattedMessage>[];
|
||||
|
||||
final Set<String> seenMessages = new Set<String>();
|
||||
bool _hasSeenError = false;
|
||||
|
||||
void resetSeenMessages() {
|
||||
seenMessages.clear();
|
||||
_hasSeenError = false;
|
||||
}
|
||||
|
||||
/// Returns `true` if a compile time error has been reported.
|
||||
bool get hasSeenError => _hasSeenError;
|
||||
|
||||
LibraryBuilder? _coreLibrary;
|
||||
LibraryBuilder? typedDataLibrary;
|
||||
|
||||
/// The first library that we've been asked to compile. When compiling a
|
||||
/// program (aka script), this is the library that should have a main method.
|
||||
LibraryBuilder? first;
|
||||
|
||||
int byteCount = 0;
|
||||
|
||||
Uri? currentUriForCrashReporting;
|
||||
|
||||
Loader(this.target);
|
||||
|
||||
LibraryBuilder get coreLibrary => _coreLibrary!;
|
||||
|
||||
void set coreLibrary(LibraryBuilder value) {
|
||||
_coreLibrary = value;
|
||||
}
|
||||
|
||||
Ticker get ticker => target.ticker;
|
||||
|
||||
Template<SummaryTemplate> get outlineSummaryTemplate;
|
||||
|
||||
bool get isSourceLoader => false;
|
||||
|
||||
/// Look up a library builder by the name [uri], or if such doesn't
|
||||
/// exist, create one. The canonical URI of the library is [uri], and its
|
||||
/// actual location is [fileUri].
|
||||
///
|
||||
/// Canonical URIs have schemes like "dart", or "package", and the actual
|
||||
/// location is often a file URI.
|
||||
///
|
||||
/// The [accessor] is the library that's trying to import, export, or include
|
||||
/// as part [uri], and [charOffset] is the location of the corresponding
|
||||
/// directive. If [accessor] isn't allowed to access [uri], it's a
|
||||
/// compile-time error.
|
||||
LibraryBuilder read(Uri uri, int charOffset,
|
||||
{Uri? fileUri,
|
||||
LibraryBuilder? accessor,
|
||||
LibraryBuilder? origin,
|
||||
Library? referencesFrom,
|
||||
bool? referenceIsPartOwner}) {
|
||||
LibraryBuilder builder = builders.putIfAbsent(uri, () {
|
||||
if (fileUri != null &&
|
||||
(fileUri!.scheme == "dart" ||
|
||||
fileUri!.scheme == "package" ||
|
||||
fileUri!.scheme == "dart-ext")) {
|
||||
fileUri = null;
|
||||
}
|
||||
Package? packageForLanguageVersion;
|
||||
if (fileUri == null) {
|
||||
switch (uri.scheme) {
|
||||
case "package":
|
||||
case "dart":
|
||||
fileUri = target.translateUri(uri) ??
|
||||
new Uri(
|
||||
scheme: untranslatableUriScheme,
|
||||
path: Uri.encodeComponent("$uri"));
|
||||
if (uri.scheme == "package") {
|
||||
packageForLanguageVersion = target.uriTranslator.getPackage(uri);
|
||||
} else {
|
||||
packageForLanguageVersion =
|
||||
target.uriTranslator.packages.packageOf(fileUri!);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fileUri = uri;
|
||||
packageForLanguageVersion =
|
||||
target.uriTranslator.packages.packageOf(fileUri!);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
packageForLanguageVersion =
|
||||
target.uriTranslator.packages.packageOf(fileUri!);
|
||||
}
|
||||
src.LanguageVersion? packageLanguageVersion;
|
||||
Uri? packageUri;
|
||||
Message? packageLanguageVersionProblem;
|
||||
if (packageForLanguageVersion != null) {
|
||||
Uri importUri = origin?.importUri ?? uri;
|
||||
if (importUri.scheme != 'dart' &&
|
||||
importUri.scheme != 'package' &&
|
||||
// ignore: unnecessary_null_comparison
|
||||
packageForLanguageVersion.name != null) {
|
||||
packageUri =
|
||||
new Uri(scheme: 'package', path: packageForLanguageVersion.name);
|
||||
}
|
||||
if (packageForLanguageVersion.languageVersion != null) {
|
||||
if (packageForLanguageVersion.languageVersion
|
||||
is InvalidLanguageVersion) {
|
||||
packageLanguageVersionProblem =
|
||||
messageLanguageVersionInvalidInDotPackages;
|
||||
packageLanguageVersion = new src.InvalidLanguageVersion(
|
||||
fileUri!, 0, noLength, target.currentSdkVersion, false);
|
||||
} else {
|
||||
Version version = new Version(
|
||||
packageForLanguageVersion.languageVersion!.major,
|
||||
packageForLanguageVersion.languageVersion!.minor);
|
||||
if (version > target.currentSdkVersion) {
|
||||
packageLanguageVersionProblem =
|
||||
templateLanguageVersionTooHigh.withArguments(
|
||||
target.currentSdkVersion.major,
|
||||
target.currentSdkVersion.minor);
|
||||
packageLanguageVersion = new src.InvalidLanguageVersion(
|
||||
fileUri!, 0, noLength, target.currentSdkVersion, false);
|
||||
} else {
|
||||
packageLanguageVersion = new src.ImplicitLanguageVersion(version);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
packageLanguageVersion ??=
|
||||
new src.ImplicitLanguageVersion(target.currentSdkVersion);
|
||||
|
||||
LibraryBuilder? library = target.createLibraryBuilder(
|
||||
uri,
|
||||
fileUri!,
|
||||
packageUri,
|
||||
packageLanguageVersion,
|
||||
origin,
|
||||
referencesFrom,
|
||||
referenceIsPartOwner);
|
||||
if (library == null) {
|
||||
throw new StateError("createLibraryBuilder for uri $uri, "
|
||||
"fileUri $fileUri returned null.");
|
||||
}
|
||||
if (packageLanguageVersionProblem != null &&
|
||||
library is src.SourceLibraryBuilder) {
|
||||
library.addPostponedProblem(
|
||||
packageLanguageVersionProblem, 0, noLength, library.fileUri);
|
||||
}
|
||||
|
||||
if (uri.scheme == "dart") {
|
||||
if (uri.path == "core") {
|
||||
_coreLibrary = library;
|
||||
} else if (uri.path == "typed_data") {
|
||||
typedDataLibrary = library;
|
||||
}
|
||||
}
|
||||
if (library.loader != this) {
|
||||
if (_coreLibrary == library) {
|
||||
target.loadExtraRequiredLibraries(this);
|
||||
}
|
||||
// This library isn't owned by this loader, so no further processing
|
||||
// should be attempted.
|
||||
return library;
|
||||
}
|
||||
|
||||
{
|
||||
// Add any additional logic after this block. Setting the
|
||||
// firstSourceUri and first library should be done as early as
|
||||
// possible.
|
||||
firstSourceUri ??= uri;
|
||||
first ??= library;
|
||||
}
|
||||
if (_coreLibrary == library) {
|
||||
target.loadExtraRequiredLibraries(this);
|
||||
}
|
||||
Uri libraryUri = origin?.importUri ?? uri;
|
||||
if (target.backendTarget.mayDefineRestrictedType(libraryUri)) {
|
||||
library.mayImplementRestrictedTypes = true;
|
||||
}
|
||||
if (uri.scheme == "dart") {
|
||||
target.readPatchFiles(library);
|
||||
}
|
||||
unparsedLibraries.addLast(library);
|
||||
return library;
|
||||
});
|
||||
if (accessor == null) {
|
||||
if (builder.loader == this && first != builder && isSourceLoader) {
|
||||
unhandled("null", "accessor", charOffset, uri);
|
||||
}
|
||||
} else {
|
||||
builder.recordAccess(charOffset, noLength, accessor.fileUri);
|
||||
if (!accessor.isPatch &&
|
||||
!accessor.isPart &&
|
||||
!target.backendTarget
|
||||
.allowPlatformPrivateLibraryAccess(accessor.importUri, uri)) {
|
||||
accessor.addProblem(messagePlatformPrivateLibraryAccess, charOffset,
|
||||
noLength, accessor.fileUri);
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
void ensureCoreLibrary() {
|
||||
if (_coreLibrary == null) {
|
||||
read(Uri.parse("dart:core"), 0, accessor: first);
|
||||
// TODO(askesc): When all backends support set literals, we no longer
|
||||
// need to index dart:collection, as it is only needed for desugaring of
|
||||
// const sets. We can remove it from this list at that time.
|
||||
read(Uri.parse("dart:collection"), 0, accessor: first);
|
||||
assert(_coreLibrary != null);
|
||||
}
|
||||
}
|
||||
|
||||
Future<Null> buildBodies() async {
|
||||
assert(_coreLibrary != null);
|
||||
for (LibraryBuilder library in builders.values) {
|
||||
if (library.loader == this) {
|
||||
currentUriForCrashReporting = library.importUri;
|
||||
await buildBody(library);
|
||||
}
|
||||
}
|
||||
currentUriForCrashReporting = null;
|
||||
logSummary(templateSourceBodySummary);
|
||||
}
|
||||
|
||||
Future<Null> buildOutlines() async {
|
||||
ensureCoreLibrary();
|
||||
while (unparsedLibraries.isNotEmpty) {
|
||||
LibraryBuilder library = unparsedLibraries.removeFirst();
|
||||
currentUriForCrashReporting = library.importUri;
|
||||
await buildOutline(library);
|
||||
}
|
||||
currentUriForCrashReporting = null;
|
||||
logSummary(outlineSummaryTemplate);
|
||||
}
|
||||
|
||||
void logSummary(Template<SummaryTemplate> template) {
|
||||
ticker.log((Duration elapsed, Duration sinceStart) {
|
||||
int libraryCount = 0;
|
||||
for (LibraryBuilder library in builders.values) {
|
||||
if (library.loader == this) libraryCount++;
|
||||
}
|
||||
double ms = elapsed.inMicroseconds / Duration.microsecondsPerMillisecond;
|
||||
Message message = template.withArguments(
|
||||
libraryCount, byteCount, ms, byteCount / ms, ms / libraryCount);
|
||||
print("$sinceStart: ${message.message}");
|
||||
});
|
||||
}
|
||||
|
||||
Future<Null> buildOutline(covariant LibraryBuilder library);
|
||||
|
||||
/// Builds all the method bodies found in the given [library].
|
||||
Future<Null> buildBody(covariant LibraryBuilder library);
|
||||
Map<Uri, LibraryBuilder> get builders;
|
||||
|
||||
/// Register [message] as a problem with a severity determined by the
|
||||
/// intrinsic severity of the message.
|
||||
|
@ -337,94 +31,11 @@ abstract class Loader {
|
|||
List<LocatedMessage>? context,
|
||||
Severity? severity,
|
||||
bool problemOnLibrary: false,
|
||||
List<Uri>? involvedFiles}) {
|
||||
return addMessage(message, charOffset, length, fileUri, severity,
|
||||
wasHandled: wasHandled,
|
||||
context: context,
|
||||
problemOnLibrary: problemOnLibrary,
|
||||
involvedFiles: involvedFiles);
|
||||
}
|
||||
|
||||
/// All messages reported by the compiler (errors, warnings, etc.) are routed
|
||||
/// through this method.
|
||||
///
|
||||
/// Returns a FormattedMessage if the message is new, that is, not previously
|
||||
/// reported. This is important as some parser errors may be reported up to
|
||||
/// three times by `OutlineBuilder`, `DietListener`, and `BodyBuilder`.
|
||||
/// If the message is not new, [null] is reported.
|
||||
///
|
||||
/// If [severity] is `Severity.error`, the message is added to
|
||||
/// [handledErrors] if [wasHandled] is true or to [unhandledErrors] if
|
||||
/// [wasHandled] is false.
|
||||
FormattedMessage? addMessage(Message message, int charOffset, int length,
|
||||
Uri? fileUri, Severity? severity,
|
||||
{bool wasHandled: false,
|
||||
List<LocatedMessage>? context,
|
||||
bool problemOnLibrary: false,
|
||||
List<Uri>? involvedFiles}) {
|
||||
severity ??= message.code.severity;
|
||||
if (severity == Severity.ignored) return null;
|
||||
String trace = """
|
||||
message: ${message.message}
|
||||
charOffset: $charOffset
|
||||
fileUri: $fileUri
|
||||
severity: $severity
|
||||
""";
|
||||
if (!seenMessages.add(trace)) return null;
|
||||
if (message.code.severity == Severity.error) {
|
||||
_hasSeenError = true;
|
||||
}
|
||||
if (message.code.severity == Severity.context) {
|
||||
internalProblem(
|
||||
templateInternalProblemContextSeverity
|
||||
.withArguments(message.code.name),
|
||||
charOffset,
|
||||
fileUri);
|
||||
}
|
||||
target.context.report(
|
||||
fileUri != null
|
||||
? message.withLocation(fileUri, charOffset, length)
|
||||
: message.withoutLocation(),
|
||||
severity,
|
||||
context: context,
|
||||
involvedFiles: involvedFiles);
|
||||
if (severity == Severity.error) {
|
||||
(wasHandled ? handledErrors : unhandledErrors).add(fileUri != null
|
||||
? message.withLocation(fileUri, charOffset, length)
|
||||
: message.withoutLocation());
|
||||
}
|
||||
FormattedMessage formattedMessage = target.createFormattedMessage(
|
||||
message, charOffset, length, fileUri, context, severity,
|
||||
involvedFiles: involvedFiles);
|
||||
if (!problemOnLibrary) {
|
||||
allComponentProblems.add(formattedMessage);
|
||||
}
|
||||
return formattedMessage;
|
||||
}
|
||||
|
||||
MemberBuilder getAbstractClassInstantiationError() {
|
||||
return target.getAbstractClassInstantiationError(this);
|
||||
}
|
||||
|
||||
MemberBuilder getCompileTimeError() => target.getCompileTimeError(this);
|
||||
|
||||
MemberBuilder getDuplicatedFieldInitializerError() {
|
||||
return target.getDuplicatedFieldInitializerError(this);
|
||||
}
|
||||
|
||||
MemberBuilder getNativeAnnotation() => target.getNativeAnnotation(this);
|
||||
List<Uri>? involvedFiles});
|
||||
|
||||
ClassBuilder computeClassBuilderFromTargetClass(Class cls);
|
||||
|
||||
TypeBuilder computeTypeBuilder(DartType type);
|
||||
|
||||
BodyBuilder createBodyBuilderForOutlineExpression(
|
||||
src.SourceLibraryBuilder library,
|
||||
DeclarationBuilder? declarationBuilder,
|
||||
ModifierBuilder member,
|
||||
Scope scope,
|
||||
Uri fileUri) {
|
||||
return new BodyBuilder.forOutlineExpression(
|
||||
library, declarationBuilder, member, scope, fileUri);
|
||||
}
|
||||
LibraryBuilder get coreLibrary;
|
||||
}
|
||||
|
|
|
@ -2353,7 +2353,7 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
|
|||
new Name(
|
||||
constructorName, _currentClassReferencesFromIndexed!.library));
|
||||
}
|
||||
ConstructorBuilder constructorBuilder = new ConstructorBuilderImpl(
|
||||
ConstructorBuilder constructorBuilder = new SourceConstructorBuilder(
|
||||
metadata,
|
||||
modifiers & ~abstractMask,
|
||||
returnType,
|
||||
|
|
|
@ -4,16 +4,14 @@
|
|||
|
||||
library fasta.source_loader;
|
||||
|
||||
import 'dart:collection' show Queue;
|
||||
import 'dart:convert' show utf8;
|
||||
|
||||
import 'dart:typed_data' show Uint8List;
|
||||
|
||||
import 'package:_fe_analyzer_shared/src/parser/class_member_parser.dart'
|
||||
show ClassMemberParser;
|
||||
|
||||
import 'package:_fe_analyzer_shared/src/parser/parser.dart'
|
||||
show Parser, lengthForToken;
|
||||
|
||||
import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
|
||||
show
|
||||
ErrorToken,
|
||||
|
@ -23,57 +21,23 @@ import 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
|
|||
ScannerResult,
|
||||
Token,
|
||||
scan;
|
||||
|
||||
import 'package:kernel/ast.dart'
|
||||
show
|
||||
Arguments,
|
||||
AsyncMarker,
|
||||
Class,
|
||||
Component,
|
||||
Constructor,
|
||||
DartType,
|
||||
Expression,
|
||||
FunctionNode,
|
||||
InterfaceType,
|
||||
Library,
|
||||
LibraryDependency,
|
||||
Member,
|
||||
NeverType,
|
||||
Nullability,
|
||||
Procedure,
|
||||
ProcedureKind,
|
||||
Reference,
|
||||
Supertype,
|
||||
TreeNode,
|
||||
VariableDeclaration,
|
||||
Version;
|
||||
|
||||
import 'package:kernel/ast.dart';
|
||||
import 'package:kernel/class_hierarchy.dart'
|
||||
show ClassHierarchy, HandleAmbiguousSupertypes;
|
||||
|
||||
import 'package:kernel/core_types.dart' show CoreTypes;
|
||||
|
||||
import 'package:kernel/reference_from_index.dart' show ReferenceFromIndex;
|
||||
|
||||
import 'package:kernel/type_environment.dart';
|
||||
|
||||
import 'package:package_config/package_config.dart';
|
||||
import 'package:package_config/package_config.dart' as package_config;
|
||||
|
||||
import '../../api_prototype/experimental_flags.dart';
|
||||
import '../../api_prototype/file_system.dart';
|
||||
|
||||
import '../../base/common.dart';
|
||||
|
||||
import '../../base/instrumentation.dart' show Instrumentation;
|
||||
|
||||
import '../../base/nnbd_mode.dart';
|
||||
|
||||
import '../denylisted_classes.dart'
|
||||
show denylistedCoreClasses, denylistedTypedDataClasses;
|
||||
|
||||
import '../builder/builder.dart';
|
||||
import '../builder/class_builder.dart';
|
||||
import '../builder/constructor_builder.dart';
|
||||
import '../builder/declaration_builder.dart';
|
||||
import '../builder/dynamic_type_declaration_builder.dart';
|
||||
import '../builder/enum_builder.dart';
|
||||
import '../builder/extension_builder.dart';
|
||||
|
@ -81,6 +45,7 @@ import '../builder/field_builder.dart';
|
|||
import '../builder/invalid_type_declaration_builder.dart';
|
||||
import '../builder/library_builder.dart';
|
||||
import '../builder/member_builder.dart';
|
||||
import '../builder/modifier_builder.dart';
|
||||
import '../builder/named_type_builder.dart';
|
||||
import '../builder/never_type_declaration_builder.dart';
|
||||
import '../builder/prefix_builder.dart';
|
||||
|
@ -88,11 +53,11 @@ import '../builder/procedure_builder.dart';
|
|||
import '../builder/type_alias_builder.dart';
|
||||
import '../builder/type_builder.dart';
|
||||
import '../builder/type_declaration_builder.dart';
|
||||
|
||||
import '../crash.dart' show firstSourceUri;
|
||||
import '../denylisted_classes.dart'
|
||||
show denylistedCoreClasses, denylistedTypedDataClasses;
|
||||
import '../export.dart' show Export;
|
||||
|
||||
import '../fasta_codes.dart';
|
||||
|
||||
import '../kernel/body_builder.dart' show BodyBuilder;
|
||||
import '../kernel/class_hierarchy_builder.dart';
|
||||
import '../kernel/kernel_helper.dart'
|
||||
|
@ -101,22 +66,24 @@ import '../kernel/kernel_target.dart' show KernelTarget;
|
|||
import '../kernel/transform_collections.dart' show CollectionTransformer;
|
||||
import '../kernel/transform_set_literals.dart' show SetLiteralTransformer;
|
||||
import '../kernel/type_builder_computer.dart' show TypeBuilderComputer;
|
||||
|
||||
import '../loader.dart' show Loader, untranslatableUriScheme;
|
||||
|
||||
import '../problems.dart' show internalProblem;
|
||||
|
||||
import '../problems.dart' show internalProblem, unhandled;
|
||||
import '../scope.dart';
|
||||
import '../ticker.dart' show Ticker;
|
||||
import '../type_inference/type_inference_engine.dart';
|
||||
import '../type_inference/type_inferrer.dart';
|
||||
|
||||
import '../util/helpers.dart';
|
||||
|
||||
import 'diet_listener.dart' show DietListener;
|
||||
import 'diet_parser.dart' show DietParser, useImplicitCreationExpressionInCfe;
|
||||
import 'name_scheme.dart';
|
||||
import 'outline_builder.dart' show OutlineBuilder;
|
||||
import 'source_class_builder.dart' show SourceClassBuilder;
|
||||
import 'source_library_builder.dart' show SourceLibraryBuilder;
|
||||
import 'source_library_builder.dart'
|
||||
show
|
||||
LanguageVersion,
|
||||
InvalidLanguageVersion,
|
||||
ImplicitLanguageVersion,
|
||||
SourceLibraryBuilder;
|
||||
import 'source_type_alias_builder.dart';
|
||||
import 'stack_listener_impl.dart' show offsetForToken;
|
||||
|
||||
|
@ -174,10 +141,365 @@ class SourceLoader extends Loader {
|
|||
|
||||
final SourceLoaderDataForTesting? dataForTesting;
|
||||
|
||||
SourceLoader(this.fileSystem, this.includeComments, KernelTarget target)
|
||||
@override
|
||||
final Map<Uri, LibraryBuilder> builders = <Uri, LibraryBuilder>{};
|
||||
|
||||
final Queue<LibraryBuilder> _unparsedLibraries = new Queue<LibraryBuilder>();
|
||||
|
||||
final List<Library> libraries = <Library>[];
|
||||
|
||||
@override
|
||||
final KernelTarget target;
|
||||
|
||||
/// List of all handled compile-time errors seen so far by libraries loaded
|
||||
/// by this loader.
|
||||
///
|
||||
/// A handled error is an error that has been added to the generated AST
|
||||
/// already, for example, as a throw expression.
|
||||
final List<LocatedMessage> handledErrors = <LocatedMessage>[];
|
||||
|
||||
/// List of all unhandled compile-time errors seen so far by libraries loaded
|
||||
/// by this loader.
|
||||
///
|
||||
/// An unhandled error is an error that hasn't been handled, see
|
||||
/// [handledErrors].
|
||||
final List<LocatedMessage> unhandledErrors = <LocatedMessage>[];
|
||||
|
||||
/// List of all problems seen so far by libraries loaded by this loader that
|
||||
/// does not belong directly to a library.
|
||||
final List<FormattedMessage> allComponentProblems = <FormattedMessage>[];
|
||||
|
||||
/// The text of the messages that have been reported.
|
||||
///
|
||||
/// This is used filter messages so that we don't report the same error twice.
|
||||
final Set<String> seenMessages = new Set<String>();
|
||||
|
||||
/// Set to `true` if one of the reported errors had severity `Severity.error`.
|
||||
///
|
||||
/// This is used for [hasSeenError].
|
||||
bool _hasSeenError = false;
|
||||
|
||||
/// Clears the [seenMessages] and [hasSeenError] state.
|
||||
void resetSeenMessages() {
|
||||
seenMessages.clear();
|
||||
_hasSeenError = false;
|
||||
}
|
||||
|
||||
/// Returns `true` if a compile time error has been reported.
|
||||
bool get hasSeenError => _hasSeenError;
|
||||
|
||||
LibraryBuilder? _coreLibrary;
|
||||
LibraryBuilder? typedDataLibrary;
|
||||
|
||||
/// The first library that we've been asked to compile. When compiling a
|
||||
/// program (aka script), this is the library that should have a main method.
|
||||
LibraryBuilder? first;
|
||||
|
||||
int byteCount = 0;
|
||||
|
||||
Uri? currentUriForCrashReporting;
|
||||
|
||||
SourceLoader(this.fileSystem, this.includeComments, this.target)
|
||||
: dataForTesting =
|
||||
retainDataForTesting ? new SourceLoaderDataForTesting() : null,
|
||||
super(target);
|
||||
retainDataForTesting ? new SourceLoaderDataForTesting() : null;
|
||||
|
||||
@override
|
||||
LibraryBuilder get coreLibrary => _coreLibrary!;
|
||||
|
||||
void set coreLibrary(LibraryBuilder value) {
|
||||
_coreLibrary = value;
|
||||
}
|
||||
|
||||
Ticker get ticker => target.ticker;
|
||||
|
||||
/// Look up a library builder by the [uri], or if such doesn't exist, create
|
||||
/// one. The canonical URI of the library is [uri], and its actual location is
|
||||
/// [fileUri].
|
||||
///
|
||||
/// Canonical URIs have schemes like "dart", or "package", and the actual
|
||||
/// location is often a file URI.
|
||||
///
|
||||
/// The [accessor] is the library that's trying to import, export, or include
|
||||
/// as part [uri], and [charOffset] is the location of the corresponding
|
||||
/// directive. If [accessor] isn't allowed to access [uri], it's a
|
||||
/// compile-time error.
|
||||
LibraryBuilder read(Uri uri, int charOffset,
|
||||
{Uri? fileUri,
|
||||
LibraryBuilder? accessor,
|
||||
LibraryBuilder? origin,
|
||||
Library? referencesFrom,
|
||||
bool? referenceIsPartOwner}) {
|
||||
LibraryBuilder builder = builders.putIfAbsent(uri, () {
|
||||
if (fileUri != null &&
|
||||
(fileUri!.scheme == "dart" ||
|
||||
fileUri!.scheme == "package" ||
|
||||
fileUri!.scheme == "dart-ext")) {
|
||||
fileUri = null;
|
||||
}
|
||||
package_config.Package? packageForLanguageVersion;
|
||||
if (fileUri == null) {
|
||||
switch (uri.scheme) {
|
||||
case "package":
|
||||
case "dart":
|
||||
fileUri = target.translateUri(uri) ??
|
||||
new Uri(
|
||||
scheme: untranslatableUriScheme,
|
||||
path: Uri.encodeComponent("$uri"));
|
||||
if (uri.scheme == "package") {
|
||||
packageForLanguageVersion = target.uriTranslator.getPackage(uri);
|
||||
} else {
|
||||
packageForLanguageVersion =
|
||||
target.uriTranslator.packages.packageOf(fileUri!);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fileUri = uri;
|
||||
packageForLanguageVersion =
|
||||
target.uriTranslator.packages.packageOf(fileUri!);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
packageForLanguageVersion =
|
||||
target.uriTranslator.packages.packageOf(fileUri!);
|
||||
}
|
||||
LanguageVersion? packageLanguageVersion;
|
||||
Uri? packageUri;
|
||||
Message? packageLanguageVersionProblem;
|
||||
if (packageForLanguageVersion != null) {
|
||||
Uri importUri = origin?.importUri ?? uri;
|
||||
if (importUri.scheme != 'dart' &&
|
||||
importUri.scheme != 'package' &&
|
||||
// ignore: unnecessary_null_comparison
|
||||
packageForLanguageVersion.name != null) {
|
||||
packageUri =
|
||||
new Uri(scheme: 'package', path: packageForLanguageVersion.name);
|
||||
}
|
||||
if (packageForLanguageVersion.languageVersion != null) {
|
||||
if (packageForLanguageVersion.languageVersion
|
||||
is package_config.InvalidLanguageVersion) {
|
||||
packageLanguageVersionProblem =
|
||||
messageLanguageVersionInvalidInDotPackages;
|
||||
packageLanguageVersion = new InvalidLanguageVersion(
|
||||
fileUri!, 0, noLength, target.currentSdkVersion, false);
|
||||
} else {
|
||||
Version version = new Version(
|
||||
packageForLanguageVersion.languageVersion!.major,
|
||||
packageForLanguageVersion.languageVersion!.minor);
|
||||
if (version > target.currentSdkVersion) {
|
||||
packageLanguageVersionProblem =
|
||||
templateLanguageVersionTooHigh.withArguments(
|
||||
target.currentSdkVersion.major,
|
||||
target.currentSdkVersion.minor);
|
||||
packageLanguageVersion = new InvalidLanguageVersion(
|
||||
fileUri!, 0, noLength, target.currentSdkVersion, false);
|
||||
} else {
|
||||
packageLanguageVersion = new ImplicitLanguageVersion(version);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
packageLanguageVersion ??=
|
||||
new ImplicitLanguageVersion(target.currentSdkVersion);
|
||||
|
||||
LibraryBuilder library = target.createLibraryBuilder(
|
||||
uri,
|
||||
fileUri!,
|
||||
packageUri,
|
||||
packageLanguageVersion,
|
||||
origin as SourceLibraryBuilder?,
|
||||
referencesFrom,
|
||||
referenceIsPartOwner);
|
||||
if (packageLanguageVersionProblem != null &&
|
||||
library is SourceLibraryBuilder) {
|
||||
library.addPostponedProblem(
|
||||
packageLanguageVersionProblem, 0, noLength, library.fileUri);
|
||||
}
|
||||
|
||||
if (uri.scheme == "dart") {
|
||||
if (uri.path == "core") {
|
||||
_coreLibrary = library;
|
||||
} else if (uri.path == "typed_data") {
|
||||
typedDataLibrary = library;
|
||||
}
|
||||
}
|
||||
if (library.loader != this) {
|
||||
if (_coreLibrary == library) {
|
||||
target.loadExtraRequiredLibraries(this);
|
||||
}
|
||||
// This library isn't owned by this loader, so no further processing
|
||||
// should be attempted.
|
||||
return library;
|
||||
}
|
||||
|
||||
{
|
||||
// Add any additional logic after this block. Setting the
|
||||
// firstSourceUri and first library should be done as early as
|
||||
// possible.
|
||||
firstSourceUri ??= uri;
|
||||
first ??= library;
|
||||
}
|
||||
if (_coreLibrary == library) {
|
||||
target.loadExtraRequiredLibraries(this);
|
||||
}
|
||||
Uri libraryUri = origin?.importUri ?? uri;
|
||||
if (target.backendTarget.mayDefineRestrictedType(libraryUri)) {
|
||||
library.mayImplementRestrictedTypes = true;
|
||||
}
|
||||
if (uri.scheme == "dart") {
|
||||
target.readPatchFiles(library as SourceLibraryBuilder);
|
||||
}
|
||||
_unparsedLibraries.addLast(library);
|
||||
return library;
|
||||
});
|
||||
if (accessor == null) {
|
||||
if (builder.loader == this && first != builder) {
|
||||
unhandled("null", "accessor", charOffset, uri);
|
||||
}
|
||||
} else {
|
||||
builder.recordAccess(charOffset, noLength, accessor.fileUri);
|
||||
if (!accessor.isPatch &&
|
||||
!accessor.isPart &&
|
||||
!target.backendTarget
|
||||
.allowPlatformPrivateLibraryAccess(accessor.importUri, uri)) {
|
||||
accessor.addProblem(messagePlatformPrivateLibraryAccess, charOffset,
|
||||
noLength, accessor.fileUri);
|
||||
}
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
void _ensureCoreLibrary() {
|
||||
if (_coreLibrary == null) {
|
||||
read(Uri.parse("dart:core"), 0, accessor: first);
|
||||
// TODO(askesc): When all backends support set literals, we no longer
|
||||
// need to index dart:collection, as it is only needed for desugaring of
|
||||
// const sets. We can remove it from this list at that time.
|
||||
read(Uri.parse("dart:collection"), 0, accessor: first);
|
||||
assert(_coreLibrary != null);
|
||||
}
|
||||
}
|
||||
|
||||
Future<Null> buildBodies() async {
|
||||
assert(_coreLibrary != null);
|
||||
for (LibraryBuilder library in builders.values) {
|
||||
if (library.loader == this) {
|
||||
currentUriForCrashReporting = library.importUri;
|
||||
await buildBody(library);
|
||||
}
|
||||
}
|
||||
currentUriForCrashReporting = null;
|
||||
logSummary(templateSourceBodySummary);
|
||||
}
|
||||
|
||||
void logSummary(Template<SummaryTemplate> template) {
|
||||
ticker.log((Duration elapsed, Duration sinceStart) {
|
||||
int libraryCount = 0;
|
||||
for (LibraryBuilder library in builders.values) {
|
||||
if (library.loader == this) libraryCount++;
|
||||
}
|
||||
double ms = elapsed.inMicroseconds / Duration.microsecondsPerMillisecond;
|
||||
Message message = template.withArguments(
|
||||
libraryCount, byteCount, ms, byteCount / ms, ms / libraryCount);
|
||||
print("$sinceStart: ${message.message}");
|
||||
});
|
||||
}
|
||||
|
||||
/// Register [message] as a problem with a severity determined by the
|
||||
/// intrinsic severity of the message.
|
||||
@override
|
||||
FormattedMessage? addProblem(
|
||||
Message message, int charOffset, int length, Uri? fileUri,
|
||||
{bool wasHandled: false,
|
||||
List<LocatedMessage>? context,
|
||||
Severity? severity,
|
||||
bool problemOnLibrary: false,
|
||||
List<Uri>? involvedFiles}) {
|
||||
return addMessage(message, charOffset, length, fileUri, severity,
|
||||
wasHandled: wasHandled,
|
||||
context: context,
|
||||
problemOnLibrary: problemOnLibrary,
|
||||
involvedFiles: involvedFiles);
|
||||
}
|
||||
|
||||
/// All messages reported by the compiler (errors, warnings, etc.) are routed
|
||||
/// through this method.
|
||||
///
|
||||
/// Returns a FormattedMessage if the message is new, that is, not previously
|
||||
/// reported. This is important as some parser errors may be reported up to
|
||||
/// three times by `OutlineBuilder`, `DietListener`, and `BodyBuilder`.
|
||||
/// If the message is not new, [null] is reported.
|
||||
///
|
||||
/// If [severity] is `Severity.error`, the message is added to
|
||||
/// [handledErrors] if [wasHandled] is true or to [unhandledErrors] if
|
||||
/// [wasHandled] is false.
|
||||
FormattedMessage? addMessage(Message message, int charOffset, int length,
|
||||
Uri? fileUri, Severity? severity,
|
||||
{bool wasHandled: false,
|
||||
List<LocatedMessage>? context,
|
||||
bool problemOnLibrary: false,
|
||||
List<Uri>? involvedFiles}) {
|
||||
severity ??= message.code.severity;
|
||||
if (severity == Severity.ignored) return null;
|
||||
String trace = """
|
||||
message: ${message.message}
|
||||
charOffset: $charOffset
|
||||
fileUri: $fileUri
|
||||
severity: $severity
|
||||
""";
|
||||
if (!seenMessages.add(trace)) return null;
|
||||
if (message.code.severity == Severity.error) {
|
||||
_hasSeenError = true;
|
||||
}
|
||||
if (message.code.severity == Severity.context) {
|
||||
internalProblem(
|
||||
templateInternalProblemContextSeverity
|
||||
.withArguments(message.code.name),
|
||||
charOffset,
|
||||
fileUri);
|
||||
}
|
||||
target.context.report(
|
||||
fileUri != null
|
||||
? message.withLocation(fileUri, charOffset, length)
|
||||
: message.withoutLocation(),
|
||||
severity,
|
||||
context: context,
|
||||
involvedFiles: involvedFiles);
|
||||
if (severity == Severity.error) {
|
||||
(wasHandled ? handledErrors : unhandledErrors).add(fileUri != null
|
||||
? message.withLocation(fileUri, charOffset, length)
|
||||
: message.withoutLocation());
|
||||
}
|
||||
FormattedMessage formattedMessage = target.createFormattedMessage(
|
||||
message, charOffset, length, fileUri, context, severity,
|
||||
involvedFiles: involvedFiles);
|
||||
if (!problemOnLibrary) {
|
||||
allComponentProblems.add(formattedMessage);
|
||||
}
|
||||
return formattedMessage;
|
||||
}
|
||||
|
||||
MemberBuilder getAbstractClassInstantiationError() {
|
||||
return target.getAbstractClassInstantiationError(this);
|
||||
}
|
||||
|
||||
MemberBuilder getCompileTimeError() => target.getCompileTimeError(this);
|
||||
|
||||
MemberBuilder getDuplicatedFieldInitializerError() {
|
||||
return target.getDuplicatedFieldInitializerError(this);
|
||||
}
|
||||
|
||||
MemberBuilder getNativeAnnotation() => target.getNativeAnnotation(this);
|
||||
|
||||
BodyBuilder createBodyBuilderForOutlineExpression(
|
||||
SourceLibraryBuilder library,
|
||||
DeclarationBuilder? declarationBuilder,
|
||||
ModifierBuilder member,
|
||||
Scope scope,
|
||||
Uri fileUri) {
|
||||
return new BodyBuilder.forOutlineExpression(
|
||||
library, declarationBuilder, member, scope, fileUri);
|
||||
}
|
||||
|
||||
NnbdMode get nnbdMode => target.context.options.nnbdMode;
|
||||
|
||||
|
@ -203,13 +525,9 @@ class SourceLoader extends Loader {
|
|||
|
||||
ClassHierarchyBuilder get builderHierarchy => _builderHierarchy!;
|
||||
|
||||
@override
|
||||
Template<SummaryTemplate> get outlineSummaryTemplate =>
|
||||
templateSourceOutlineSummary;
|
||||
|
||||
@override
|
||||
bool get isSourceLoader => true;
|
||||
|
||||
Future<Token> tokenize(SourceLibraryBuilder library,
|
||||
{bool suppressLexicalErrors: false}) async {
|
||||
Uri fileUri = library.fileUri;
|
||||
|
@ -372,9 +690,15 @@ class SourceLoader extends Loader {
|
|||
_typeInferenceEngine!.typeDependencies[member] = typeDependency;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Null> buildOutlines() async {
|
||||
await super.buildOutlines();
|
||||
_ensureCoreLibrary();
|
||||
while (_unparsedLibraries.isNotEmpty) {
|
||||
LibraryBuilder library = _unparsedLibraries.removeFirst();
|
||||
currentUriForCrashReporting = library.importUri;
|
||||
await buildOutline(library as SourceLibraryBuilder);
|
||||
}
|
||||
currentUriForCrashReporting = null;
|
||||
logSummary(outlineSummaryTemplate);
|
||||
|
||||
if (_strongOptOutLibraries != null) {
|
||||
// We have libraries that are opted out in strong mode "non-explicitly",
|
||||
|
@ -409,9 +733,9 @@ class SourceLoader extends Loader {
|
|||
Set<LibraryBuilder> libraries,
|
||||
{required bool emitNonPackageErrors}) {
|
||||
Map<String?, List<LibraryBuilder>> libraryByPackage = {};
|
||||
Map<Package, Version> enableNonNullableVersionByPackage = {};
|
||||
Map<package_config.Package, Version> enableNonNullableVersionByPackage = {};
|
||||
for (LibraryBuilder libraryBuilder in libraries) {
|
||||
final Package? package =
|
||||
final package_config.Package? package =
|
||||
target.uriTranslator.getPackage(libraryBuilder.importUri);
|
||||
|
||||
if (package != null &&
|
||||
|
@ -476,7 +800,6 @@ class SourceLoader extends Loader {
|
|||
return bytes.sublist(0, bytes.length - 1);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Null> buildOutline(SourceLibraryBuilder library) async {
|
||||
Token tokens = await tokenize(library);
|
||||
// ignore: unnecessary_null_comparison
|
||||
|
@ -485,7 +808,7 @@ class SourceLoader extends Loader {
|
|||
new ClassMemberParser(listener).parseUnit(tokens);
|
||||
}
|
||||
|
||||
@override
|
||||
/// Builds all the method bodies found in the given [library].
|
||||
Future<Null> buildBody(LibraryBuilder library) async {
|
||||
if (library is SourceLibraryBuilder) {
|
||||
// We tokenize source files twice to keep memory usage low. This is the
|
||||
|
@ -578,9 +901,6 @@ class SourceLoader extends Loader {
|
|||
parameters);
|
||||
}
|
||||
|
||||
@override
|
||||
KernelTarget get target => super.target as KernelTarget;
|
||||
|
||||
DietListener createDietListener(SourceLibraryBuilder library) {
|
||||
return new DietListener(library, hierarchy, coreTypes, typeInferenceEngine);
|
||||
}
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
// 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.
|
||||
|
||||
library fasta.target;
|
||||
|
||||
import 'package:kernel/ast.dart' show Component;
|
||||
|
||||
import 'ticker.dart' show Ticker;
|
||||
|
||||
/// A compilation target.
|
||||
///
|
||||
/// A target reads source files with [read], builds outlines when
|
||||
/// [buildOutlines] is called and builds the full component when
|
||||
/// [buildComponent] is called.
|
||||
abstract class Target {
|
||||
final Ticker ticker;
|
||||
|
||||
Target(this.ticker);
|
||||
|
||||
/// Build and return outlines for all libraries.
|
||||
Future<Component?> buildOutlines();
|
||||
|
||||
/// Build and return the full component for all libraries.
|
||||
Future<Component?> buildComponent();
|
||||
}
|
|
@ -2,230 +2,13 @@
|
|||
// 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 fasta.target_implementation;
|
||||
|
||||
import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
|
||||
|
||||
import 'package:kernel/ast.dart' show Library, Source, Version;
|
||||
|
||||
import 'package:kernel/target/targets.dart' as backend show Target;
|
||||
|
||||
import '../base/processed_options.dart' show ProcessedOptions;
|
||||
|
||||
import 'builder/class_builder.dart';
|
||||
import 'builder/library_builder.dart';
|
||||
import 'builder/member_builder.dart';
|
||||
import 'source/source_library_builder.dart' show LanguageVersion;
|
||||
import 'package:kernel/target/targets.dart' show Target;
|
||||
|
||||
import 'compiler_context.dart' show CompilerContext;
|
||||
|
||||
import 'loader.dart' show Loader;
|
||||
|
||||
import 'messages.dart' show FormattedMessage, LocatedMessage, Message;
|
||||
|
||||
import 'target.dart' show Target;
|
||||
|
||||
import 'ticker.dart' show Ticker;
|
||||
|
||||
import 'uri_translator.dart' show UriTranslator;
|
||||
|
||||
import '../api_prototype/experimental_flags.dart' show ExperimentalFlag;
|
||||
|
||||
/// Provides the implementation details used by a loader for a target.
|
||||
abstract class TargetImplementation extends Target {
|
||||
final UriTranslator uriTranslator;
|
||||
abstract class TargetImplementation {
|
||||
CompilerContext get context;
|
||||
|
||||
final backend.Target backendTarget;
|
||||
|
||||
final CompilerContext context = CompilerContext.current;
|
||||
|
||||
/// Shared with [CompilerContext].
|
||||
final Map<Uri, Source> uriToSource = CompilerContext.current.uriToSource;
|
||||
|
||||
MemberBuilder? cachedAbstractClassInstantiationError;
|
||||
MemberBuilder? cachedCompileTimeError;
|
||||
MemberBuilder? cachedDuplicatedFieldInitializerError;
|
||||
MemberBuilder? cachedNativeAnnotation;
|
||||
|
||||
final ProcessedOptions _options;
|
||||
|
||||
TargetImplementation(Ticker ticker, this.uriTranslator, this.backendTarget)
|
||||
// ignore: unnecessary_null_comparison
|
||||
: assert(ticker != null),
|
||||
// ignore: unnecessary_null_comparison
|
||||
assert(uriTranslator != null),
|
||||
// ignore: unnecessary_null_comparison
|
||||
assert(backendTarget != null),
|
||||
_options = CompilerContext.current.options,
|
||||
super(ticker);
|
||||
|
||||
bool isExperimentEnabledInLibrary(ExperimentalFlag flag, Uri importUri) {
|
||||
return _options.isExperimentEnabledInLibrary(flag, importUri);
|
||||
}
|
||||
|
||||
Version getExperimentEnabledVersionInLibrary(
|
||||
ExperimentalFlag flag, Uri importUri) {
|
||||
return _options.getExperimentEnabledVersionInLibrary(flag, importUri);
|
||||
}
|
||||
|
||||
bool isExperimentEnabledInLibraryByVersion(
|
||||
ExperimentalFlag flag, Uri importUri, Version version) {
|
||||
return _options.isExperimentEnabledInLibraryByVersion(
|
||||
flag, importUri, version);
|
||||
}
|
||||
|
||||
/// Returns `true` if the [flag] is enabled by default.
|
||||
bool isExperimentEnabledByDefault(ExperimentalFlag flag) {
|
||||
return _options.isExperimentEnabledByDefault(flag);
|
||||
}
|
||||
|
||||
/// Returns `true` if the [flag] is enabled globally.
|
||||
///
|
||||
/// This is `true` either if the [flag] is passed through an explicit
|
||||
/// `--enable-experiment` option or if the [flag] is expired and on by
|
||||
/// default.
|
||||
bool isExperimentEnabledGlobally(ExperimentalFlag flag) {
|
||||
return _options.isExperimentEnabledGlobally(flag);
|
||||
}
|
||||
|
||||
/// Creates a [LibraryBuilder] corresponding to [uri], if one doesn't exist
|
||||
/// already.
|
||||
///
|
||||
/// [fileUri] must not be null and is a URI that can be passed to FileSystem
|
||||
/// to locate the corresponding file.
|
||||
///
|
||||
/// [origin] is non-null if the created library is a patch to [origin].
|
||||
///
|
||||
/// [packageUri] is the base uri for the package which the library belongs to.
|
||||
/// For instance 'package:foo'.
|
||||
///
|
||||
/// This is used to associate libraries in for instance the 'bin' and 'test'
|
||||
/// folders of a package source with the package uri of the 'lib' folder.
|
||||
///
|
||||
/// If the [packageUri] is `null` the package association of this library is
|
||||
/// based on its [importUri].
|
||||
///
|
||||
/// For libraries with a 'package:' [importUri], the package path must match
|
||||
/// the path in the [importUri]. For libraries with a 'dart:' [importUri] the
|
||||
/// [packageUri] must be `null`.
|
||||
///
|
||||
/// [packageLanguageVersion] is the language version defined by the package
|
||||
/// which the library belongs to, or the current sdk version if the library
|
||||
/// doesn't belong to a package.
|
||||
LibraryBuilder? createLibraryBuilder(
|
||||
Uri uri,
|
||||
Uri fileUri,
|
||||
Uri? packageUri,
|
||||
LanguageVersion packageLanguageVersion,
|
||||
covariant LibraryBuilder? origin,
|
||||
Library? referencesFrom,
|
||||
bool? referenceIsPartOwner);
|
||||
|
||||
/// The class [cls] is involved in a cyclic definition. This method should
|
||||
/// ensure that the cycle is broken, for example, by removing superclass and
|
||||
/// implemented interfaces.
|
||||
void breakCycle(ClassBuilder cls);
|
||||
|
||||
Uri? translateUri(Uri uri) => uriTranslator.translate(uri);
|
||||
|
||||
/// Returns a reference to the constructor of
|
||||
/// [AbstractClassInstantiationError] error. The constructor is expected to
|
||||
/// accept a single argument of type String, which is the name of the
|
||||
/// abstract class.
|
||||
MemberBuilder getAbstractClassInstantiationError(Loader loader) {
|
||||
return cachedAbstractClassInstantiationError ??=
|
||||
loader.coreLibrary.getConstructor("AbstractClassInstantiationError");
|
||||
}
|
||||
|
||||
/// Returns a reference to the constructor used for creating a compile-time
|
||||
/// error. The constructor is expected to accept a single argument of type
|
||||
/// String, which is the compile-time error message.
|
||||
MemberBuilder getCompileTimeError(Loader loader) {
|
||||
return cachedCompileTimeError ??= loader.coreLibrary
|
||||
.getConstructor("_CompileTimeError", bypassLibraryPrivacy: true);
|
||||
}
|
||||
|
||||
/// Returns a reference to the constructor used for creating a runtime error
|
||||
/// when a final field is initialized twice. The constructor is expected to
|
||||
/// accept a single argument which is the name of the field.
|
||||
MemberBuilder getDuplicatedFieldInitializerError(Loader loader) {
|
||||
return cachedDuplicatedFieldInitializerError ??= loader.coreLibrary
|
||||
.getConstructor("_DuplicatedFieldInitializerError",
|
||||
bypassLibraryPrivacy: true);
|
||||
}
|
||||
|
||||
/// Returns a reference to the constructor used for creating `native`
|
||||
/// annotations. The constructor is expected to accept a single argument of
|
||||
/// type String, which is the name of the native method.
|
||||
MemberBuilder getNativeAnnotation(Loader loader) {
|
||||
if (cachedNativeAnnotation != null) return cachedNativeAnnotation!;
|
||||
LibraryBuilder internal = loader.read(Uri.parse("dart:_internal"), -1,
|
||||
accessor: loader.coreLibrary);
|
||||
return cachedNativeAnnotation = internal.getConstructor("ExternalName");
|
||||
}
|
||||
|
||||
void loadExtraRequiredLibraries(Loader loader) {
|
||||
for (String uri in backendTarget.extraRequiredLibraries) {
|
||||
loader.read(Uri.parse(uri), 0, accessor: loader.coreLibrary);
|
||||
}
|
||||
if (context.compilingPlatform) {
|
||||
for (String uri in backendTarget.extraRequiredLibrariesPlatform) {
|
||||
loader.read(Uri.parse(uri), 0, accessor: loader.coreLibrary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addSourceInformation(
|
||||
Uri importUri, Uri fileUri, List<int> lineStarts, List<int> sourceCode);
|
||||
|
||||
void readPatchFiles(covariant LibraryBuilder library) {}
|
||||
|
||||
FormattedMessage createFormattedMessage(
|
||||
Message message,
|
||||
int charOffset,
|
||||
int length,
|
||||
Uri? fileUri,
|
||||
List<LocatedMessage>? messageContext,
|
||||
Severity severity,
|
||||
{List<Uri>? involvedFiles}) {
|
||||
ProcessedOptions processedOptions = context.options;
|
||||
return processedOptions.format(
|
||||
fileUri != null
|
||||
? message.withLocation(fileUri, charOffset, length)
|
||||
: message.withoutLocation(),
|
||||
severity,
|
||||
messageContext,
|
||||
involvedFiles: involvedFiles);
|
||||
}
|
||||
|
||||
String get currentSdkVersionString {
|
||||
return CompilerContext.current.options.currentSdkVersion;
|
||||
}
|
||||
|
||||
Version? _currentSdkVersion;
|
||||
Version get currentSdkVersion {
|
||||
if (_currentSdkVersion == null) {
|
||||
_parseCurrentSdkVersion();
|
||||
}
|
||||
return _currentSdkVersion!;
|
||||
}
|
||||
|
||||
void _parseCurrentSdkVersion() {
|
||||
bool good = false;
|
||||
// ignore: unnecessary_null_comparison
|
||||
if (currentSdkVersionString != null) {
|
||||
List<String> dotSeparatedParts = currentSdkVersionString.split(".");
|
||||
if (dotSeparatedParts.length >= 2) {
|
||||
_currentSdkVersion = new Version(int.tryParse(dotSeparatedParts[0])!,
|
||||
int.tryParse(dotSeparatedParts[1])!);
|
||||
good = true;
|
||||
}
|
||||
}
|
||||
if (!good) {
|
||||
throw new StateError(
|
||||
"Unparsable sdk version given: $currentSdkVersionString");
|
||||
}
|
||||
}
|
||||
|
||||
void releaseAncillaryResources();
|
||||
Target get backendTarget;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ import 'fasta/kernel/utils.dart' show printComponentText, serializeComponent;
|
|||
|
||||
import 'fasta/kernel/verifier.dart' show verifyComponent;
|
||||
|
||||
import 'fasta/loader.dart' show Loader;
|
||||
import 'fasta/source/source_loader.dart' show SourceLoader;
|
||||
|
||||
import 'fasta/uri_translator.dart' show UriTranslator;
|
||||
|
||||
|
@ -67,7 +67,7 @@ Future<CompilerResult> generateKernelInternal(
|
|||
options.reportNullSafetyCompilationModeInfo();
|
||||
FileSystem fs = options.fileSystem;
|
||||
|
||||
Loader? sourceLoader;
|
||||
SourceLoader? sourceLoader;
|
||||
return withCrashReporting<CompilerResult>(() async {
|
||||
UriTranslator uriTranslator = await options.getUriTranslator();
|
||||
|
||||
|
@ -90,7 +90,7 @@ Future<CompilerResult> generateKernelInternal(
|
|||
dillTarget.loader.appendLibraries(additionalDill);
|
||||
}
|
||||
|
||||
await dillTarget.buildOutlines();
|
||||
dillTarget.buildOutlines();
|
||||
|
||||
KernelTarget kernelTarget =
|
||||
new KernelTarget(fs, false, dillTarget, uriTranslator);
|
||||
|
|
|
@ -1895,7 +1895,7 @@ class Outline extends Step<TestDescription, ComponentResult, FastaContext> {
|
|||
StandardFileSystem.instance, false, dillTarget, uriTranslator);
|
||||
|
||||
sourceTarget.setEntryPoints(entryPoints);
|
||||
await dillTarget.buildOutlines();
|
||||
dillTarget.buildOutlines();
|
||||
return sourceTarget;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -289,7 +289,7 @@ class CompileTask {
|
|||
CompilerContext.recordDependency(platform);
|
||||
}
|
||||
kernelTarget.setEntryPoints(c.options.inputs);
|
||||
await dillTarget.buildOutlines();
|
||||
dillTarget.buildOutlines();
|
||||
await kernelTarget.loader.buildOutlines();
|
||||
|
||||
Uri? dFile;
|
||||
|
@ -328,7 +328,7 @@ class CompileTask {
|
|||
}
|
||||
|
||||
kernelTarget.setEntryPoints(c.options.inputs);
|
||||
await dillTarget.buildOutlines();
|
||||
dillTarget.buildOutlines();
|
||||
var outline = await kernelTarget.buildOutlines();
|
||||
if (c.options.debugDump && output != null) {
|
||||
printComponentText(outline,
|
||||
|
|
|
@ -883,7 +883,7 @@ class DocTestIncrementalKernelTarget extends IncrementalKernelTarget {
|
|||
Uri fileUri,
|
||||
Uri? packageUri,
|
||||
LanguageVersion packageLanguageVersion,
|
||||
SourceLibraryBuilder origin,
|
||||
SourceLibraryBuilder? origin,
|
||||
kernel.Library? referencesFrom,
|
||||
bool? referenceIsPartOwner) {
|
||||
if (uri == DocTestIncrementalCompiler.dartDocTestUri) {
|
||||
|
|
Loading…
Reference in a new issue