Index: pkg/compiler/lib/src/compiler.dart |
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart |
index c702e041c5ffa8eb8c031845915d554c5e5e3c8c..64d963b16689c058a70ff10161ea971d17f8915f 100644 |
--- a/pkg/compiler/lib/src/compiler.dart |
+++ b/pkg/compiler/lib/src/compiler.dart |
@@ -26,7 +26,7 @@ import 'common/work.dart' show ItemCompilationContext, WorkItem; |
import 'common.dart'; |
import 'compile_time_constants.dart'; |
import 'constants/values.dart'; |
-import 'core_types.dart' show CoreClasses, CoreTypes; |
+import 'core_types.dart' show CoreClasses, CommonElements, CoreTypes; |
import 'dart_types.dart' show DartType, DynamicType, InterfaceType, Types; |
import 'deferred_load.dart' show DeferredLoadTask; |
import 'diagnostics/code_location.dart'; |
@@ -145,64 +145,16 @@ abstract class Compiler implements LibraryLoaderListener { |
Tracer tracer; |
- LibraryElement coreLibrary; |
- LibraryElement asyncLibrary; |
- |
LibraryElement mainApp; |
FunctionElement mainFunction; |
- /// Initialized when dart:mirrors is loaded. |
- LibraryElement mirrorsLibrary; |
- |
- /// Initialized when dart:typed_data is loaded. |
- LibraryElement typedDataLibrary; |
- |
DiagnosticReporter get reporter => _reporter; |
+ CommonElements get commonElements => _coreTypes; |
CoreClasses get coreClasses => _coreTypes; |
CoreTypes get coreTypes => _coreTypes; |
Resolution get resolution => _resolution; |
ParsingContext get parsingContext => _parsingContext; |
- ClassElement typedDataClass; |
- |
- // TODO(johnniwinther): Move this to the JavaScriptBackend. |
- /// The class for patch annotation defined in dart:_js_helper. |
- ClassElement patchAnnotationClass; |
- |
- // TODO(johnniwinther): Move this to the JavaScriptBackend. |
- ClassElement nativeAnnotationClass; |
- |
- ConstructorElement _symbolConstructor; |
- ConstructorElement get symbolConstructor { |
- if (_symbolConstructor == null) { |
- ClassElement symbolClass = coreClasses.symbolClass; |
- symbolClass.ensureResolved(resolution); |
- _symbolConstructor = symbolClass.lookupConstructor(''); |
- assert(invariant(symbolClass, _symbolConstructor != null, |
- message: "Default constructor not found ${symbolClass}.")); |
- } |
- return _symbolConstructor; |
- } |
- |
- // Initialized when dart:mirrors is loaded. |
- ClassElement mirrorSystemClass; |
- |
- // Initialized when dart:mirrors is loaded. |
- ClassElement mirrorsUsedClass; |
- |
- // Initialized after mirrorSystemClass has been resolved. |
- FunctionElement mirrorSystemGetNameFunction; |
- |
- // Initialized when mirrorsUsedClass has been resolved. |
- FunctionElement mirrorsUsedConstructor; |
- |
- // Initialized when dart:mirrors is loaded. |
- ClassElement deferredLibraryClass; |
- |
- Element identicalFunction; |
- Element loadLibraryFunction; |
- Element functionApplyMethod; |
- |
// TODO(zarah): Remove this map and incorporate compile-time errors |
// in the model. |
/// Tracks elements with compile-time errors. |
@@ -285,7 +237,7 @@ abstract class Compiler implements LibraryLoaderListener { |
_resolution = new _CompilerResolution(this); |
// TODO(johnniwinther): Initialize core types in [initializeCoreClasses] and |
// make its field final. |
- _coreTypes = new _CompilerCoreTypes(_resolution); |
+ _coreTypes = new _CompilerCoreTypes(_resolution, reporter); |
types = new Types(_resolution); |
tracer = new Tracer(this, this.outputProvider); |
@@ -321,7 +273,8 @@ abstract class Compiler implements LibraryLoaderListener { |
libraryLoader = new LibraryLoaderTask( |
resolvedUriTranslator, |
options.compileOnly |
- ? new _NoScriptLoader(this) : new _ScriptLoader(this), |
+ ? new _NoScriptLoader(this) |
+ : new _ScriptLoader(this), |
new _ElementScanner(scanner), |
serialization, |
this, |
@@ -406,14 +359,7 @@ abstract class Compiler implements LibraryLoaderListener { |
/// Note that [library] has not been scanned yet, nor has its imports/exports |
/// been resolved. |
void onLibraryCreated(LibraryElement library) { |
- Uri uri = library.canonicalUri; |
- if (uri == Uris.dart_core) { |
- coreLibrary = library; |
- } else if (uri == Uris.dart__native_typed_data) { |
- typedDataLibrary = library; |
- } else if (uri == Uris.dart_mirrors) { |
- mirrorsLibrary = library; |
- } |
+ _coreTypes.onLibraryCreated(library); |
backend.onLibraryCreated(library); |
} |
@@ -427,31 +373,6 @@ abstract class Compiler implements LibraryLoaderListener { |
/// Use [loader] to register the creation and scanning of a patch library |
/// for [library]. |
Future onLibraryScanned(LibraryElement library, LibraryLoader loader) { |
- Uri uri = library.canonicalUri; |
- // If the script of the library is synthesized, the library does not exist |
- // and we do not try to load the helpers. |
- // |
- // This could for example happen if dart:async is disabled, then loading it |
- // should not try to find the given element. |
- if (!library.isSynthesized) { |
- if (uri == Uris.dart_core) { |
- initializeCoreClasses(); |
- identicalFunction = coreLibrary.find('identical'); |
- } else if (uri == Uris.dart_mirrors) { |
- mirrorSystemClass = findRequiredElement(library, 'MirrorSystem'); |
- mirrorsUsedClass = findRequiredElement(library, 'MirrorsUsed'); |
- } else if (uri == Uris.dart_async) { |
- asyncLibrary = library; |
- deferredLibraryClass = findRequiredElement(library, 'DeferredLibrary'); |
- _coreTypes.futureClass = findRequiredElement(library, 'Future'); |
- _coreTypes.streamClass = findRequiredElement(library, 'Stream'); |
- } else if (uri == Uris.dart__native_typed_data) { |
- typedDataClass = findRequiredElement(library, 'NativeTypedData'); |
- } else if (uri == js_backend.BackendHelpers.DART_JS_HELPER) { |
- patchAnnotationClass = findRequiredElement(library, '_Patch'); |
- nativeAnnotationClass = findRequiredElement(library, 'Native'); |
- } |
- } |
return backend.onLibraryScanned(library, loader); |
} |
@@ -558,71 +479,13 @@ abstract class Compiler implements LibraryLoaderListener { |
.join(MessageTemplate.IMPORT_EXPERIMENTAL_MIRRORS_PADDING) |
}); |
} |
- |
- coreClasses.functionClass.ensureResolved(resolution); |
- functionApplyMethod = |
- coreClasses.functionClass.lookupLocalMember('apply'); |
}).then((_) => backend.onLibrariesLoaded(loadedLibraries)); |
} |
- Element findRequiredElement(LibraryElement library, String name) { |
- var element = library.find(name); |
- if (element == null) { |
- reporter.internalError( |
- library, |
- "The library '${library.canonicalUri}' does not contain required " |
- "element: '$name'."); |
- } |
- return element; |
- } |
- |
// TODO(johnniwinther): Move this to [PatchParser] when it is moved to the |
// [JavaScriptBackend]. Currently needed for testing. |
String get patchVersion => backend.patchVersion; |
- // TODO(johnniwinther): Remove this. All elements should be looked up on |
- // demand. |
- void onClassResolved(ClassElement cls) { |
- if (mirrorSystemClass == cls) { |
- mirrorSystemGetNameFunction = cls.lookupLocalMember('getName'); |
- } else if (mirrorsUsedClass == cls) { |
- mirrorsUsedConstructor = cls.constructors.head; |
- } |
- } |
- |
- void initializeCoreClasses() { |
- final List missingCoreClasses = []; |
- ClassElement lookupCoreClass(String name) { |
- ClassElement result = coreLibrary.find(name); |
- if (result == null) { |
- missingCoreClasses.add(name); |
- } |
- return result; |
- } |
- |
- _coreTypes.objectClass = lookupCoreClass('Object'); |
- _coreTypes.boolClass = lookupCoreClass('bool'); |
- _coreTypes.numClass = lookupCoreClass('num'); |
- _coreTypes.intClass = lookupCoreClass('int'); |
- _coreTypes.doubleClass = lookupCoreClass('double'); |
- _coreTypes.resourceClass = lookupCoreClass('Resource'); |
- _coreTypes.stringClass = lookupCoreClass('String'); |
- _coreTypes.functionClass = lookupCoreClass('Function'); |
- _coreTypes.listClass = lookupCoreClass('List'); |
- _coreTypes.typeClass = lookupCoreClass('Type'); |
- _coreTypes.mapClass = lookupCoreClass('Map'); |
- _coreTypes.nullClass = lookupCoreClass('Null'); |
- _coreTypes.stackTraceClass = lookupCoreClass('StackTrace'); |
- _coreTypes.iterableClass = lookupCoreClass('Iterable'); |
- _coreTypes.symbolClass = lookupCoreClass('Symbol'); |
- if (!missingCoreClasses.isEmpty) { |
- reporter.internalError( |
- coreLibrary, |
- 'dart:core library does not contain required classes: ' |
- '$missingCoreClasses'); |
- } |
- } |
- |
Element _unnamedListConstructor; |
Element get unnamedListConstructor { |
if (_unnamedListConstructor != null) return _unnamedListConstructor; |
@@ -1299,28 +1162,188 @@ class SuppressionInfo { |
int hints = 0; |
} |
-class _CompilerCoreTypes implements CoreTypes, CoreClasses { |
+class _CompilerCoreTypes implements CoreTypes, CoreClasses, CommonElements { |
final Resolution resolution; |
+ final DiagnosticReporter reporter; |
+ |
+ LibraryElement coreLibrary; |
+ LibraryElement asyncLibrary; |
+ LibraryElement mirrorsLibrary; |
+ LibraryElement typedDataLibrary; |
+ |
+ // TODO(sigmund): possibly move this to target-specific collection of |
+ // elements, or refactor the library so that the helpers we need are in a |
+ // target-agnostic place. Currently we are using @patch and @Native from |
+ // here. We hope we can make those independent of the backend and generic |
+ // enough so the patching algorithm can work without being configured for a |
+ // specific backend. |
+ LibraryElement jsHelperLibrary; |
+ |
+ _CompilerCoreTypes(this.resolution, this.reporter); |
+ |
+ // From dart:core |
+ |
+ ClassElement _objectClass; |
+ ClassElement get objectClass => |
+ _objectClass ??= _findRequired(coreLibrary, 'Object'); |
+ |
+ ClassElement _boolClass; |
+ ClassElement get boolClass => |
+ _boolClass ??= _findRequired(coreLibrary, 'bool'); |
+ |
+ ClassElement _numClass; |
+ ClassElement get numClass => _numClass ??= _findRequired(coreLibrary, 'num'); |
+ |
+ ClassElement _intClass; |
+ ClassElement get intClass => _intClass ??= _findRequired(coreLibrary, 'int'); |
+ |
+ ClassElement _doubleClass; |
+ ClassElement get doubleClass => |
+ _doubleClass ??= _findRequired(coreLibrary, 'double'); |
+ |
+ ClassElement _stringClass; |
+ ClassElement get stringClass => |
+ _stringClass ??= _findRequired(coreLibrary, 'String'); |
+ |
+ ClassElement _functionClass; |
+ ClassElement get functionClass => |
+ _functionClass ??= _findRequired(coreLibrary, 'Function'); |
+ |
+ Element _functionApplyMethod; |
+ Element get functionApplyMethod { |
+ if (_functionApplyMethod == null) { |
+ functionClass.ensureResolved(resolution); |
+ _functionApplyMethod = functionClass.lookupLocalMember('apply'); |
+ assert(invariant(functionClass, _functionApplyMethod != null, |
+ message: "Member `apply` not found in ${functionClass}.")); |
+ } |
+ return _functionApplyMethod; |
+ } |
+ |
+ bool isFunctionApplyMethod(Element element) => |
+ element.name == 'apply' && element.enclosingClass == functionClass; |
+ |
+ ClassElement _nullClass; |
+ ClassElement get nullClass => |
+ _nullClass ??= _findRequired(coreLibrary, 'Null'); |
+ |
+ ClassElement _listClass; |
+ ClassElement get listClass => |
+ _listClass ??= _findRequired(coreLibrary, 'List'); |
- ClassElement objectClass; |
- ClassElement boolClass; |
- ClassElement numClass; |
- ClassElement intClass; |
- ClassElement doubleClass; |
- ClassElement stringClass; |
- ClassElement functionClass; |
- ClassElement nullClass; |
- ClassElement listClass; |
- ClassElement typeClass; |
- ClassElement mapClass; |
- ClassElement symbolClass; |
- ClassElement stackTraceClass; |
- ClassElement futureClass; |
- ClassElement iterableClass; |
- ClassElement streamClass; |
- ClassElement resourceClass; |
- |
- _CompilerCoreTypes(this.resolution); |
+ ClassElement _typeClass; |
+ ClassElement get typeClass => |
+ _typeClass ??= _findRequired(coreLibrary, 'Type'); |
+ |
+ ClassElement _mapClass; |
+ ClassElement get mapClass => _mapClass ??= _findRequired(coreLibrary, 'Map'); |
+ |
+ ClassElement _symbolClass; |
+ ClassElement get symbolClass => |
+ _symbolClass ??= _findRequired(coreLibrary, 'Symbol'); |
+ |
+ ConstructorElement _symbolConstructor; |
+ ConstructorElement get symbolConstructor { |
+ if (_symbolConstructor == null) { |
+ symbolClass.ensureResolved(resolution); |
+ _symbolConstructor = symbolClass.lookupConstructor(''); |
+ assert(invariant(symbolClass, _symbolConstructor != null, |
+ message: "Default constructor not found ${symbolClass}.")); |
+ } |
+ return _symbolConstructor; |
+ } |
+ |
+ bool isSymbolConstructor(Element e) => |
+ e.enclosingClass == symbolClass && e == symbolConstructor; |
+ |
+ ClassElement _stackTraceClass; |
+ ClassElement get stackTraceClass => |
+ _stackTraceClass ??= _findRequired(coreLibrary, 'StackTrace'); |
+ |
+ ClassElement _iterableClass; |
+ ClassElement get iterableClass => |
+ _iterableClass ??= _findRequired(coreLibrary, 'Iterable'); |
+ |
+ ClassElement _resourceClass; |
+ ClassElement get resourceClass => |
+ _resourceClass ??= _findRequired(coreLibrary, 'Resource'); |
+ |
+ Element _identicalFunction; |
+ Element get identicalFunction => |
+ _identicalFunction ??= coreLibrary.find('identical'); |
+ |
+ // From dart:async |
+ |
+ ClassElement _futureClass; |
+ ClassElement get futureClass => |
+ _futureClass ??= _findRequired(asyncLibrary, 'Future'); |
+ |
+ ClassElement _streamClass; |
+ ClassElement get streamClass => |
+ _streamClass ??= _findRequired(asyncLibrary, 'Stream'); |
+ |
+ ClassElement _deferredLibraryClass; |
+ ClassElement get deferredLibraryClass => |
+ _deferredLibraryClass ??= _findRequired(asyncLibrary, "DeferredLibrary"); |
+ |
+ // From dart:mirrors |
+ |
+ ClassElement _mirrorSystemClass; |
+ ClassElement get mirrorSystemClass => |
+ _mirrorSystemClass ??= _findRequired(mirrorsLibrary, 'MirrorSystem'); |
+ |
+ FunctionElement _mirrorSystemGetNameFunction; |
+ bool isMirrorSystemGetNameFunction(Element element) { |
+ if (_mirrorSystemGetNameFunction == null) { |
+ if (!element.isFunction || mirrorsLibrary == null) return false; |
+ ClassElement cls = mirrorSystemClass; |
+ if (element.enclosingClass != cls) return false; |
+ if (cls != null) { |
+ cls.ensureResolved(resolution); |
+ _mirrorSystemGetNameFunction = cls.lookupLocalMember('getName'); |
+ } |
+ } |
+ return element == _mirrorSystemGetNameFunction; |
+ } |
+ |
+ ClassElement _mirrorsUsedClass; |
+ ClassElement get mirrorsUsedClass => |
+ _mirrorsUsedClass ??= _findRequired(mirrorsLibrary, 'MirrorsUsed'); |
+ |
+ bool isMirrorsUsedConstructor(ConstructorElement element) => |
+ mirrorsLibrary != null && mirrorsUsedClass == element.enclosingClass; |
+ |
+ ConstructorElement _mirrorsUsedConstructor; |
+ @override |
+ ConstructorElement get mirrorsUsedConstructor { |
+ if (_mirrorsUsedConstructor == null) { |
+ ClassElement cls = mirrorsUsedClass; |
+ if (cls != null) { |
+ cls.ensureResolved(resolution); |
+ _mirrorsUsedConstructor = cls.constructors.head; |
+ } |
+ } |
+ return _mirrorsUsedConstructor; |
+ } |
+ |
+ // From dart:typed_data |
+ |
+ ClassElement _typedDataClass; |
+ ClassElement get typedDataClass => |
+ _typedDataClass ??= _findRequired(typedDataLibrary, 'NativeTypedData'); |
+ |
+ // From dart:_js_helper |
+ // TODO(sigmund,johnniwinther): refactor needed: either these move to a |
+ // backend-specific collection of helpers, or the helper code moves to a |
+ // backend agnostic library (see commend above on [jsHelperLibrary]. |
+ |
+ ClassElement _patchAnnotationClass; |
+ ClassElement get patchAnnotationClass => |
+ _patchAnnotationClass ??= _findRequired(jsHelperLibrary, '_Patch'); |
+ |
+ ClassElement _nativeAnnotationClass; |
+ ClassElement get nativeAnnotationClass => |
+ _nativeAnnotationClass ??= _findRequired(jsHelperLibrary, 'Native'); |
@override |
InterfaceType get objectType { |
@@ -1447,6 +1470,39 @@ class _CompilerCoreTypes implements CoreTypes, CoreClasses { |
} |
return type.createInstantiation([elementType]); |
} |
+ |
+ void onLibraryCreated(LibraryElement library) { |
+ Uri uri = library.canonicalUri; |
+ if (uri == Uris.dart_core) { |
+ coreLibrary = library; |
+ } else if (uri == Uris.dart_async) { |
+ asyncLibrary = library; |
+ } else if (uri == Uris.dart__native_typed_data) { |
+ typedDataLibrary = library; |
+ } else if (uri == Uris.dart_mirrors) { |
+ mirrorsLibrary = library; |
+ } else if (uri == js_backend.BackendHelpers.DART_JS_HELPER) { |
+ jsHelperLibrary = library; |
+ } |
+ } |
+ |
+ Element _findRequired(LibraryElement library, String name) { |
+ // If the script of the library is synthesized, the library does not exist |
+ // and we do not try to load the helpers. |
+ // |
+ // This could for example happen if dart:async is disabled, then loading it |
+ // should not try to find the given element. |
+ if (library == null || library.isSynthesized) return null; |
+ |
+ var element = library.find(name); |
+ if (element == null) { |
+ reporter.internalError( |
+ library, |
+ "The library '${library.canonicalUri}' does not contain required " |
+ "element: '$name'."); |
+ } |
+ return element; |
+ } |
} |
class CompilerDiagnosticReporter extends DiagnosticReporter { |
@@ -1893,6 +1949,9 @@ class _CompilerResolution implements Resolution { |
CoreTypes get coreTypes => compiler.coreTypes; |
@override |
+ CommonElements get commonElements => compiler.commonElements; |
+ |
+ @override |
Types get types => compiler.types; |
@override |
@@ -1918,27 +1977,10 @@ class _CompilerResolution implements Resolution { |
compiler.mirrorUsageAnalyzerTask; |
@override |
- LibraryElement get coreLibrary => compiler.coreLibrary; |
- |
- @override |
- FunctionElement get identicalFunction => compiler.identicalFunction; |
- |
- @override |
- ClassElement get mirrorSystemClass => compiler.mirrorSystemClass; |
- |
- @override |
- FunctionElement get mirrorSystemGetNameFunction => |
- compiler.mirrorSystemGetNameFunction; |
- |
- @override |
- ConstructorElement get mirrorsUsedConstructor => |
- compiler.mirrorsUsedConstructor; |
+ LibraryElement get coreLibrary => compiler._coreTypes.coreLibrary; |
@override |
- ConstructorElement get symbolConstructor => compiler.symbolConstructor; |
- |
- @override |
- ConstantValue proxyConstant; |
+ bool get wasProxyConstantComputedTestingOnly => _proxyConstant != null; |
@override |
void registerClass(ClassElement cls) { |
@@ -1979,10 +2021,6 @@ class _CompilerResolution implements Resolution { |
} |
@override |
- void onClassResolved(ClassElement element) => |
- compiler.onClassResolved(element); |
- |
- @override |
void registerCompileTimeError(Element element, DiagnosticMessage message) => |
compiler.registerCompileTimeError(element, message); |
@@ -2131,16 +2169,18 @@ class _CompilerResolution implements Resolution { |
_resolutionImpactCache.remove(element); |
} |
+ ConstantValue _proxyConstant; |
+ |
@override |
bool isProxyConstant(ConstantValue value) { |
FieldElement field = coreLibrary.find('proxy'); |
if (field == null) return false; |
if (!hasBeenResolved(field)) return false; |
- if (proxyConstant == null) { |
- proxyConstant = constants |
+ if (_proxyConstant == null) { |
+ _proxyConstant = constants |
.getConstantValue(resolver.constantCompiler.compileConstant(field)); |
} |
- return proxyConstant == value; |
+ return _proxyConstant == value; |
} |
} |
@@ -2183,8 +2223,8 @@ class _NoScriptLoader implements ScriptLoader { |
_NoScriptLoader(this.compiler); |
Future<Script> readScript(Uri uri, [Spannable spannable]) { |
- compiler.reporter.internalError(spannable, |
- "Script loading of '$uri' is not enabled."); |
+ compiler.reporter |
+ .internalError(spannable, "Script loading of '$uri' is not enabled."); |
} |
} |