Index: pkg/compiler/lib/src/native/enqueue.dart |
diff --git a/pkg/compiler/lib/src/native/enqueue.dart b/pkg/compiler/lib/src/native/enqueue.dart |
index adb79f734192f2ec6a09d220a73d095e2211682d..430b22ed2554908ff103ae04500247f0ead90767 100644 |
--- a/pkg/compiler/lib/src/native/enqueue.dart |
+++ b/pkg/compiler/lib/src/native/enqueue.dart |
@@ -4,18 +4,16 @@ |
import '../common.dart'; |
import '../common/backend_api.dart'; |
-import '../common/resolution.dart' show Resolution; |
-import '../compiler.dart' show Compiler; |
-import '../common_elements.dart' show CommonElements; |
+import '../common_elements.dart' show CommonElements, ElementEnvironment; |
import '../elements/elements.dart'; |
import '../elements/entities.dart'; |
import '../elements/resolution_types.dart'; |
import '../elements/types.dart'; |
import '../js_backend/backend_helpers.dart' show BackendHelpers; |
import '../js_backend/backend_usage.dart' show BackendUsageBuilder; |
-import '../js_backend/js_backend.dart'; |
-import '../js_backend/native_data.dart' show NativeBasicData, NativeData; |
+import '../js_backend/native_data.dart' show NativeData; |
import '../js_emitter/js_emitter.dart' show CodeEmitterTask, NativeEmitter; |
+import '../options.dart'; |
import '../universe/use.dart' show StaticUse, TypeUse; |
import '../universe/world_impact.dart' |
show WorldImpact, WorldImpactBuilder, WorldImpactBuilderImpl; |
@@ -30,7 +28,7 @@ class NativeEnqueuer { |
void onInstantiatedType(InterfaceType type) {} |
/// Initial entry point to native enqueuer. |
- WorldImpact processNativeClasses(Iterable<LibraryElement> libraries) => |
+ WorldImpact processNativeClasses(Iterable<LibraryEntity> libraries) => |
const WorldImpact(); |
/// Registers the [nativeBehavior]. Adds the liveness of its instantiated |
@@ -42,29 +40,29 @@ class NativeEnqueuer { |
bool get hasInstantiatedNativeClasses => false; |
/// Emits a summary information using the [log] function. |
- void logSummary(log(message)) {} |
+ void logSummary(void log(String message)) {} |
} |
abstract class NativeEnqueuerBase implements NativeEnqueuer { |
- final Set<ClassElement> _registeredClasses = new Set<ClassElement>(); |
- final Set<ClassElement> _unusedClasses = new Set<ClassElement>(); |
+ final Set<ClassEntity> _registeredClasses = new Set<ClassEntity>(); |
+ final Set<ClassEntity> _unusedClasses = new Set<ClassEntity>(); |
bool get hasInstantiatedNativeClasses => !_registeredClasses.isEmpty; |
- final Compiler _compiler; |
- final bool enableLiveTypeAnalysis; |
+ /// Log message reported if all native types are used. |
+ String _allUsedMessage; |
- /// Subclasses of [NativeEnqueuerBase] are constructed by the backend. |
- NativeEnqueuerBase(this._compiler, this.enableLiveTypeAnalysis); |
- |
- JavaScriptBackend get _backend => _compiler.backend; |
- BackendHelpers get _helpers => _backend.helpers; |
- Resolution get _resolution => _compiler.resolution; |
+ final CompilerOptions _options; |
+ final ElementEnvironment _elementEnvironment; |
+ final CommonElements _commonElements; |
+ final BackendHelpers _helpers; |
+ final BackendClasses _backendClasses; |
- DiagnosticReporter get _reporter => _compiler.reporter; |
- CommonElements get _commonElements => _compiler.commonElements; |
+ /// Subclasses of [NativeEnqueuerBase] are constructed by the backend. |
+ NativeEnqueuerBase(this._options, this._elementEnvironment, |
+ this._commonElements, this._helpers, this._backendClasses); |
- BackendClasses get _backendClasses => _backend.backendClasses; |
+ bool get enableLiveTypeAnalysis => _options.enableNativeLiveTypeAnalysis; |
void onInstantiatedType(InterfaceType type) { |
if (_unusedClasses.remove(type.element)) { |
@@ -74,17 +72,16 @@ abstract class NativeEnqueuerBase implements NativeEnqueuer { |
/// Register [classes] as natively instantiated in [impactBuilder]. |
void _registerTypeUses( |
- WorldImpactBuilder impactBuilder, Set<ClassElement> classes, cause) { |
- for (ClassElement cls in classes) { |
+ WorldImpactBuilder impactBuilder, Set<ClassEntity> classes, cause) { |
+ for (ClassEntity cls in classes) { |
if (!_unusedClasses.contains(cls)) { |
// No need to add [classElement] to [impactBuilder]: it has already been |
// instantiated and we don't track origins of native instantiations |
// precisely. |
continue; |
} |
- cls.ensureResolved(_resolution); |
- impactBuilder |
- .registerTypeUse(new TypeUse.nativeInstantiation(cls.rawType)); |
+ impactBuilder.registerTypeUse( |
+ new TypeUse.nativeInstantiation(_elementEnvironment.getRawType(cls))); |
} |
} |
@@ -95,12 +92,12 @@ abstract class NativeEnqueuerBase implements NativeEnqueuer { |
void _processNativeBehavior( |
WorldImpactBuilder impactBuilder, NativeBehavior behavior, cause) { |
- void registerInstantiation(ResolutionInterfaceType type) { |
+ void registerInstantiation(InterfaceType type) { |
impactBuilder.registerTypeUse(new TypeUse.nativeInstantiation(type)); |
} |
int unusedBefore = _unusedClasses.length; |
- Set<ClassElement> matchingClasses = new Set<ClassElement>(); |
+ Set<ClassEntity> matchingClasses = new Set<ClassEntity>(); |
for (var type in behavior.typesInstantiated) { |
if (type is SpecialType) { |
if (type == SpecialType.JsObject) { |
@@ -108,7 +105,7 @@ abstract class NativeEnqueuerBase implements NativeEnqueuer { |
} |
continue; |
} |
- if (type is ResolutionInterfaceType) { |
+ if (type is InterfaceType) { |
if (type == _commonElements.numType) { |
registerInstantiation(_commonElements.doubleType); |
registerInstantiation(_commonElements.intType); |
@@ -117,7 +114,8 @@ abstract class NativeEnqueuerBase implements NativeEnqueuer { |
type == _commonElements.stringType || |
type == _commonElements.nullType || |
type == _commonElements.boolType || |
- type.asInstanceOf(_backendClasses.listClass) != null) { |
+ _elementEnvironment.isSubtype(type, |
+ _elementEnvironment.getRawType(_backendClasses.listClass))) { |
registerInstantiation(type); |
} |
// TODO(johnniwinther): Improve spec string precision to handle type |
@@ -128,15 +126,17 @@ abstract class NativeEnqueuerBase implements NativeEnqueuer { |
// TODO(johnniwinther,sra): Find and replace uses of `List` with the |
// actual implementation classes such as `JSArray` et al. |
matchingClasses |
- .addAll(_findUnusedClassesMatching((ClassElement nativeClass) { |
- ResolutionInterfaceType nativeType = nativeClass.thisType; |
- ResolutionInterfaceType specType = type.element.thisType; |
- return _compiler.types.isSubtype(nativeType, specType); |
+ .addAll(_findUnusedClassesMatching((ClassEntity nativeClass) { |
+ InterfaceType nativeType = |
+ _elementEnvironment.getThisType(nativeClass); |
+ InterfaceType specType = |
+ _elementEnvironment.getThisType(type.element); |
+ return _elementEnvironment.isSubtype(nativeType, specType); |
})); |
} else if (type.isDynamic) { |
matchingClasses.addAll(_unusedClasses); |
} else { |
- assert(type is ResolutionVoidType); |
+ assert(type is VoidType); |
} |
} |
if (matchingClasses.isNotEmpty && _registeredClasses.isEmpty) { |
@@ -147,18 +147,18 @@ abstract class NativeEnqueuerBase implements NativeEnqueuer { |
// Give an info so that library developers can compile with -v to find why |
// all the native classes are included. |
if (unusedBefore > 0 && unusedBefore == matchingClasses.length) { |
- _reporter.log('All native types marked as used due to $cause.'); |
+ _allUsedMessage ??= 'All native types marked as used due to $cause.'; |
} |
} |
- Iterable<ClassElement> _findUnusedClassesMatching( |
- bool predicate(classElement)) { |
+ Iterable<ClassEntity> _findUnusedClassesMatching( |
+ bool predicate(ClassEntity classElement)) { |
return _unusedClasses.where(predicate); |
} |
void _registerBackendUse(FunctionEntity element) {} |
- Iterable<ClassElement> _onFirstNativeClass(WorldImpactBuilder impactBuilder) { |
+ Iterable<ClassEntity> _onFirstNativeClass(WorldImpactBuilder impactBuilder) { |
void staticUse(FunctionEntity element) { |
impactBuilder.registerStaticUse(new StaticUse.implicitInvoke(element)); |
_registerBackendUse(element); |
@@ -171,8 +171,8 @@ abstract class NativeEnqueuerBase implements NativeEnqueuer { |
return _findNativeExceptions(); |
} |
- Iterable<ClassElement> _findNativeExceptions() { |
- return _findUnusedClassesMatching((classElement) { |
+ Iterable<ClassEntity> _findNativeExceptions() { |
+ return _findUnusedClassesMatching((ClassEntity classElement) { |
// TODO(sra): Annotate exception classes in dart:html. |
String name = classElement.name; |
if (name.contains('Exception')) return true; |
@@ -180,28 +180,41 @@ abstract class NativeEnqueuerBase implements NativeEnqueuer { |
return false; |
}); |
} |
+ |
+ void logSummary(void log(String message)) { |
+ if (_allUsedMessage != null) { |
+ log(_allUsedMessage); |
+ } |
+ } |
} |
class NativeResolutionEnqueuer extends NativeEnqueuerBase { |
final NativeClassResolver _nativeClassResolver; |
+ final BackendUsageBuilder _backendUsageBuilder; |
/// The set of all native classes. Each native class is in [nativeClasses] |
/// and exactly one of [unusedClasses] and [registeredClasses]. |
- final Set<ClassElement> _nativeClasses = new Set<ClassElement>(); |
- |
- NativeResolutionEnqueuer(Compiler compiler, this._nativeClassResolver) |
- : super(compiler, compiler.options.enableNativeLiveTypeAnalysis); |
- |
- BackendUsageBuilder get _backendUsageBuilder => _backend.backendUsageBuilder; |
+ final Set<ClassEntity> _nativeClasses = new Set<ClassEntity>(); |
+ |
+ NativeResolutionEnqueuer( |
+ CompilerOptions options, |
+ ElementEnvironment elementEnvironment, |
+ CommonElements commonElements, |
+ BackendHelpers helpers, |
+ BackendClasses backendClasses, |
+ this._backendUsageBuilder, |
+ this._nativeClassResolver) |
+ : super(options, elementEnvironment, commonElements, helpers, |
+ backendClasses); |
void _registerBackendUse(FunctionEntity element) { |
_backendUsageBuilder.registerBackendFunctionUse(element); |
_backendUsageBuilder.registerGlobalFunctionDependency(element); |
} |
- WorldImpact processNativeClasses(Iterable<LibraryElement> libraries) { |
+ WorldImpact processNativeClasses(Iterable<LibraryEntity> libraries) { |
WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl(); |
- Set<ClassElement> nativeClasses = |
+ Set<ClassEntity> nativeClasses = |
_nativeClassResolver.computeNativeClasses(libraries); |
_nativeClasses.addAll(nativeClasses); |
_unusedClasses.addAll(nativeClasses); |
@@ -211,7 +224,8 @@ class NativeResolutionEnqueuer extends NativeEnqueuerBase { |
return impactBuilder; |
} |
- void logSummary(log(message)) { |
+ void logSummary(void log(String message)) { |
+ super.logSummary(log); |
log('Resolved ${_registeredClasses.length} native elements used, ' |
'${_unusedClasses.length} native elements dead.'); |
} |
@@ -219,16 +233,22 @@ class NativeResolutionEnqueuer extends NativeEnqueuerBase { |
class NativeCodegenEnqueuer extends NativeEnqueuerBase { |
final CodeEmitterTask _emitter; |
- |
- final Set<ClassElement> _doneAddSubtypes = new Set<ClassElement>(); |
- |
final NativeResolutionEnqueuer _resolutionEnqueuer; |
+ final NativeData _nativeData; |
- NativeCodegenEnqueuer( |
- Compiler compiler, this._emitter, this._resolutionEnqueuer) |
- : super(compiler, compiler.options.enableNativeLiveTypeAnalysis) {} |
+ final Set<ClassEntity> _doneAddSubtypes = new Set<ClassEntity>(); |
- NativeData get _nativeData => _backend.nativeData; |
+ NativeCodegenEnqueuer( |
+ CompilerOptions options, |
+ ElementEnvironment elementEnvironment, |
+ CommonElements commonElements, |
+ BackendHelpers helpers, |
+ BackendClasses backendClasses, |
+ this._emitter, |
+ this._resolutionEnqueuer, |
+ this._nativeData) |
+ : super(options, elementEnvironment, commonElements, helpers, |
+ backendClasses); |
WorldImpact processNativeClasses(Iterable<LibraryElement> libraries) { |
WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl(); |
@@ -240,8 +260,8 @@ class NativeCodegenEnqueuer extends NativeEnqueuerBase { |
} |
// HACK HACK - add all the resolved classes. |
- Set<ClassElement> matchingClasses = new Set<ClassElement>(); |
- for (final classElement in _resolutionEnqueuer._registeredClasses) { |
+ Set<ClassEntity> matchingClasses = new Set<ClassEntity>(); |
+ for (ClassEntity classElement in _resolutionEnqueuer._registeredClasses) { |
if (_unusedClasses.contains(classElement)) { |
matchingClasses.add(classElement); |
} |
@@ -254,10 +274,10 @@ class NativeCodegenEnqueuer extends NativeEnqueuerBase { |
} |
void _registerTypeUses( |
- WorldImpactBuilder impactBuilder, Set<ClassElement> classes, cause) { |
+ WorldImpactBuilder impactBuilder, Set<ClassEntity> classes, cause) { |
super._registerTypeUses(impactBuilder, classes, cause); |
- for (ClassElement classElement in classes) { |
+ for (ClassEntity classElement in classes) { |
// Add the information that this class is a subtype of its supertypes. The |
// code emitter and the ssa builder use that information. |
_addSubtypes(classElement, _emitter.nativeEmitter); |
@@ -293,7 +313,8 @@ class NativeCodegenEnqueuer extends NativeEnqueuerBase { |
directSubtypes.add(cls); |
} |
- void logSummary(log(message)) { |
+ void logSummary(void log(String message)) { |
+ super.logSummary(log); |
log('Compiled ${_registeredClasses.length} native classes, ' |
'${_unusedClasses.length} native classes omitted.'); |
} |