| // Copyright (c) 2014, 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. | |
| // TODO(sigmund): rename and move to common/elements.dart | |
| library dart2js.type_system; | |
| import 'common.dart'; | |
| import 'common/names.dart' show Identifiers, Uris; | |
| import 'constants/expressions.dart' show ConstantExpression; | |
| import 'constants/values.dart'; | |
| import 'elements/entities.dart'; | |
| import 'elements/types.dart'; | |
| import 'js_backend/backend.dart' show JavaScriptBackend; | |
| import 'js_backend/constant_system_javascript.dart'; | |
| import 'js_backend/native_data.dart' show NativeBasicData; | |
| import 'native/native.dart'; | |
| import 'types/abstract_value_domain.dart'; | |
| import 'universe/selector.dart' show Selector; | |
| /// The common elements and types in Dart. | |
| abstract class CommonElements { | |
| /// The `Object` class defined in 'dart:core'. | |
| ClassEntity get objectClass; | |
| /// The `bool` class defined in 'dart:core'. | |
| ClassEntity get boolClass; | |
| /// The `num` class defined in 'dart:core'. | |
| ClassEntity get numClass; | |
| /// The `int` class defined in 'dart:core'. | |
| ClassEntity get intClass; | |
| /// The `double` class defined in 'dart:core'. | |
| ClassEntity get doubleClass; | |
| /// The `String` class defined in 'dart:core'. | |
| ClassEntity get stringClass; | |
| /// The `Function` class defined in 'dart:core'. | |
| ClassEntity get functionClass; | |
| /// The `Resource` class defined in 'dart:core'. | |
| ClassEntity get resourceClass; | |
| /// The `Symbol` class defined in 'dart:core'. | |
| ClassEntity get symbolClass; | |
| /// The `Null` class defined in 'dart:core'. | |
| ClassEntity get nullClass; | |
| /// The `Type` class defined in 'dart:core'. | |
| ClassEntity get typeClass; | |
| /// The `StackTrace` class defined in 'dart:core'; | |
| ClassEntity get stackTraceClass; | |
| /// The `List` class defined in 'dart:core'; | |
| ClassEntity get listClass; | |
| /// The `Map` class defined in 'dart:core'; | |
| ClassEntity get mapClass; | |
| /// The `Iterable` class defined in 'dart:core'; | |
| ClassEntity get iterableClass; | |
| /// The `Future` class defined in 'async';. | |
| ClassEntity get futureClass; | |
| /// The `Stream` class defined in 'async'; | |
| ClassEntity get streamClass; | |
| /// The dart:core library. | |
| LibraryEntity get coreLibrary; | |
| /// The dart:async library. | |
| LibraryEntity get asyncLibrary; | |
| /// The dart:mirrors library. | |
| LibraryEntity get mirrorsLibrary; | |
| /// The dart:typed_data library. | |
| LibraryEntity get typedDataLibrary; | |
| /// The dart:_js_helper library. | |
| LibraryEntity get jsHelperLibrary; | |
| /// The dart:_interceptors library. | |
| LibraryEntity get interceptorsLibrary; | |
| /// The dart:_foreign_helper library. | |
| LibraryEntity get foreignLibrary; | |
| /// The dart:_internal library. | |
| LibraryEntity get internalLibrary; | |
| /// The `NativeTypedData` class from dart:typed_data. | |
| ClassEntity get typedDataClass; | |
| /// Constructor of the `Symbol` class in dart:internal. This getter will | |
| /// ensure that `Symbol` is resolved and lookup the constructor on demand. | |
| ConstructorEntity get symbolConstructorTarget; | |
| /// Whether [element] is the same as [symbolConstructor]. Used to check | |
| /// for the constructor without computing it until it is likely to be seen. | |
| bool isSymbolConstructor(ConstructorEntity element); | |
| /// The function `identical` in dart:core. | |
| FunctionEntity get identicalFunction; | |
| /// Whether [element] is the `Function.apply` method. This will not | |
| /// resolve the apply method if it hasn't been seen yet during compilation. | |
| bool isFunctionApplyMethod(MemberEntity element); | |
| /// The `dynamic` type. | |
| DynamicType get dynamicType; | |
| /// The `Object` type defined in 'dart:core'. | |
| InterfaceType get objectType; | |
| /// The `bool` type defined in 'dart:core'. | |
| InterfaceType get boolType; | |
| /// The `num` type defined in 'dart:core'. | |
| InterfaceType get numType; | |
| /// The `int` type defined in 'dart:core'. | |
| InterfaceType get intType; | |
| /// The `double` type defined in 'dart:core'. | |
| InterfaceType get doubleType; | |
| /// The `Resource` type defined in 'dart:core'. | |
| InterfaceType get resourceType; | |
| /// The `String` type defined in 'dart:core'. | |
| InterfaceType get stringType; | |
| /// The `Symbol` type defined in 'dart:core'. | |
| InterfaceType get symbolType; | |
| /// The `Function` type defined in 'dart:core'. | |
| InterfaceType get functionType; | |
| /// The `Null` type defined in 'dart:core'. | |
| InterfaceType get nullType; | |
| /// The `Type` type defined in 'dart:core'. | |
| InterfaceType get typeType; | |
| InterfaceType get typeLiteralType; | |
| /// The `StackTrace` type defined in 'dart:core'; | |
| InterfaceType get stackTraceType; | |
| /// Returns an instance of the `List` type defined in 'dart:core' with | |
| /// [elementType] as its type argument. | |
| /// | |
| /// If no type argument is provided, the canonical raw type is returned. | |
| InterfaceType listType([DartType elementType]); | |
| /// Returns an instance of the `Map` type defined in 'dart:core' with | |
| /// [keyType] and [valueType] as its type arguments. | |
| /// | |
| /// If no type arguments are provided, the canonical raw type is returned. | |
| InterfaceType mapType([DartType keyType, DartType valueType]); | |
| /// Returns an instance of the `Iterable` type defined in 'dart:core' with | |
| /// [elementType] as its type argument. | |
| /// | |
| /// If no type argument is provided, the canonical raw type is returned. | |
| InterfaceType iterableType([DartType elementType]); | |
| /// Returns an instance of the `Future` type defined in 'dart:async' with | |
| /// [elementType] as its type argument. | |
| /// | |
| /// If no type argument is provided, the canonical raw type is returned. | |
| InterfaceType futureType([DartType elementType]); | |
| /// Returns an instance of the `Stream` type defined in 'dart:async' with | |
| /// [elementType] as its type argument. | |
| /// | |
| /// If no type argument is provided, the canonical raw type is returned. | |
| InterfaceType streamType([DartType elementType]); | |
| /// Returns `true` if [element] is a superclass of `String` or `num`. | |
| bool isNumberOrStringSupertype(ClassEntity element); | |
| /// Returns `true` if [element] is a superclass of `String`. | |
| bool isStringOnlySupertype(ClassEntity element); | |
| /// Returns `true` if [element] is a superclass of `List`. | |
| bool isListSupertype(ClassEntity element); | |
| InterfaceType getConstantMapTypeFor(InterfaceType sourceType, | |
| {bool hasProtoKey: false, bool onlyStringKeys: false}); | |
| FieldEntity get symbolField; | |
| InterfaceType get symbolImplementationType; | |
| // From dart:core | |
| ClassEntity get mapLiteralClass; | |
| ConstructorEntity get mapLiteralConstructor; | |
| ConstructorEntity get mapLiteralConstructorEmpty; | |
| FunctionEntity get mapLiteralUntypedMaker; | |
| FunctionEntity get mapLiteralUntypedEmptyMaker; | |
| FunctionEntity get objectNoSuchMethod; | |
| bool isDefaultNoSuchMethodImplementation(FunctionEntity element); | |
| // From dart:async | |
| FunctionEntity get asyncHelperStart; | |
| FunctionEntity get asyncHelperStartSync; | |
| FunctionEntity get asyncHelperAwait; | |
| FunctionEntity get asyncHelperReturn; | |
| FunctionEntity get asyncHelperRethrow; | |
| FunctionEntity get wrapBody; | |
| FunctionEntity get yieldStar; | |
| FunctionEntity get yieldSingle; | |
| FunctionEntity get syncStarUncaughtError; | |
| FunctionEntity get asyncStarHelper; | |
| FunctionEntity get streamOfController; | |
| FunctionEntity get endOfIteration; | |
| ClassEntity get syncStarIterable; | |
| ClassEntity get futureImplementation; | |
| ClassEntity get controllerStream; | |
| ClassEntity get streamIterator; | |
| ConstructorEntity get streamIteratorConstructor; | |
| FunctionEntity get syncStarIterableFactory; | |
| FunctionEntity get asyncAwaitCompleterFactory; | |
| FunctionEntity get syncCompleterFactory; | |
| FunctionEntity get asyncStarStreamControllerFactory; | |
| ClassEntity get jsInterceptorClass; | |
| ClassEntity get jsStringClass; | |
| ClassEntity get jsArrayClass; | |
| ClassEntity get jsNumberClass; | |
| ClassEntity get jsIntClass; | |
| ClassEntity get jsDoubleClass; | |
| ClassEntity get jsNullClass; | |
| ClassEntity get jsBoolClass; | |
| ClassEntity get jsPlainJavaScriptObjectClass; | |
| ClassEntity get jsUnknownJavaScriptObjectClass; | |
| ClassEntity get jsJavaScriptFunctionClass; | |
| ClassEntity get jsJavaScriptObjectClass; | |
| ClassEntity get jsIndexableClass; | |
| ClassEntity get jsMutableIndexableClass; | |
| ClassEntity get jsMutableArrayClass; | |
| ClassEntity get jsFixedArrayClass; | |
| ClassEntity get jsExtendableArrayClass; | |
| ClassEntity get jsUnmodifiableArrayClass; | |
| ClassEntity get jsPositiveIntClass; | |
| ClassEntity get jsUInt32Class; | |
| ClassEntity get jsUInt31Class; | |
| /// Returns `true` member is the 'findIndexForNativeSubclassType' method | |
| /// declared in `dart:_interceptors`. | |
| bool isFindIndexForNativeSubclassType(MemberEntity member); | |
| FunctionEntity get getNativeInterceptorMethod; | |
| ConstructorEntity get jsArrayTypedConstructor; | |
| // From dart:_js_helper | |
| // TODO(johnniwinther): Avoid the need for this (from [CheckedModeHelper]). | |
| FunctionEntity findHelperFunction(String name); | |
| ClassEntity get closureClass; | |
| ClassEntity get boundClosureClass; | |
| ClassEntity get typeLiteralClass; | |
| ClassEntity get constMapLiteralClass; | |
| ClassEntity get typeVariableClass; | |
| ClassEntity get jsInvocationMirrorClass; | |
| MemberEntity get invocationTypeArgumentGetter; | |
| /// Interface used to determine if an object has the JavaScript | |
| /// indexing behavior. The interface is only visible to specific libraries. | |
| ClassEntity get jsIndexingBehaviorInterface; | |
| ClassEntity get stackTraceHelperClass; | |
| ClassEntity get constantMapClass; | |
| ClassEntity get constantStringMapClass; | |
| ClassEntity get constantProtoMapClass; | |
| ClassEntity get generalConstantMapClass; | |
| ClassEntity get annotationCreatesClass; | |
| ClassEntity get annotationReturnsClass; | |
| ClassEntity get annotationJSNameClass; | |
| /// The class for native annotations defined in dart:_js_helper. | |
| ClassEntity get nativeAnnotationClass; | |
| ConstructorEntity get typeVariableConstructor; | |
| FunctionEntity get assertTest; | |
| FunctionEntity get assertThrow; | |
| FunctionEntity get assertHelper; | |
| FunctionEntity get assertUnreachableMethod; | |
| /// Holds the method "getIsolateAffinityTag" when dart:_js_helper has been | |
| /// loaded. | |
| FunctionEntity get getIsolateAffinityTagMarker; | |
| /// Holds the method "requiresPreamble" in _js_helper. | |
| FunctionEntity get requiresPreambleMarker; | |
| FunctionEntity get loadLibraryWrapper; | |
| FunctionEntity get loadDeferredLibrary; | |
| FunctionEntity get boolConversionCheck; | |
| FunctionEntity get traceHelper; | |
| FunctionEntity get closureFromTearOff; | |
| FunctionEntity get isJsIndexable; | |
| FunctionEntity get throwIllegalArgumentException; | |
| FunctionEntity get throwIndexOutOfRangeException; | |
| FunctionEntity get exceptionUnwrapper; | |
| FunctionEntity get throwRuntimeError; | |
| FunctionEntity get throwUnsupportedError; | |
| FunctionEntity get throwTypeError; | |
| FunctionEntity get throwAbstractClassInstantiationError; | |
| FunctionEntity get checkConcurrentModificationError; | |
| FunctionEntity get throwConcurrentModificationError; | |
| FunctionEntity get stringInterpolationHelper; | |
| FunctionEntity get wrapExceptionHelper; | |
| FunctionEntity get throwExpressionHelper; | |
| FunctionEntity get closureConverter; | |
| FunctionEntity get traceFromException; | |
| FunctionEntity get setRuntimeTypeInfo; | |
| FunctionEntity get getRuntimeTypeInfo; | |
| FunctionEntity get getTypeArgumentByIndex; | |
| FunctionEntity get computeSignature; | |
| FunctionEntity get getRuntimeTypeArguments; | |
| FunctionEntity get getRuntimeTypeArgument; | |
| FunctionEntity get getRuntimeTypeArgumentIntercepted; | |
| FunctionEntity get assertIsSubtype; | |
| FunctionEntity get checkSubtype; | |
| FunctionEntity get assertSubtype; | |
| FunctionEntity get subtypeCast; | |
| FunctionEntity get functionTypeTest; | |
| FunctionEntity get futureOrTest; | |
| FunctionEntity get checkSubtypeOfRuntimeType; | |
| FunctionEntity get assertSubtypeOfRuntimeType; | |
| FunctionEntity get subtypeOfRuntimeTypeCast; | |
| FunctionEntity get checkDeferredIsLoaded; | |
| FunctionEntity get throwNoSuchMethod; | |
| FunctionEntity get createRuntimeType; | |
| FunctionEntity get fallThroughError; | |
| FunctionEntity get createInvocationMirror; | |
| FunctionEntity get createUnmangledInvocationMirror; | |
| FunctionEntity get cyclicThrowHelper; | |
| FunctionEntity get defineProperty; | |
| bool isExtractTypeArguments(FunctionEntity member); | |
| ClassEntity getInstantiationClass(int typeArgumentCount); | |
| FunctionEntity getInstantiateFunction(int typeArgumentCount); | |
| FunctionEntity get instantiatedGenericFunctionType; | |
| FunctionEntity get extractFunctionTypeObjectFromInternal; | |
| // From dart:_internal | |
| ClassEntity get symbolImplementationClass; | |
| /// Used to annotate items that have the keyword "native". | |
| ClassEntity get externalNameClass; | |
| InterfaceType get externalNameType; | |
| ConstructorEntity get symbolValidatedConstructor; | |
| // From dart:_js_embedded_names | |
| ClassEntity get jsGetNameEnum; | |
| ClassEntity get expectNoInlineClass; | |
| ClassEntity get expectTrustTypeAnnotationsClass; | |
| ClassEntity get expectAssumeDynamicClass; | |
| /// Returns `true` if [member] is a "foreign helper", that is, a member whose | |
| /// semantics is defined synthetically and not through Dart code. | |
| /// | |
| /// Most foreign helpers are located in the `dart:_foreign_helper` library. | |
| bool isForeignHelper(MemberEntity member); | |
| ClassEntity getDefaultSuperclass( | |
| ClassEntity cls, NativeBasicData nativeBasicData); | |
| } | |
| abstract class KCommonElements implements CommonElements { | |
| // From package:js | |
| ClassEntity get jsAnnotationClass; | |
| ClassEntity get jsAnonymousClass; | |
| ClassEntity get noSideEffectsClass; | |
| ClassEntity get noThrowsClass; | |
| ClassEntity get noInlineClass; | |
| ClassEntity get forceInlineClass; | |
| bool isCreateInvocationMirrorHelper(MemberEntity member); | |
| bool isSymbolValidatedConstructor(ConstructorEntity element); | |
| ClassEntity get metaNoInlineClass; | |
| ClassEntity get metaTryInlineClass; | |
| /// Returns `true` if [function] is allowed to be external. | |
| /// | |
| /// This returns `true` for foreign helpers, from environment constructors and | |
| /// members of libraries that support native. | |
| /// | |
| /// This returns `false` for JS interop members which therefore must be | |
| /// allowed to be external through the JS interop annotation handling. | |
| bool isExternalAllowed(FunctionEntity function); | |
| } | |
| abstract class JCommonElements implements CommonElements { | |
| /// Returns `true` if [element] is the unnamed constructor of `List`. This | |
| /// will not resolve the constructor if it hasn't been seen yet during | |
| /// compilation. | |
| bool isUnnamedListConstructor(ConstructorEntity element); | |
| /// Returns `true` if [element] is the 'filled' constructor of `List`. This | |
| /// will not resolve the constructor if it hasn't been seen yet during | |
| /// compilation. | |
| bool isFilledListConstructor(ConstructorEntity element); | |
| bool isDefaultEqualityImplementation(MemberEntity element); | |
| /// Returns `true` if [selector] applies to `JSIndexable.length`. | |
| bool appliesToJsIndexableLength(Selector selector); | |
| FunctionEntity get jsArrayRemoveLast; | |
| FunctionEntity get jsArrayAdd; | |
| bool isJsStringSplit(MemberEntity member); | |
| /// Returns `true` if [selector] applies to `JSString.split` on [receiver] | |
| /// in the given [world]. | |
| /// | |
| /// Returns `false` if `JSString.split` is not available. | |
| bool appliesToJsStringSplit(Selector selector, AbstractValue receiver, | |
| AbstractValueDomain abstractValueDomain); | |
| FunctionEntity get jsStringSplit; | |
| FunctionEntity get jsStringToString; | |
| FunctionEntity get jsStringOperatorAdd; | |
| ClassEntity get jsConstClass; | |
| /// Return `true` if [member] is the 'checkInt' function defined in | |
| /// dart:_js_helpers. | |
| bool isCheckInt(MemberEntity member); | |
| /// Return `true` if [member] is the 'checkNum' function defined in | |
| /// dart:_js_helpers. | |
| bool isCheckNum(MemberEntity member); | |
| /// Return `true` if [member] is the 'checkString' function defined in | |
| /// dart:_js_helpers. | |
| bool isCheckString(MemberEntity member); | |
| bool isInstantiationClass(ClassEntity cls); | |
| // From dart:_native_typed_data | |
| ClassEntity get typedArrayOfIntClass; | |
| ClassEntity get typedArrayOfDoubleClass; | |
| ClassEntity get jsBuiltinEnum; | |
| bool isForeign(MemberEntity element); | |
| /// Returns `true` if the implementation of the 'operator ==' [function] is | |
| /// known to handle `null` as argument. | |
| bool operatorEqHandlesNullArgument(FunctionEntity function); | |
| } | |
| class CommonElementsImpl | |
| implements CommonElements, KCommonElements, JCommonElements { | |
| final ElementEnvironment _env; | |
| CommonElementsImpl(this._env); | |
| /// The `Object` class defined in 'dart:core'. | |
| ClassEntity _objectClass; | |
| ClassEntity get objectClass => | |
| _objectClass ??= _findClass(coreLibrary, 'Object'); | |
| /// The `bool` class defined in 'dart:core'. | |
| ClassEntity _boolClass; | |
| ClassEntity get boolClass => _boolClass ??= _findClass(coreLibrary, 'bool'); | |
| /// The `num` class defined in 'dart:core'. | |
| ClassEntity _numClass; | |
| ClassEntity get numClass => _numClass ??= _findClass(coreLibrary, 'num'); | |
| /// The `int` class defined in 'dart:core'. | |
| ClassEntity _intClass; | |
| ClassEntity get intClass => _intClass ??= _findClass(coreLibrary, 'int'); | |
| /// The `double` class defined in 'dart:core'. | |
| ClassEntity _doubleClass; | |
| ClassEntity get doubleClass => | |
| _doubleClass ??= _findClass(coreLibrary, 'double'); | |
| /// The `String` class defined in 'dart:core'. | |
| ClassEntity _stringClass; | |
| ClassEntity get stringClass => | |
| _stringClass ??= _findClass(coreLibrary, 'String'); | |
| /// The `Function` class defined in 'dart:core'. | |
| ClassEntity _functionClass; | |
| ClassEntity get functionClass => | |
| _functionClass ??= _findClass(coreLibrary, 'Function'); | |
| /// The `Resource` class defined in 'dart:core'. | |
| ClassEntity _resourceClass; | |
| ClassEntity get resourceClass => | |
| _resourceClass ??= _findClass(coreLibrary, 'Resource'); | |
| /// The `Symbol` class defined in 'dart:core'. | |
| ClassEntity _symbolClass; | |
| ClassEntity get symbolClass => | |
| _symbolClass ??= _findClass(coreLibrary, 'Symbol'); | |
| /// The `Null` class defined in 'dart:core'. | |
| ClassEntity _nullClass; | |
| ClassEntity get nullClass => _nullClass ??= _findClass(coreLibrary, 'Null'); | |
| /// The `Type` class defined in 'dart:core'. | |
| ClassEntity _typeClass; | |
| ClassEntity get typeClass => _typeClass ??= _findClass(coreLibrary, 'Type'); | |
| /// The `StackTrace` class defined in 'dart:core'; | |
| ClassEntity _stackTraceClass; | |
| ClassEntity get stackTraceClass => | |
| _stackTraceClass ??= _findClass(coreLibrary, 'StackTrace'); | |
| /// The `List` class defined in 'dart:core'; | |
| ClassEntity _listClass; | |
| ClassEntity get listClass => _listClass ??= _findClass(coreLibrary, 'List'); | |
| /// The `Map` class defined in 'dart:core'; | |
| ClassEntity _mapClass; | |
| ClassEntity get mapClass => _mapClass ??= _findClass(coreLibrary, 'Map'); | |
| /// The `Iterable` class defined in 'dart:core'; | |
| ClassEntity _iterableClass; | |
| ClassEntity get iterableClass => | |
| _iterableClass ??= _findClass(coreLibrary, 'Iterable'); | |
| /// The `Future` class defined in 'async';. | |
| ClassEntity _futureClass; | |
| ClassEntity get futureClass => | |
| _futureClass ??= _findClass(asyncLibrary, 'Future'); | |
| /// The `Stream` class defined in 'async'; | |
| ClassEntity _streamClass; | |
| ClassEntity get streamClass => | |
| _streamClass ??= _findClass(asyncLibrary, 'Stream'); | |
| /// The dart:core library. | |
| LibraryEntity _coreLibrary; | |
| LibraryEntity get coreLibrary => | |
| _coreLibrary ??= _env.lookupLibrary(Uris.dart_core, required: true); | |
| /// The dart:async library. | |
| LibraryEntity _asyncLibrary; | |
| LibraryEntity get asyncLibrary => | |
| _asyncLibrary ??= _env.lookupLibrary(Uris.dart_async); | |
| /// The dart:mirrors library. Null if the program doesn't access dart:mirrors. | |
| LibraryEntity _mirrorsLibrary; | |
| LibraryEntity get mirrorsLibrary => | |
| _mirrorsLibrary ??= _env.lookupLibrary(Uris.dart_mirrors); | |
| /// The dart:typed_data library. | |
| LibraryEntity _typedDataLibrary; | |
| LibraryEntity get typedDataLibrary => | |
| _typedDataLibrary ??= _env.lookupLibrary(Uris.dart__native_typed_data); | |
| LibraryEntity _jsHelperLibrary; | |
| LibraryEntity get jsHelperLibrary => | |
| _jsHelperLibrary ??= _env.lookupLibrary(Uris.dart__js_helper); | |
| LibraryEntity _interceptorsLibrary; | |
| LibraryEntity get interceptorsLibrary => | |
| _interceptorsLibrary ??= _env.lookupLibrary(Uris.dart__interceptors); | |
| LibraryEntity _foreignLibrary; | |
| LibraryEntity get foreignLibrary => | |
| _foreignLibrary ??= _env.lookupLibrary(Uris.dart__foreign_helper); | |
| /// Reference to the internal library to lookup functions to always inline. | |
| LibraryEntity _internalLibrary; | |
| LibraryEntity get internalLibrary => _internalLibrary ??= | |
| _env.lookupLibrary(Uris.dart__internal, required: true); | |
| /// The `NativeTypedData` class from dart:typed_data. | |
| ClassEntity _typedDataClass; | |
| ClassEntity get typedDataClass => | |
| _typedDataClass ??= _findClass(typedDataLibrary, 'NativeTypedData'); | |
| /// Constructor of the `Symbol` class in dart:internal. This getter will | |
| /// ensure that `Symbol` is resolved and lookup the constructor on demand. | |
| ConstructorEntity _symbolConstructorTarget; | |
| ConstructorEntity get symbolConstructorTarget { | |
| // TODO(johnniwinther): Kernel does not include redirecting factories | |
| // so this cannot be found in kernel. Find a consistent way to handle | |
| // this and similar cases. | |
| return _symbolConstructorTarget ??= | |
| _findConstructor(symbolImplementationClass, ''); | |
| } | |
| bool _computedSymbolConstructorDependencies = false; | |
| ConstructorEntity _symbolConstructorImplementationTarget; | |
| void _ensureSymbolConstructorDependencies() { | |
| if (_computedSymbolConstructorDependencies) return; | |
| _computedSymbolConstructorDependencies = true; | |
| if (_symbolConstructorTarget == null) { | |
| if (_symbolImplementationClass == null) { | |
| _symbolImplementationClass = | |
| _findClass(internalLibrary, 'Symbol', required: false); | |
| } | |
| if (_symbolImplementationClass != null) { | |
| _symbolConstructorTarget = | |
| _findConstructor(_symbolImplementationClass, '', required: false); | |
| } | |
| } | |
| if (_symbolClass == null) { | |
| _symbolClass = _findClass(coreLibrary, 'Symbol', required: false); | |
| } | |
| if (_symbolClass == null) { | |
| return; | |
| } | |
| _symbolConstructorImplementationTarget = | |
| _findConstructor(symbolClass, '', required: false); | |
| } | |
| /// Whether [element] is the same as [symbolConstructor]. Used to check | |
| /// for the constructor without computing it until it is likely to be seen. | |
| bool isSymbolConstructor(ConstructorEntity element) { | |
| assert(element != null); | |
| _ensureSymbolConstructorDependencies(); | |
| return element == _symbolConstructorImplementationTarget || | |
| element == _symbolConstructorTarget; | |
| } | |
| /// The function `identical` in dart:core. | |
| FunctionEntity _identicalFunction; | |
| FunctionEntity get identicalFunction => | |
| _identicalFunction ??= _findLibraryMember(coreLibrary, 'identical'); | |
| /// Whether [element] is the `Function.apply` method. This will not | |
| /// resolve the apply method if it hasn't been seen yet during compilation. | |
| bool isFunctionApplyMethod(MemberEntity element) => | |
| element.name == 'apply' && element.enclosingClass == functionClass; | |
| /// Returns `true` if [element] is the unnamed constructor of `List`. This | |
| /// will not resolve the constructor if it hasn't been seen yet during | |
| /// compilation. | |
| bool isUnnamedListConstructor(ConstructorEntity element) => | |
| (element.name == '' && element.enclosingClass == listClass) || | |
| (element.name == 'list' && element.enclosingClass == jsArrayClass); | |
| /// Returns `true` if [element] is the 'filled' constructor of `List`. This | |
| /// will not resolve the constructor if it hasn't been seen yet during | |
| /// compilation. | |
| bool isFilledListConstructor(ConstructorEntity element) => | |
| element.name == 'filled' && element.enclosingClass == listClass; | |
| /// The `dynamic` type. | |
| DynamicType get dynamicType => _env.dynamicType; | |
| /// The `Object` type defined in 'dart:core'. | |
| InterfaceType get objectType => _getRawType(objectClass); | |
| /// The `bool` type defined in 'dart:core'. | |
| InterfaceType get boolType => _getRawType(boolClass); | |
| /// The `num` type defined in 'dart:core'. | |
| InterfaceType get numType => _getRawType(numClass); | |
| /// The `int` type defined in 'dart:core'. | |
| InterfaceType get intType => _getRawType(intClass); | |
| /// The `double` type defined in 'dart:core'. | |
| InterfaceType get doubleType => _getRawType(doubleClass); | |
| /// The `Resource` type defined in 'dart:core'. | |
| InterfaceType get resourceType => _getRawType(resourceClass); | |
| /// The `String` type defined in 'dart:core'. | |
| InterfaceType get stringType => _getRawType(stringClass); | |
| /// The `Symbol` type defined in 'dart:core'. | |
| InterfaceType get symbolType => _getRawType(symbolClass); | |
| /// The `Function` type defined in 'dart:core'. | |
| InterfaceType get functionType => _getRawType(functionClass); | |
| /// The `Null` type defined in 'dart:core'. | |
| InterfaceType get nullType => _getRawType(nullClass); | |
| /// The `Type` type defined in 'dart:core'. | |
| InterfaceType get typeType => _getRawType(typeClass); | |
| InterfaceType get typeLiteralType => _getRawType(typeLiteralClass); | |
| /// The `StackTrace` type defined in 'dart:core'; | |
| InterfaceType get stackTraceType => _getRawType(stackTraceClass); | |
| /// Returns an instance of the `List` type defined in 'dart:core' with | |
| /// [elementType] as its type argument. | |
| /// | |
| /// If no type argument is provided, the canonical raw type is returned. | |
| InterfaceType listType([DartType elementType]) { | |
| if (elementType == null) { | |
| return _getRawType(listClass); | |
| } | |
| return _createInterfaceType(listClass, [elementType]); | |
| } | |
| /// Returns an instance of the `Map` type defined in 'dart:core' with | |
| /// [keyType] and [valueType] as its type arguments. | |
| /// | |
| /// If no type arguments are provided, the canonical raw type is returned. | |
| InterfaceType mapType([DartType keyType, DartType valueType]) { | |
| if (keyType == null && valueType == null) { | |
| return _getRawType(mapClass); | |
| } else if (keyType == null) { | |
| keyType = dynamicType; | |
| } else if (valueType == null) { | |
| valueType = dynamicType; | |
| } | |
| return _createInterfaceType(mapClass, [keyType, valueType]); | |
| } | |
| /// Returns an instance of the `Iterable` type defined in 'dart:core' with | |
| /// [elementType] as its type argument. | |
| /// | |
| /// If no type argument is provided, the canonical raw type is returned. | |
| InterfaceType iterableType([DartType elementType]) { | |
| if (elementType == null) { | |
| return _getRawType(iterableClass); | |
| } | |
| return _createInterfaceType(iterableClass, [elementType]); | |
| } | |
| /// Returns an instance of the `Future` type defined in 'dart:async' with | |
| /// [elementType] as its type argument. | |
| /// | |
| /// If no type argument is provided, the canonical raw type is returned. | |
| InterfaceType futureType([DartType elementType]) { | |
| if (elementType == null) { | |
| return _getRawType(futureClass); | |
| } | |
| return _createInterfaceType(futureClass, [elementType]); | |
| } | |
| /// Returns an instance of the `Stream` type defined in 'dart:async' with | |
| /// [elementType] as its type argument. | |
| /// | |
| /// If no type argument is provided, the canonical raw type is returned. | |
| InterfaceType streamType([DartType elementType]) { | |
| if (elementType == null) { | |
| return _getRawType(streamClass); | |
| } | |
| return _createInterfaceType(streamClass, [elementType]); | |
| } | |
| /// Returns `true` if [element] is a superclass of `String` or `num`. | |
| bool isNumberOrStringSupertype(ClassEntity element) { | |
| return element == _findClass(coreLibrary, 'Comparable', required: false); | |
| } | |
| /// Returns `true` if [element] is a superclass of `String`. | |
| bool isStringOnlySupertype(ClassEntity element) { | |
| return element == _findClass(coreLibrary, 'Pattern', required: false); | |
| } | |
| /// Returns `true` if [element] is a superclass of `List`. | |
| bool isListSupertype(ClassEntity element) => element == iterableClass; | |
| ClassEntity _findClass(LibraryEntity library, String name, | |
| {bool required: true}) { | |
| if (library == null) return null; | |
| return _env.lookupClass(library, name, required: required); | |
| } | |
| MemberEntity _findLibraryMember(LibraryEntity library, String name, | |
| {bool setter: false, bool required: true}) { | |
| if (library == null) return null; | |
| return _env.lookupLibraryMember(library, name, | |
| setter: setter, required: required); | |
| } | |
| MemberEntity _findClassMember(ClassEntity cls, String name, | |
| {bool setter: false, bool required: true}) { | |
| return _env.lookupLocalClassMember(cls, name, | |
| setter: setter, required: required); | |
| } | |
| ConstructorEntity _findConstructor(ClassEntity cls, String name, | |
| {bool required: true}) { | |
| return _env.lookupConstructor(cls, name, required: required); | |
| } | |
| /// Return the raw type of [cls]. | |
| InterfaceType _getRawType(ClassEntity cls) { | |
| return _env.getRawType(cls); | |
| } | |
| /// Create the instantiation of [cls] with the given [typeArguments]. | |
| InterfaceType _createInterfaceType( | |
| ClassEntity cls, List<DartType> typeArguments) { | |
| return _env.createInterfaceType(cls, typeArguments); | |
| } | |
| InterfaceType getConstantMapTypeFor(InterfaceType sourceType, | |
| {bool hasProtoKey: false, bool onlyStringKeys: false}) { | |
| ClassEntity classElement = onlyStringKeys | |
| ? (hasProtoKey ? constantProtoMapClass : constantStringMapClass) | |
| : generalConstantMapClass; | |
| List<DartType> typeArgument = sourceType.typeArguments; | |
| if (sourceType.treatAsRaw) { | |
| return _env.getRawType(classElement); | |
| } else { | |
| return _env.createInterfaceType(classElement, typeArgument); | |
| } | |
| } | |
| FieldEntity get symbolField => symbolImplementationField; | |
| InterfaceType get symbolImplementationType => | |
| _env.getRawType(symbolImplementationClass); | |
| bool isDefaultEqualityImplementation(MemberEntity element) { | |
| assert(element.name == '=='); | |
| ClassEntity classElement = element.enclosingClass; | |
| return classElement == objectClass || | |
| classElement == jsInterceptorClass || | |
| classElement == jsNullClass; | |
| } | |
| // From dart:core | |
| ClassEntity _mapLiteralClass; | |
| ClassEntity get mapLiteralClass { | |
| if (_mapLiteralClass == null) { | |
| _mapLiteralClass = _env.lookupClass(coreLibrary, 'LinkedHashMap'); | |
| if (_mapLiteralClass == null) { | |
| _mapLiteralClass = _findClass( | |
| _env.lookupLibrary(Uris.dart_collection), 'LinkedHashMap'); | |
| } | |
| } | |
| return _mapLiteralClass; | |
| } | |
| ConstructorEntity _mapLiteralConstructor; | |
| ConstructorEntity _mapLiteralConstructorEmpty; | |
| FunctionEntity _mapLiteralUntypedMaker; | |
| FunctionEntity _mapLiteralUntypedEmptyMaker; | |
| void _ensureMapLiteralHelpers() { | |
| if (_mapLiteralConstructor != null) return; | |
| _mapLiteralConstructor = | |
| _env.lookupConstructor(mapLiteralClass, '_literal'); | |
| _mapLiteralConstructorEmpty = | |
| _env.lookupConstructor(mapLiteralClass, '_empty'); | |
| _mapLiteralUntypedMaker = | |
| _env.lookupLocalClassMember(mapLiteralClass, '_makeLiteral'); | |
| _mapLiteralUntypedEmptyMaker = | |
| _env.lookupLocalClassMember(mapLiteralClass, '_makeEmpty'); | |
| } | |
| ConstructorEntity get mapLiteralConstructor { | |
| _ensureMapLiteralHelpers(); | |
| return _mapLiteralConstructor; | |
| } | |
| ConstructorEntity get mapLiteralConstructorEmpty { | |
| _ensureMapLiteralHelpers(); | |
| return _mapLiteralConstructorEmpty; | |
| } | |
| FunctionEntity get mapLiteralUntypedMaker { | |
| _ensureMapLiteralHelpers(); | |
| return _mapLiteralUntypedMaker; | |
| } | |
| FunctionEntity get mapLiteralUntypedEmptyMaker { | |
| _ensureMapLiteralHelpers(); | |
| return _mapLiteralUntypedEmptyMaker; | |
| } | |
| FunctionEntity _objectNoSuchMethod; | |
| FunctionEntity get objectNoSuchMethod { | |
| return _objectNoSuchMethod ??= | |
| _env.lookupLocalClassMember(objectClass, Identifiers.noSuchMethod_); | |
| } | |
| bool isDefaultNoSuchMethodImplementation(FunctionEntity element) { | |
| ClassEntity classElement = element.enclosingClass; | |
| return classElement == objectClass || | |
| classElement == jsInterceptorClass || | |
| classElement == jsNullClass; | |
| } | |
| // From dart:async | |
| ClassEntity _findAsyncHelperClass(String name) => | |
| _findClass(asyncLibrary, name); | |
| FunctionEntity _findAsyncHelperFunction(String name) => | |
| _findLibraryMember(asyncLibrary, name); | |
| FunctionEntity get asyncHelperStart => | |
| _findAsyncHelperFunction("_asyncStart"); | |
| FunctionEntity get asyncHelperStartSync => | |
| _findAsyncHelperFunction("_asyncStartSync"); | |
| FunctionEntity get asyncHelperAwait => | |
| _findAsyncHelperFunction("_asyncAwait"); | |
| FunctionEntity get asyncHelperReturn => | |
| _findAsyncHelperFunction("_asyncReturn"); | |
| FunctionEntity get asyncHelperRethrow => | |
| _findAsyncHelperFunction("_asyncRethrow"); | |
| FunctionEntity get wrapBody => | |
| _findAsyncHelperFunction("_wrapJsFunctionForAsync"); | |
| FunctionEntity get yieldStar => _env.lookupLocalClassMember( | |
| _findAsyncHelperClass("_IterationMarker"), "yieldStar"); | |
| FunctionEntity get yieldSingle => _env.lookupLocalClassMember( | |
| _findAsyncHelperClass("_IterationMarker"), "yieldSingle"); | |
| FunctionEntity get syncStarUncaughtError => _env.lookupLocalClassMember( | |
| _findAsyncHelperClass("_IterationMarker"), "uncaughtError"); | |
| FunctionEntity get asyncStarHelper => | |
| _findAsyncHelperFunction("_asyncStarHelper"); | |
| FunctionEntity get streamOfController => | |
| _findAsyncHelperFunction("_streamOfController"); | |
| FunctionEntity get endOfIteration => _env.lookupLocalClassMember( | |
| _findAsyncHelperClass("_IterationMarker"), "endOfIteration"); | |
| ClassEntity get syncStarIterable => | |
| _findAsyncHelperClass("_SyncStarIterable"); | |
| ClassEntity get futureImplementation => _findAsyncHelperClass('_Future'); | |
| ClassEntity get controllerStream => | |
| _findAsyncHelperClass("_ControllerStream"); | |
| ClassEntity get streamIterator => _findAsyncHelperClass("StreamIterator"); | |
| ConstructorEntity get streamIteratorConstructor => | |
| _env.lookupConstructor(streamIterator, ""); | |
| FunctionEntity _syncStarIterableFactory; | |
| FunctionEntity get syncStarIterableFactory => _syncStarIterableFactory ??= | |
| _findAsyncHelperFunction('_makeSyncStarIterable'); | |
| FunctionEntity _asyncAwaitCompleterFactory; | |
| FunctionEntity get asyncAwaitCompleterFactory => | |
| _asyncAwaitCompleterFactory ??= | |
| _findAsyncHelperFunction('_makeAsyncAwaitCompleter'); | |
| FunctionEntity _syncCompleterFactory; | |
| FunctionEntity get syncCompleterFactory => | |
| _syncCompleterFactory ??= _findAsyncHelperFunction('_makeSyncCompleter'); | |
| FunctionEntity _asyncStarStreamControllerFactory; | |
| FunctionEntity get asyncStarStreamControllerFactory => | |
| _asyncStarStreamControllerFactory ??= | |
| _findAsyncHelperFunction('_makeAsyncStarStreamController'); | |
| // From dart:_interceptors | |
| ClassEntity _findInterceptorsClass(String name) => | |
| _findClass(interceptorsLibrary, name); | |
| FunctionEntity _findInterceptorsFunction(String name) => | |
| _findLibraryMember(interceptorsLibrary, name); | |
| ClassEntity _jsInterceptorClass; | |
| ClassEntity get jsInterceptorClass => | |
| _jsInterceptorClass ??= _findInterceptorsClass('Interceptor'); | |
| ClassEntity _jsStringClass; | |
| ClassEntity get jsStringClass => | |
| _jsStringClass ??= _findInterceptorsClass('JSString'); | |
| ClassEntity _jsArrayClass; | |
| ClassEntity get jsArrayClass => | |
| _jsArrayClass ??= _findInterceptorsClass('JSArray'); | |
| ClassEntity _jsNumberClass; | |
| ClassEntity get jsNumberClass => | |
| _jsNumberClass ??= _findInterceptorsClass('JSNumber'); | |
| ClassEntity _jsIntClass; | |
| ClassEntity get jsIntClass => _jsIntClass ??= _findInterceptorsClass('JSInt'); | |
| ClassEntity _jsDoubleClass; | |
| ClassEntity get jsDoubleClass => | |
| _jsDoubleClass ??= _findInterceptorsClass('JSDouble'); | |
| ClassEntity _jsNullClass; | |
| ClassEntity get jsNullClass => | |
| _jsNullClass ??= _findInterceptorsClass('JSNull'); | |
| ClassEntity _jsBoolClass; | |
| ClassEntity get jsBoolClass => | |
| _jsBoolClass ??= _findInterceptorsClass('JSBool'); | |
| ClassEntity _jsPlainJavaScriptObjectClass; | |
| ClassEntity get jsPlainJavaScriptObjectClass => | |
| _jsPlainJavaScriptObjectClass ??= | |
| _findInterceptorsClass('PlainJavaScriptObject'); | |
| ClassEntity _jsUnknownJavaScriptObjectClass; | |
| ClassEntity get jsUnknownJavaScriptObjectClass => | |
| _jsUnknownJavaScriptObjectClass ??= | |
| _findInterceptorsClass('UnknownJavaScriptObject'); | |
| ClassEntity _jsJavaScriptFunctionClass; | |
| ClassEntity get jsJavaScriptFunctionClass => _jsJavaScriptFunctionClass ??= | |
| _findInterceptorsClass('JavaScriptFunction'); | |
| ClassEntity _jsJavaScriptObjectClass; | |
| ClassEntity get jsJavaScriptObjectClass => | |
| _jsJavaScriptObjectClass ??= _findInterceptorsClass('JavaScriptObject'); | |
| ClassEntity _jsIndexableClass; | |
| ClassEntity get jsIndexableClass => | |
| _jsIndexableClass ??= _findInterceptorsClass('JSIndexable'); | |
| ClassEntity _jsMutableIndexableClass; | |
| ClassEntity get jsMutableIndexableClass => | |
| _jsMutableIndexableClass ??= _findInterceptorsClass('JSMutableIndexable'); | |
| ClassEntity _jsMutableArrayClass; | |
| ClassEntity get jsMutableArrayClass => | |
| _jsMutableArrayClass ??= _findInterceptorsClass('JSMutableArray'); | |
| ClassEntity _jsFixedArrayClass; | |
| ClassEntity get jsFixedArrayClass => | |
| _jsFixedArrayClass ??= _findInterceptorsClass('JSFixedArray'); | |
| ClassEntity _jsExtendableArrayClass; | |
| ClassEntity get jsExtendableArrayClass => | |
| _jsExtendableArrayClass ??= _findInterceptorsClass('JSExtendableArray'); | |
| ClassEntity _jsUnmodifiableArrayClass; | |
| ClassEntity get jsUnmodifiableArrayClass => _jsUnmodifiableArrayClass ??= | |
| _findInterceptorsClass('JSUnmodifiableArray'); | |
| ClassEntity _jsPositiveIntClass; | |
| ClassEntity get jsPositiveIntClass => | |
| _jsPositiveIntClass ??= _findInterceptorsClass('JSPositiveInt'); | |
| ClassEntity _jsUInt32Class; | |
| ClassEntity get jsUInt32Class => | |
| _jsUInt32Class ??= _findInterceptorsClass('JSUInt32'); | |
| ClassEntity _jsUInt31Class; | |
| ClassEntity get jsUInt31Class => | |
| _jsUInt31Class ??= _findInterceptorsClass('JSUInt31'); | |
| /// Returns `true` member is the 'findIndexForNativeSubclassType' method | |
| /// declared in `dart:_interceptors`. | |
| bool isFindIndexForNativeSubclassType(MemberEntity member) { | |
| return member.name == 'findIndexForNativeSubclassType' && | |
| member.isTopLevel && | |
| member.library == interceptorsLibrary; | |
| } | |
| FunctionEntity _getNativeInterceptorMethod; | |
| FunctionEntity get getNativeInterceptorMethod => | |
| _getNativeInterceptorMethod ??= | |
| _findInterceptorsFunction('getNativeInterceptor'); | |
| /// Returns `true` if [selector] applies to `JSIndexable.length`. | |
| bool appliesToJsIndexableLength(Selector selector) { | |
| return selector.name == 'length' && (selector.isGetter || selector.isCall); | |
| } | |
| ConstructorEntity _jsArrayTypedConstructor; | |
| ConstructorEntity get jsArrayTypedConstructor => | |
| _jsArrayTypedConstructor ??= _findConstructor(jsArrayClass, 'typed'); | |
| FunctionEntity _jsArrayRemoveLast; | |
| FunctionEntity get jsArrayRemoveLast => | |
| _jsArrayRemoveLast ??= _findClassMember(jsArrayClass, 'removeLast'); | |
| FunctionEntity _jsArrayAdd; | |
| FunctionEntity get jsArrayAdd => | |
| _jsArrayAdd ??= _findClassMember(jsArrayClass, 'add'); | |
| bool _isJsStringClass(ClassEntity cls) { | |
| return cls.name == 'JSString' && cls.library == interceptorsLibrary; | |
| } | |
| bool isJsStringSplit(MemberEntity member) { | |
| return member.name == 'split' && | |
| member.isInstanceMember && | |
| _isJsStringClass(member.enclosingClass); | |
| } | |
| /// Returns `true` if [selector] applies to `JSString.split` on [receiver] | |
| /// in the given [world]. | |
| /// | |
| /// Returns `false` if `JSString.split` is not available. | |
| bool appliesToJsStringSplit(Selector selector, AbstractValue receiver, | |
| AbstractValueDomain abstractValueDomain) { | |
| if (_jsStringSplit == null) { | |
| ClassEntity cls = | |
| _findClass(interceptorsLibrary, 'JSString', required: false); | |
| if (cls == null) return false; | |
| _jsStringSplit = _findClassMember(cls, 'split', required: false); | |
| if (_jsStringSplit == null) return false; | |
| } | |
| return selector.applies(_jsStringSplit) && | |
| (receiver == null || | |
| abstractValueDomain.canHit(receiver, jsStringSplit, selector)); | |
| } | |
| FunctionEntity _jsStringSplit; | |
| FunctionEntity get jsStringSplit => | |
| _jsStringSplit ??= _findClassMember(jsStringClass, 'split'); | |
| FunctionEntity _jsStringToString; | |
| FunctionEntity get jsStringToString => | |
| _jsStringToString ??= _findClassMember(jsStringClass, 'toString'); | |
| FunctionEntity _jsStringOperatorAdd; | |
| FunctionEntity get jsStringOperatorAdd => | |
| _jsStringOperatorAdd ??= _findClassMember(jsStringClass, '+'); | |
| ClassEntity _jsConstClass; | |
| ClassEntity get jsConstClass => | |
| _jsConstClass ??= _findClass(foreignLibrary, 'JS_CONST'); | |
| // From package:js | |
| ClassEntity _jsAnnotationClass; | |
| ClassEntity get jsAnnotationClass { | |
| if (_jsAnnotationClass == null) { | |
| LibraryEntity library = _env.lookupLibrary(Uris.package_js); | |
| if (library == null) return null; | |
| _jsAnnotationClass = _findClass(library, 'JS'); | |
| } | |
| return _jsAnnotationClass; | |
| } | |
| ClassEntity _jsAnonymousClass; | |
| ClassEntity get jsAnonymousClass { | |
| if (_jsAnonymousClass == null) { | |
| LibraryEntity library = _env.lookupLibrary(Uris.package_js); | |
| if (library == null) return null; | |
| _jsAnonymousClass = _findClass(library, '_Anonymous'); | |
| } | |
| return _jsAnonymousClass; | |
| } | |
| // From dart:_js_helper | |
| // TODO(johnniwinther): Avoid the need for this (from [CheckedModeHelper]). | |
| FunctionEntity findHelperFunction(String name) => _findHelperFunction(name); | |
| FunctionEntity _findHelperFunction(String name) => | |
| _findLibraryMember(jsHelperLibrary, name); | |
| ClassEntity _findHelperClass(String name) => | |
| _findClass(jsHelperLibrary, name); | |
| ClassEntity _closureClass; | |
| ClassEntity get closureClass => _closureClass ??= _findHelperClass('Closure'); | |
| ClassEntity _boundClosureClass; | |
| ClassEntity get boundClosureClass => | |
| _boundClosureClass ??= _findHelperClass('BoundClosure'); | |
| ClassEntity _typeLiteralClass; | |
| ClassEntity get typeLiteralClass => | |
| _typeLiteralClass ??= _findHelperClass('TypeImpl'); | |
| ClassEntity _constMapLiteralClass; | |
| ClassEntity get constMapLiteralClass => | |
| _constMapLiteralClass ??= _findHelperClass('ConstantMap'); | |
| ClassEntity _typeVariableClass; | |
| ClassEntity get typeVariableClass => | |
| _typeVariableClass ??= _findHelperClass('TypeVariable'); | |
| ClassEntity _noSideEffectsClass; | |
| ClassEntity get noSideEffectsClass => | |
| _noSideEffectsClass ??= _findHelperClass('NoSideEffects'); | |
| ClassEntity _noThrowsClass; | |
| ClassEntity get noThrowsClass => | |
| _noThrowsClass ??= _findHelperClass('NoThrows'); | |
| ClassEntity _noInlineClass; | |
| ClassEntity get noInlineClass => | |
| _noInlineClass ??= _findHelperClass('NoInline'); | |
| ClassEntity _forceInlineClass; | |
| ClassEntity get forceInlineClass => | |
| _forceInlineClass ??= _findHelperClass('ForceInline'); | |
| ClassEntity _jsInvocationMirrorClass; | |
| ClassEntity get jsInvocationMirrorClass => | |
| _jsInvocationMirrorClass ??= _findHelperClass('JSInvocationMirror'); | |
| MemberEntity _invocationTypeArgumentGetter; | |
| MemberEntity get invocationTypeArgumentGetter => | |
| _invocationTypeArgumentGetter ??= | |
| _findClassMember(jsInvocationMirrorClass, 'typeArguments'); | |
| /// Interface used to determine if an object has the JavaScript | |
| /// indexing behavior. The interface is only visible to specific libraries. | |
| ClassEntity _jsIndexingBehaviorInterface; | |
| ClassEntity get jsIndexingBehaviorInterface => | |
| _jsIndexingBehaviorInterface ??= | |
| _findHelperClass('JavaScriptIndexingBehavior'); | |
| ClassEntity get stackTraceHelperClass => _findHelperClass('_StackTrace'); | |
| ClassEntity get constantMapClass => | |
| _findHelperClass(JavaScriptMapConstant.DART_CLASS); | |
| ClassEntity get constantStringMapClass => | |
| _findHelperClass(JavaScriptMapConstant.DART_STRING_CLASS); | |
| ClassEntity get constantProtoMapClass => | |
| _findHelperClass(JavaScriptMapConstant.DART_PROTO_CLASS); | |
| ClassEntity get generalConstantMapClass => | |
| _findHelperClass(JavaScriptMapConstant.DART_GENERAL_CLASS); | |
| ClassEntity get annotationCreatesClass => _findHelperClass('Creates'); | |
| ClassEntity get annotationReturnsClass => _findHelperClass('Returns'); | |
| ClassEntity get annotationJSNameClass => _findHelperClass('JSName'); | |
| /// The class for native annotations defined in dart:_js_helper. | |
| ClassEntity _nativeAnnotationClass; | |
| ClassEntity get nativeAnnotationClass => | |
| _nativeAnnotationClass ??= _findHelperClass('Native'); | |
| ConstructorEntity _typeVariableConstructor; | |
| ConstructorEntity get typeVariableConstructor => _typeVariableConstructor ??= | |
| _env.lookupConstructor(typeVariableClass, ''); | |
| FunctionEntity _assertTest; | |
| FunctionEntity get assertTest => | |
| _assertTest ??= _findHelperFunction('assertTest'); | |
| FunctionEntity _assertThrow; | |
| FunctionEntity get assertThrow => | |
| _assertThrow ??= _findHelperFunction('assertThrow'); | |
| FunctionEntity _assertHelper; | |
| FunctionEntity get assertHelper => | |
| _assertHelper ??= _findHelperFunction('assertHelper'); | |
| FunctionEntity _assertUnreachableMethod; | |
| FunctionEntity get assertUnreachableMethod => | |
| _assertUnreachableMethod ??= _findHelperFunction('assertUnreachable'); | |
| /// Holds the method "getIsolateAffinityTag" when dart:_js_helper has been | |
| /// loaded. | |
| FunctionEntity _getIsolateAffinityTagMarker; | |
| FunctionEntity get getIsolateAffinityTagMarker => | |
| _getIsolateAffinityTagMarker ??= | |
| _findHelperFunction('getIsolateAffinityTag'); | |
| /// Holds the method "requiresPreamble" in _js_helper. | |
| FunctionEntity _requiresPreambleMarker; | |
| FunctionEntity get requiresPreambleMarker => | |
| _requiresPreambleMarker ??= _findHelperFunction('requiresPreamble'); | |
| FunctionEntity get loadLibraryWrapper => | |
| _findHelperFunction("_loadLibraryWrapper"); | |
| FunctionEntity get loadDeferredLibrary => | |
| _findHelperFunction("loadDeferredLibrary"); | |
| FunctionEntity get boolConversionCheck => | |
| _findHelperFunction('boolConversionCheck'); | |
| FunctionEntity get _consoleTraceHelper => | |
| _findHelperFunction('consoleTraceHelper'); | |
| FunctionEntity get _postTraceHelper => _findHelperFunction('postTraceHelper'); | |
| FunctionEntity _traceHelper; | |
| FunctionEntity get traceHelper { | |
| return _traceHelper ??= JavaScriptBackend.TRACE_METHOD == 'console' | |
| ? _consoleTraceHelper | |
| : _postTraceHelper; | |
| } | |
| FunctionEntity get closureFromTearOff => | |
| _findHelperFunction('closureFromTearOff'); | |
| FunctionEntity get isJsIndexable => _findHelperFunction('isJsIndexable'); | |
| FunctionEntity get throwIllegalArgumentException => | |
| _findHelperFunction('iae'); | |
| FunctionEntity get throwIndexOutOfRangeException => | |
| _findHelperFunction('ioore'); | |
| FunctionEntity get exceptionUnwrapper => | |
| _findHelperFunction('unwrapException'); | |
| FunctionEntity get throwRuntimeError => | |
| _findHelperFunction('throwRuntimeError'); | |
| FunctionEntity get throwUnsupportedError => | |
| _findHelperFunction('throwUnsupportedError'); | |
| FunctionEntity get throwTypeError => _findHelperFunction('throwTypeError'); | |
| FunctionEntity get throwAbstractClassInstantiationError => | |
| _findHelperFunction('throwAbstractClassInstantiationError'); | |
| FunctionEntity _cachedCheckConcurrentModificationError; | |
| FunctionEntity get checkConcurrentModificationError => | |
| _cachedCheckConcurrentModificationError ??= | |
| _findHelperFunction('checkConcurrentModificationError'); | |
| FunctionEntity get throwConcurrentModificationError => | |
| _findHelperFunction('throwConcurrentModificationError'); | |
| /// Return `true` if [member] is the 'checkInt' function defined in | |
| /// dart:_js_helpers. | |
| bool isCheckInt(MemberEntity member) { | |
| return member.isFunction && | |
| member.isTopLevel && | |
| member.library == jsHelperLibrary && | |
| member.name == 'checkInt'; | |
| } | |
| /// Return `true` if [member] is the 'checkNum' function defined in | |
| /// dart:_js_helpers. | |
| bool isCheckNum(MemberEntity member) { | |
| return member.isFunction && | |
| member.isTopLevel && | |
| member.library == jsHelperLibrary && | |
| member.name == 'checkNum'; | |
| } | |
| /// Return `true` if [member] is the 'checkString' function defined in | |
| /// dart:_js_helpers. | |
| bool isCheckString(MemberEntity member) { | |
| return member.isFunction && | |
| member.isTopLevel && | |
| member.library == jsHelperLibrary && | |
| member.name == 'checkString'; | |
| } | |
| FunctionEntity get stringInterpolationHelper => _findHelperFunction('S'); | |
| FunctionEntity get wrapExceptionHelper => | |
| _findHelperFunction('wrapException'); | |
| FunctionEntity get throwExpressionHelper => | |
| _findHelperFunction('throwExpression'); | |
| FunctionEntity get closureConverter => | |
| _findHelperFunction('convertDartClosureToJS'); | |
| FunctionEntity get traceFromException => | |
| _findHelperFunction('getTraceFromException'); | |
| FunctionEntity get setRuntimeTypeInfo => | |
| _findHelperFunction('setRuntimeTypeInfo'); | |
| FunctionEntity get getRuntimeTypeInfo => | |
| _findHelperFunction('getRuntimeTypeInfo'); | |
| FunctionEntity get getTypeArgumentByIndex => | |
| _findHelperFunction('getTypeArgumentByIndex'); | |
| FunctionEntity get computeSignature => | |
| _findHelperFunction('computeSignature'); | |
| FunctionEntity get getRuntimeTypeArguments => | |
| _findHelperFunction('getRuntimeTypeArguments'); | |
| FunctionEntity get getRuntimeTypeArgument => | |
| _findHelperFunction('getRuntimeTypeArgument'); | |
| FunctionEntity get getRuntimeTypeArgumentIntercepted => | |
| _findHelperFunction('getRuntimeTypeArgumentIntercepted'); | |
| FunctionEntity get assertIsSubtype => _findHelperFunction('assertIsSubtype'); | |
| FunctionEntity get checkSubtype => _findHelperFunction('checkSubtype'); | |
| FunctionEntity get assertSubtype => _findHelperFunction('assertSubtype'); | |
| FunctionEntity get subtypeCast => _findHelperFunction('subtypeCast'); | |
| FunctionEntity get functionTypeTest => | |
| _findHelperFunction('functionTypeTest'); | |
| FunctionEntity get futureOrTest => _findHelperFunction('futureOrTest'); | |
| FunctionEntity get checkSubtypeOfRuntimeType => | |
| _findHelperFunction('checkSubtypeOfRuntimeType'); | |
| FunctionEntity get assertSubtypeOfRuntimeType => | |
| _findHelperFunction('assertSubtypeOfRuntimeType'); | |
| FunctionEntity get subtypeOfRuntimeTypeCast => | |
| _findHelperFunction('subtypeOfRuntimeTypeCast'); | |
| FunctionEntity get checkDeferredIsLoaded => | |
| _findHelperFunction('checkDeferredIsLoaded'); | |
| FunctionEntity get throwNoSuchMethod => | |
| _findHelperFunction('throwNoSuchMethod'); | |
| FunctionEntity get createRuntimeType => | |
| _findHelperFunction('createRuntimeType'); | |
| FunctionEntity get fallThroughError => | |
| _findHelperFunction("getFallThroughError"); | |
| FunctionEntity get createInvocationMirror => | |
| _findHelperFunction('createInvocationMirror'); | |
| bool isCreateInvocationMirrorHelper(MemberEntity member) { | |
| return member.isTopLevel && | |
| member.name == '_createInvocationMirror' && | |
| member.library == coreLibrary; | |
| } | |
| FunctionEntity get createUnmangledInvocationMirror => | |
| _findHelperFunction('createUnmangledInvocationMirror'); | |
| FunctionEntity get cyclicThrowHelper => | |
| _findHelperFunction("throwCyclicInit"); | |
| FunctionEntity get defineProperty => _findHelperFunction('defineProperty'); | |
| bool isExtractTypeArguments(FunctionEntity member) { | |
| return member.name == 'extractTypeArguments' && | |
| member.library == internalLibrary; | |
| } | |
| // TODO(johnniwinther,sra): Support arbitrary type argument count. | |
| void _checkTypeArgumentCount(int typeArgumentCount) { | |
| assert(typeArgumentCount > 0); | |
| if (typeArgumentCount > 20) { | |
| failedAt( | |
| NO_LOCATION_SPANNABLE, | |
| "Unsupported instantiation argument count: " | |
| "${typeArgumentCount}"); | |
| } | |
| } | |
| ClassEntity getInstantiationClass(int typeArgumentCount) { | |
| _checkTypeArgumentCount(typeArgumentCount); | |
| return _findHelperClass('Instantiation$typeArgumentCount'); | |
| } | |
| FunctionEntity getInstantiateFunction(int typeArgumentCount) { | |
| _checkTypeArgumentCount(typeArgumentCount); | |
| return _findHelperFunction('instantiate$typeArgumentCount'); | |
| } | |
| FunctionEntity get instantiatedGenericFunctionType => | |
| _findHelperFunction('instantiatedGenericFunctionType'); | |
| FunctionEntity get extractFunctionTypeObjectFromInternal => | |
| _findHelperFunction('extractFunctionTypeObjectFromInternal'); | |
| bool isInstantiationClass(ClassEntity cls) { | |
| return cls.library == _jsHelperLibrary && | |
| cls.name != 'Instantiation' && | |
| cls.name.startsWith('Instantiation'); | |
| } | |
| // From dart:_internal | |
| ClassEntity _symbolImplementationClass; | |
| ClassEntity get symbolImplementationClass => | |
| _symbolImplementationClass ??= _findClass(internalLibrary, 'Symbol'); | |
| /// Used to annotate items that have the keyword "native". | |
| ClassEntity _externalNameClass; | |
| ClassEntity get externalNameClass => | |
| _externalNameClass ??= _findClass(internalLibrary, 'ExternalName'); | |
| InterfaceType get externalNameType => _getRawType(externalNameClass); | |
| ConstructorEntity get symbolValidatedConstructor => | |
| _symbolValidatedConstructor ??= | |
| _findConstructor(symbolImplementationClass, 'validated'); | |
| /// Returns the field that holds the internal name in the implementation class | |
| /// for `Symbol`. | |
| FieldEntity _symbolImplementationField; | |
| FieldEntity get symbolImplementationField => _symbolImplementationField ??= | |
| _env.lookupLocalClassMember(symbolImplementationClass, '_name', | |
| required: true); | |
| ConstructorEntity _symbolValidatedConstructor; | |
| bool isSymbolValidatedConstructor(ConstructorEntity element) { | |
| if (_symbolValidatedConstructor != null) { | |
| return element == _symbolValidatedConstructor; | |
| } | |
| return false; | |
| } | |
| // From dart:_native_typed_data | |
| ClassEntity _typedArrayOfIntClass; | |
| ClassEntity get typedArrayOfIntClass => _typedArrayOfIntClass ??= _findClass( | |
| _env.lookupLibrary(Uris.dart__native_typed_data, required: true), | |
| 'NativeTypedArrayOfInt'); | |
| ClassEntity _typedArrayOfDoubleClass; | |
| ClassEntity get typedArrayOfDoubleClass => | |
| _typedArrayOfDoubleClass ??= _findClass( | |
| _env.lookupLibrary(Uris.dart__native_typed_data, required: true), | |
| 'NativeTypedArrayOfDouble'); | |
| // From dart:_js_embedded_names | |
| /// Holds the class for the [JsGetName] enum. | |
| ClassEntity _jsGetNameEnum; | |
| ClassEntity get jsGetNameEnum => _jsGetNameEnum ??= _findClass( | |
| _env.lookupLibrary(Uris.dart__js_embedded_names, required: true), | |
| 'JsGetName'); | |
| /// Holds the class for the [JsBuiltins] enum. | |
| ClassEntity _jsBuiltinEnum; | |
| ClassEntity get jsBuiltinEnum => _jsBuiltinEnum ??= _findClass( | |
| _env.lookupLibrary(Uris.dart__js_embedded_names, required: true), | |
| 'JsBuiltin'); | |
| static final Uri PACKAGE_EXPECT = | |
| new Uri(scheme: 'package', path: 'expect/expect.dart'); | |
| bool _expectAnnotationChecked = false; | |
| ClassEntity _expectNoInlineClass; | |
| ClassEntity _expectTrustTypeAnnotationsClass; | |
| ClassEntity _expectAssumeDynamicClass; | |
| void _ensureExpectAnnotations() { | |
| if (!_expectAnnotationChecked) { | |
| _expectAnnotationChecked = true; | |
| LibraryEntity library = _env.lookupLibrary(PACKAGE_EXPECT); | |
| if (library != null) { | |
| _expectNoInlineClass = _env.lookupClass(library, 'NoInline'); | |
| _expectTrustTypeAnnotationsClass = | |
| _env.lookupClass(library, 'TrustTypeAnnotations'); | |
| _expectAssumeDynamicClass = _env.lookupClass(library, 'AssumeDynamic'); | |
| if (_expectNoInlineClass == null || | |
| _expectTrustTypeAnnotationsClass == null || | |
| _expectAssumeDynamicClass == null) { | |
| // This is not the package you're looking for. | |
| _expectNoInlineClass = null; | |
| _expectTrustTypeAnnotationsClass = null; | |
| _expectAssumeDynamicClass = null; | |
| } | |
| } | |
| } | |
| } | |
| ClassEntity get expectNoInlineClass { | |
| _ensureExpectAnnotations(); | |
| return _expectNoInlineClass; | |
| } | |
| ClassEntity get expectTrustTypeAnnotationsClass { | |
| _ensureExpectAnnotations(); | |
| return _expectTrustTypeAnnotationsClass; | |
| } | |
| ClassEntity get expectAssumeDynamicClass { | |
| _ensureExpectAnnotations(); | |
| return _expectAssumeDynamicClass; | |
| } | |
| static final Uri PACKAGE_META_DART2JS = | |
| new Uri(scheme: 'package', path: 'meta/dart2js.dart'); | |
| bool _metaAnnotationChecked = false; | |
| ClassEntity _metaNoInlineClass; | |
| ClassEntity _metaTryInlineClass; | |
| void _ensureMetaAnnotations() { | |
| if (!_metaAnnotationChecked) { | |
| _metaAnnotationChecked = true; | |
| LibraryEntity library = _env.lookupLibrary(PACKAGE_META_DART2JS); | |
| if (library != null) { | |
| _metaNoInlineClass = _env.lookupClass(library, '_NoInline'); | |
| _metaTryInlineClass = _env.lookupClass(library, '_TryInline'); | |
| if (_metaNoInlineClass == null || _metaTryInlineClass == null) { | |
| // This is not the package you're looking for. | |
| _metaNoInlineClass = null; | |
| _metaTryInlineClass = null; | |
| } | |
| } | |
| } | |
| } | |
| ClassEntity get metaNoInlineClass { | |
| _ensureMetaAnnotations(); | |
| return _metaNoInlineClass; | |
| } | |
| ClassEntity get metaTryInlineClass { | |
| _ensureMetaAnnotations(); | |
| return _metaTryInlineClass; | |
| } | |
| bool isForeign(MemberEntity element) => element.library == foreignLibrary; | |
| /// Returns `true` if [member] is a "foreign helper", that is, a member whose | |
| /// semantics is defined synthetically and not through Dart code. | |
| /// | |
| /// Most foreign helpers are located in the `dart:_foreign_helper` library. | |
| bool isForeignHelper(MemberEntity member) { | |
| return member.library == foreignLibrary || | |
| isCreateInvocationMirrorHelper(member); | |
| } | |
| /// Returns `true` if [function] is allowed to be external. | |
| /// | |
| /// This returns `true` for foreign helpers, from environment constructors and | |
| /// members of libraries that support native. | |
| /// | |
| /// This returns `false` for JS interop members which therefore must be | |
| /// allowed to be external through the JS interop annotation handling. | |
| bool isExternalAllowed(FunctionEntity function) { | |
| return isForeignHelper(function) || | |
| (function is ConstructorEntity && | |
| function.isFromEnvironmentConstructor) || | |
| maybeEnableNative(function.library.canonicalUri) || | |
| // TODO(johnniwinther): Remove this when importing dart:mirrors is | |
| // a compile-time error. | |
| function.library.canonicalUri == Uris.dart_mirrors; | |
| } | |
| /// Returns `true` if the implementation of the 'operator ==' [function] is | |
| /// known to handle `null` as argument. | |
| bool operatorEqHandlesNullArgument(FunctionEntity function) { | |
| assert(function.name == '==', | |
| failedAt(function, "Unexpected function $function.")); | |
| ClassEntity cls = function.enclosingClass; | |
| return cls == objectClass || | |
| cls == jsInterceptorClass || | |
| cls == jsNullClass; | |
| } | |
| ClassEntity getDefaultSuperclass( | |
| ClassEntity cls, NativeBasicData nativeBasicData) { | |
| if (nativeBasicData.isJsInteropClass(cls)) { | |
| return jsJavaScriptObjectClass; | |
| } | |
| // Native classes inherit from Interceptor. | |
| return nativeBasicData.isNativeClass(cls) | |
| ? jsInterceptorClass | |
| : objectClass; | |
| } | |
| } | |
| /// Interface for accessing libraries, classes and members. | |
| /// | |
| /// The element environment makes private and injected members directly | |
| /// available and should therefore not be used to determine scopes. | |
| /// | |
| /// The properties exposed are Dart-centric and should therefore, long-term, not | |
| /// be used during codegen, expect for mirrors. | |
| // TODO(johnniwinther): Split this into an element environment and a type query | |
| // interface, the first should only be used during resolution and the latter in | |
| // both resolution and codegen. | |
| abstract class ElementEnvironment { | |
| /// Returns the main library for the compilation. | |
| LibraryEntity get mainLibrary; | |
| /// Returns the main method for the compilation. | |
| FunctionEntity get mainFunction; | |
| /// Returns all known libraries. | |
| Iterable<LibraryEntity> get libraries; | |
| /// Returns the library name of [library] or '' if the library is unnamed. | |
| String getLibraryName(LibraryEntity library); | |
| /// Lookup the library with the canonical [uri], fail if the library is | |
| /// missing and [required]; | |
| LibraryEntity lookupLibrary(Uri uri, {bool required: false}); | |
| /// Calls [f] for every class declared in [library]. | |
| void forEachClass(LibraryEntity library, void f(ClassEntity cls)); | |
| /// Lookup the class [name] in [library], fail if the class is missing and | |
| /// [required]. | |
| ClassEntity lookupClass(LibraryEntity library, String name, | |
| {bool required: false}); | |
| /// Calls [f] for every top level member in [library]. | |
| void forEachLibraryMember(LibraryEntity library, void f(MemberEntity member)); | |
| /// Lookup the member [name] in [library], fail if the class is missing and | |
| /// [required]. | |
| MemberEntity lookupLibraryMember(LibraryEntity library, String name, | |
| {bool setter: false, bool required: false}); | |
| /// Lookup the member [name] in [cls], fail if the class is missing and | |
| /// [required]. | |
| MemberEntity lookupLocalClassMember(ClassEntity cls, String name, | |
| {bool setter: false, bool required: false}); | |
| /// Lookup the member [name] in [cls] and its superclasses. | |
| /// | |
| /// Return `null` if the member is not found in the class or any superclass. | |
| MemberEntity lookupClassMember(ClassEntity cls, String name, | |
| {bool setter: false}) { | |
| var entity = lookupLocalClassMember(cls, name, setter: setter); | |
| if (entity != null) return entity; | |
| var superclass = getSuperClass(cls); | |
| if (superclass == null) return null; | |
| return lookupClassMember(superclass, name, setter: setter); | |
| } | |
| /// Lookup the constructor [name] in [cls], fail if the class is missing and | |
| /// [required]. | |
| ConstructorEntity lookupConstructor(ClassEntity cls, String name, | |
| {bool required: false}); | |
| /// Calls [f] for each class member declared in [cls]. | |
| void forEachLocalClassMember(ClassEntity cls, void f(MemberEntity member)); | |
| /// Calls [f] for each class member declared or inherited in [cls] together | |
| /// with the class that declared the member. | |
| /// | |
| /// TODO(johnniwinther): This should not include static members of | |
| /// superclasses. | |
| void forEachClassMember( | |
| ClassEntity cls, void f(ClassEntity declarer, MemberEntity member)); | |
| /// Calls [f] for every constructor declared in [cls]. | |
| /// | |
| /// Will ensure that the class and all constructors are resolved if | |
| /// [ensureResolved] is `true`. | |
| void forEachConstructor( | |
| ClassEntity cls, void f(ConstructorEntity constructor)); | |
| /// Returns the superclass of [cls]. | |
| /// | |
| /// If [skipUnnamedMixinApplications] is `true`, unnamed mixin applications | |
| /// are excluded, for instance for these classes | |
| /// | |
| /// class S {} | |
| /// class M {} | |
| /// class C extends S with M {} | |
| /// | |
| /// the result of `getSuperClass(C)` is the unnamed mixin application | |
| /// typically named `S+M` and `getSuperClass(S+M)` is `S`, whereas | |
| /// the result of `getSuperClass(C, skipUnnamedMixinApplications: false)` is | |
| /// `S`. | |
| ClassEntity getSuperClass(ClassEntity cls, | |
| {bool skipUnnamedMixinApplications: false}); | |
| /// Calls [f] for each supertype of [cls]. | |
| void forEachSupertype(ClassEntity cls, void f(InterfaceType supertype)); | |
| /// Create the instantiation of [cls] with the given [typeArguments]. | |
| InterfaceType createInterfaceType( | |
| ClassEntity cls, List<DartType> typeArguments); | |
| /// Returns the `dynamic` type. | |
| DartType get dynamicType; | |
| /// Returns the 'raw type' of [cls]. That is, the instantiation of [cls] | |
| /// where all types arguments are `dynamic`. | |
| InterfaceType getRawType(ClassEntity cls); | |
| /// Returns the 'this type' of [cls]. That is, the instantiation of [cls] | |
| /// where the type arguments are the type variables of [cls]. | |
| InterfaceType getThisType(ClassEntity cls); | |
| /// Returns `true` if [cls] is generic. | |
| bool isGenericClass(ClassEntity cls); | |
| /// Returns `true` if [cls] is a mixin application (named or unnamed). | |
| bool isMixinApplication(ClassEntity cls); | |
| /// Returns `true` if [cls] is an unnamed mixin application. | |
| bool isUnnamedMixinApplication(ClassEntity cls); | |
| /// The upper bound on the [typeVariable]. If not explicitly declared, this is | |
| /// `Object`. | |
| DartType getTypeVariableBound(TypeVariableEntity typeVariable); | |
| /// Returns the type of [function]. | |
| FunctionType getFunctionType(FunctionEntity function); | |
| /// Returns the function type variables defined on [function]. | |
| List<TypeVariableType> getFunctionTypeVariables(FunctionEntity function); | |
| /// Returns the 'element' type of a function with an async, async* or sync* | |
| /// marker. The return type of the method is inspected to determine the type | |
| /// parameter of the Future, Stream or Iterable. | |
| DartType getFunctionAsyncOrSyncStarElementType(FunctionEntity function); | |
| /// Returns the 'element' type of a function with the async, async* or sync* | |
| /// marker [marker]. [returnType] is the return type marked function. | |
| DartType getAsyncOrSyncStarElementType( | |
| AsyncMarker marker, DartType returnType); | |
| /// Returns the type of the [local] function. | |
| FunctionType getLocalFunctionType(Local local); | |
| /// Returns the 'unaliased' type of [type]. For typedefs this is the function | |
| /// type it is an alias of, for other types it is the type itself. | |
| /// | |
| /// Use this during resolution to ensure that the alias has been computed. | |
| // TODO(johnniwinther): Remove this when the resolver is removed. | |
| DartType getUnaliasedType(DartType type); | |
| /// Returns `true` if [cls] is a Dart enum class. | |
| bool isEnumClass(ClassEntity cls); | |
| } | |
| abstract class KElementEnvironment extends ElementEnvironment { | |
| /// Calls [f] for each class that is mixed into [cls] or one of its | |
| /// superclasses. | |
| void forEachMixin(ClassEntity cls, void f(ClassEntity mixin)); | |
| /// Gets the constant value of [field], or `null` if [field] is non-const. | |
| ConstantExpression getFieldConstantForTesting(FieldEntity field); | |
| /// Returns `true` if [member] a the synthetic getter `loadLibrary` injected | |
| /// on deferred libraries. | |
| bool isDeferredLoadLibraryGetter(MemberEntity member); | |
| /// Returns the imports seen in [library] | |
| Iterable<ImportEntity> getImports(LibraryEntity library); | |
| /// Returns the metadata constants declared on [library]. | |
| Iterable<ConstantValue> getLibraryMetadata(LibraryEntity library); | |
| /// Returns the metadata constants declared on [cls]. | |
| Iterable<ConstantValue> getClassMetadata(ClassEntity cls); | |
| /// Returns the metadata constants declared on [member]. | |
| Iterable<ConstantValue> getMemberMetadata(MemberEntity member, | |
| {bool includeParameterMetadata: false}); | |
| } | |
| abstract class JElementEnvironment extends ElementEnvironment { | |
| /// Calls [f] for each class member added to [cls] during compilation. | |
| void forEachInjectedClassMember(ClassEntity cls, void f(MemberEntity member)); | |
| /// Calls [f] for every constructor body in [cls]. | |
| void forEachConstructorBody( | |
| ClassEntity cls, void f(ConstructorBodyEntity constructorBody)); | |
| /// Calls [f] for each nested closure in [member]. | |
| void forEachNestedClosure( | |
| MemberEntity member, void f(FunctionEntity closure)); | |
| /// Returns `true` if [cls] is a mixin application that mixes in methods with | |
| /// super calls. | |
| bool isSuperMixinApplication(ClassEntity cls); | |
| /// Returns the 'effective' mixin class if [cls] is a mixin application, and | |
| /// `null` otherwise. | |
| /// | |
| /// The 'effective' mixin class is the class from which members are mixed in. | |
| /// Normally this is the mixin class itself, but not if the mixin class itself | |
| /// is a mixin application. | |
| /// | |
| /// Consider this hierarchy: | |
| /// | |
| /// class A {} | |
| /// class B = Object with A {} | |
| /// class C = Object with B {} | |
| /// | |
| /// The mixin classes of `B` and `C` are `A` and `B`, respectively, but the | |
| /// _effective_ mixin class of both is `A`. | |
| ClassEntity getEffectiveMixinClass(ClassEntity cls); | |
| /// The default type of the [typeVariable]. | |
| /// | |
| /// This is the type used as the default type argument when no explicit type | |
| /// argument is passed. | |
| DartType getTypeVariableDefaultType(TypeVariableEntity typeVariable); | |
| /// Returns the type of [field]. | |
| DartType getFieldType(FieldEntity field); | |
| } |