1eda15854d
Experiments that have not be enabled by default should only be allowed in the current version of the sdk. Closes #45460 Change-Id: I159f390ac85fe37943920717ce11a4c817d5b4a9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193480 Commit-Queue: Johnni Winther <johnniwinther@google.com> Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
234 lines
8.4 KiB
Dart
234 lines
8.4 KiB
Dart
// 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.
|
|
|
|
// @dart = 2.9
|
|
|
|
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 '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;
|
|
|
|
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)
|
|
: assert(ticker != null),
|
|
assert(uriTranslator != null),
|
|
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) {
|
|
if (cachedAbstractClassInstantiationError != null) {
|
|
return cachedAbstractClassInstantiationError;
|
|
}
|
|
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) {
|
|
if (cachedCompileTimeError != null) return cachedCompileTimeError;
|
|
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) {
|
|
if (cachedDuplicatedFieldInitializerError != null) {
|
|
return cachedDuplicatedFieldInitializerError;
|
|
}
|
|
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(
|
|
message.withLocation(fileUri, charOffset, length),
|
|
severity,
|
|
messageContext,
|
|
involvedFiles: involvedFiles);
|
|
}
|
|
|
|
String get currentSdkVersionString {
|
|
return CompilerContext.current.options.currentSdkVersion;
|
|
}
|
|
|
|
Version _currentSdkVersion;
|
|
Version get currentSdkVersion {
|
|
if (_currentSdkVersion != null) return _currentSdkVersion;
|
|
_parseCurrentSdkVersion();
|
|
return _currentSdkVersion;
|
|
}
|
|
|
|
void _parseCurrentSdkVersion() {
|
|
bool good = false;
|
|
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();
|
|
}
|