mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 04:16:51 +00:00
Add TypeUse.
BUG= R=sigurdm@google.com Review URL: https://codereview.chromium.org/1422623014.
This commit is contained in:
parent
08efdd3f30
commit
3837194311
|
@ -24,7 +24,8 @@ import '../resolution/tree_elements.dart' show
|
|||
TreeElements;
|
||||
import '../universe/use.dart' show
|
||||
DynamicUse,
|
||||
StaticUse;
|
||||
StaticUse,
|
||||
TypeUse;
|
||||
import '../universe/world_impact.dart' show
|
||||
WorldImpact,
|
||||
WorldImpactBuilder;
|
||||
|
@ -189,8 +190,8 @@ class CodegenRegistry extends Registry {
|
|||
compiler.dumpInfoTask.elementUsesSelector(currentElement, dynamicUse);
|
||||
}
|
||||
|
||||
void registerIsCheck(DartType type) {
|
||||
worldImpact.registerIsCheck(type);
|
||||
void registerTypeUse(TypeUse typeUse) {
|
||||
worldImpact.registerTypeUse(typeUse);
|
||||
}
|
||||
|
||||
void registerCompileTimeConstant(ConstantValue constant) {
|
||||
|
@ -223,7 +224,7 @@ class CodegenRegistry extends Registry {
|
|||
}
|
||||
|
||||
void registerInstantiation(InterfaceType type) {
|
||||
worldImpact.registerInstantiatedType(type);
|
||||
registerTypeUse(new TypeUse.instantiation(type));
|
||||
}
|
||||
|
||||
void registerAsyncMarker(FunctionElement element) {
|
||||
|
|
|
@ -364,12 +364,11 @@ class DartImpactTransformer extends ImpactTransformer {
|
|||
backend.usedTypeLiterals.add(typeLiteral.element);
|
||||
}
|
||||
}
|
||||
for (InterfaceType instantiatedType in worldImpact.instantiatedTypes) {
|
||||
// TODO(johnniwinther): Remove this when dependency tracking is done on
|
||||
// the world impact itself.
|
||||
transformed.registerInstantiatedType(instantiatedType);
|
||||
backend.registerPlatformMembers(instantiatedType,
|
||||
registerUse: transformed.registerDynamicUse);
|
||||
for (TypeUse typeUse in worldImpact.typeUses) {
|
||||
if (typeUse.kind == TypeUseKind.INSTANTIATION) {
|
||||
backend.registerPlatformMembers(typeUse.type,
|
||||
registerUse: transformed.registerDynamicUse);
|
||||
}
|
||||
}
|
||||
return transformed;
|
||||
}
|
||||
|
|
|
@ -48,7 +48,9 @@ import '../tree/tree.dart';
|
|||
import '../universe/selector.dart' show
|
||||
Selector;
|
||||
import '../universe/use.dart' show
|
||||
DynamicUse;
|
||||
DynamicUse,
|
||||
TypeUse,
|
||||
TypeUseKind;
|
||||
import '../universe/world_impact.dart' show
|
||||
WorldImpact,
|
||||
TransformedWorldImpact;
|
||||
|
|
|
@ -48,7 +48,9 @@ import 'tree/tree.dart' show
|
|||
NewExpression,
|
||||
Node;
|
||||
import 'universe/use.dart' show
|
||||
StaticUse;
|
||||
StaticUse,
|
||||
TypeUse,
|
||||
TypeUseKind;
|
||||
import 'universe/world_impact.dart' show
|
||||
WorldImpact;
|
||||
import 'util/setlet.dart' show
|
||||
|
@ -318,18 +320,27 @@ class DeferredLoadTask extends CompilerTask {
|
|||
elements.add(staticUse.element);
|
||||
});
|
||||
elements.addAll(worldImpact.closures);
|
||||
for (DartType type in worldImpact.typeLiterals) {
|
||||
if (type.isTypedef || type.isInterfaceType) {
|
||||
elements.add(type.element);
|
||||
for (TypeUse typeUse in worldImpact.typeUses) {
|
||||
DartType type = typeUse.type;
|
||||
switch (typeUse.kind) {
|
||||
case TypeUseKind.TYPE_LITERAL:
|
||||
if (type.isTypedef || type.isInterfaceType) {
|
||||
elements.add(type.element);
|
||||
}
|
||||
break;
|
||||
case TypeUseKind.INSTANTIATION:
|
||||
case TypeUseKind.IS_CHECK:
|
||||
case TypeUseKind.AS_CAST:
|
||||
case TypeUseKind.CATCH_TYPE:
|
||||
collectTypeDependencies(type);
|
||||
break;
|
||||
case TypeUseKind.CHECKED_MODE_CHECK:
|
||||
if (compiler.enableTypeAssertions) {
|
||||
collectTypeDependencies(type);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
worldImpact.instantiatedTypes.forEach(collectTypeDependencies);
|
||||
worldImpact.isChecks.forEach(collectTypeDependencies);
|
||||
worldImpact.asCasts.forEach(collectTypeDependencies);
|
||||
worldImpact.onCatchTypes.forEach(collectTypeDependencies);
|
||||
if (compiler.enableTypeAssertions) {
|
||||
worldImpact.checkedModeChecks.forEach(collectTypeDependencies);
|
||||
}
|
||||
|
||||
TreeElements treeElements = analyzableElement.resolvedAst.elements;
|
||||
assert(treeElements != null);
|
||||
|
|
|
@ -54,7 +54,9 @@ import 'universe/universe.dart';
|
|||
import 'universe/use.dart' show
|
||||
DynamicUse,
|
||||
StaticUse,
|
||||
StaticUseKind;
|
||||
StaticUseKind,
|
||||
TypeUse,
|
||||
TypeUseKind;
|
||||
import 'universe/world_impact.dart' show
|
||||
WorldImpact;
|
||||
import 'util/util.dart' show
|
||||
|
@ -167,13 +169,7 @@ abstract class Enqueuer {
|
|||
// TODO(johnniwinther): Optimize the application of the world impact.
|
||||
worldImpact.dynamicUses.forEach(registerDynamicUse);
|
||||
worldImpact.staticUses.forEach(registerStaticUse);
|
||||
worldImpact.instantiatedTypes.forEach(registerInstantiatedType);
|
||||
worldImpact.isChecks.forEach(registerIsCheck);
|
||||
worldImpact.asCasts.forEach(registerIsCheck);
|
||||
if (compiler.enableTypeAssertions) {
|
||||
worldImpact.checkedModeChecks.forEach(registerIsCheck);
|
||||
}
|
||||
worldImpact.onCatchTypes.forEach(registerIsCheck);
|
||||
worldImpact.typeUses.forEach(registerTypeUse);
|
||||
worldImpact.closures.forEach(registerClosure);
|
||||
}
|
||||
|
||||
|
@ -640,7 +636,29 @@ abstract class Enqueuer {
|
|||
}
|
||||
}
|
||||
|
||||
void registerIsCheck(DartType type) {
|
||||
void registerTypeUse(TypeUse typeUse) {
|
||||
DartType type = typeUse.type;
|
||||
switch (typeUse.kind) {
|
||||
case TypeUseKind.INSTANTIATION:
|
||||
registerInstantiatedType(type);
|
||||
break;
|
||||
case TypeUseKind.INSTANTIATION:
|
||||
case TypeUseKind.IS_CHECK:
|
||||
case TypeUseKind.AS_CAST:
|
||||
case TypeUseKind.CATCH_TYPE:
|
||||
_registerIsCheck(type);
|
||||
break;
|
||||
case TypeUseKind.CHECKED_MODE_CHECK:
|
||||
if (compiler.enableTypeAssertions) {
|
||||
_registerIsCheck(type);
|
||||
}
|
||||
break;
|
||||
case TypeUseKind.TYPE_LITERAL:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void _registerIsCheck(DartType type) {
|
||||
type = universe.registerIsCheck(type, compiler);
|
||||
// Even in checked mode, type annotations for return type and argument
|
||||
// types do not imply type checks, so there should never be a check
|
||||
|
|
|
@ -2770,29 +2770,52 @@ class JavaScriptImpactTransformer extends ImpactTransformer {
|
|||
}
|
||||
}
|
||||
|
||||
for (InterfaceType type in worldImpact.instantiatedTypes) {
|
||||
registerRequiredType(type);
|
||||
}
|
||||
|
||||
for (DartType type in worldImpact.isChecks) {
|
||||
onIsCheck(type, transformed);
|
||||
}
|
||||
|
||||
if (worldImpact.asCasts.isNotEmpty) {
|
||||
for (DartType type in worldImpact.asCasts) {
|
||||
onIsCheck(type, transformed);
|
||||
bool hasAsCast = false;
|
||||
bool hasTypeLiteral = false;
|
||||
for (TypeUse typeUse in worldImpact.typeUses) {
|
||||
DartType type = typeUse.type;
|
||||
switch (typeUse.kind) {
|
||||
case TypeUseKind.INSTANTIATION:
|
||||
registerRequiredType(type);
|
||||
break;
|
||||
case TypeUseKind.IS_CHECK:
|
||||
onIsCheck(type, transformed);
|
||||
break;
|
||||
case TypeUseKind.AS_CAST:
|
||||
onIsCheck(type, transformed);
|
||||
hasAsCast = true;
|
||||
break;
|
||||
case TypeUseKind.CHECKED_MODE_CHECK:
|
||||
if (backend.compiler.enableTypeAssertions) {
|
||||
onIsCheck(type, transformed);
|
||||
}
|
||||
break;
|
||||
case TypeUseKind.CATCH_TYPE:
|
||||
onIsCheck(type, transformed);
|
||||
break;
|
||||
case TypeUseKind.TYPE_LITERAL:
|
||||
backend.customElementsAnalysis.registerTypeLiteral(type);
|
||||
if (type.isTypedef) {
|
||||
backend.compiler.world.allTypedefs.add(type.element);
|
||||
}
|
||||
if (type.isTypeVariable) {
|
||||
ClassElement cls = type.element.enclosingClass;
|
||||
backend.rti.registerClassUsingTypeVariableExpression(cls);
|
||||
registerBackendImpact(transformed, impacts.typeVariableExpression);
|
||||
}
|
||||
hasTypeLiteral = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasAsCast) {
|
||||
registerBackendImpact(transformed, impacts.asCheck);
|
||||
}
|
||||
|
||||
if (backend.compiler.enableTypeAssertions) {
|
||||
for (DartType type in worldImpact.checkedModeChecks) {
|
||||
onIsCheck(type, transformed);
|
||||
}
|
||||
}
|
||||
|
||||
for (DartType type in worldImpact.onCatchTypes) {
|
||||
onIsCheck(type, transformed);
|
||||
if (hasTypeLiteral) {
|
||||
transformed.registerTypeUse(new TypeUse.instantiation(
|
||||
backend.compiler.coreTypes.typeType));
|
||||
registerBackendImpact(transformed, impacts.typeLiteral);
|
||||
}
|
||||
|
||||
for (MapLiteralUse mapLiteralUse in worldImpact.mapLiterals) {
|
||||
|
@ -2801,7 +2824,8 @@ class JavaScriptImpactTransformer extends ImpactTransformer {
|
|||
if (mapLiteralUse.isConstant) {
|
||||
registerBackendImpact(transformed, impacts.constantMapLiteral);
|
||||
} else {
|
||||
transformed.registerInstantiatedType(mapLiteralUse.type);
|
||||
transformed.registerTypeUse(
|
||||
new TypeUse.instantiation(mapLiteralUse.type));
|
||||
}
|
||||
registerRequiredType(mapLiteralUse.type);
|
||||
}
|
||||
|
@ -2809,26 +2833,11 @@ class JavaScriptImpactTransformer extends ImpactTransformer {
|
|||
for (ListLiteralUse listLiteralUse in worldImpact.listLiterals) {
|
||||
// TODO(johnniwinther): Use the [isConstant] and [isEmpty] property when
|
||||
// factory constructors are registered directly.
|
||||
transformed.registerInstantiatedType(listLiteralUse.type);
|
||||
transformed.registerTypeUse(
|
||||
new TypeUse.instantiation(listLiteralUse.type));
|
||||
registerRequiredType(listLiteralUse.type);
|
||||
}
|
||||
|
||||
if (worldImpact.typeLiterals.isNotEmpty) {
|
||||
transformed.registerInstantiatedType(backend.compiler.coreTypes.typeType);
|
||||
registerBackendImpact(transformed, impacts.typeLiteral);
|
||||
for (DartType typeLiteral in worldImpact.typeLiterals) {
|
||||
backend.customElementsAnalysis.registerTypeLiteral(typeLiteral);
|
||||
if (typeLiteral.isTypedef) {
|
||||
backend.compiler.world.allTypedefs.add(typeLiteral.element);
|
||||
}
|
||||
if (typeLiteral.isTypeVariable) {
|
||||
ClassElement cls = typeLiteral.element.enclosingClass;
|
||||
backend.rti.registerClassUsingTypeVariableExpression(cls);
|
||||
registerBackendImpact(transformed, impacts.typeVariableExpression);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (worldImpact.constSymbolNames.isNotEmpty) {
|
||||
registerBackendImpact(transformed, impacts.constSymbol);
|
||||
for (String constSymbolName in worldImpact.constSymbolNames) {
|
||||
|
@ -2861,12 +2870,14 @@ class JavaScriptImpactTransformer extends ImpactTransformer {
|
|||
}
|
||||
for (InterfaceType instantiatedType in backendImpact.instantiatedTypes) {
|
||||
backend.registerBackendUse(instantiatedType.element);
|
||||
worldImpact.registerInstantiatedType(instantiatedType);
|
||||
worldImpact.registerTypeUse(
|
||||
new TypeUse.instantiation(instantiatedType));
|
||||
}
|
||||
for (ClassElement cls in backendImpact.instantiatedClasses) {
|
||||
cls.ensureResolved(backend.resolution);
|
||||
backend.registerBackendUse(cls);
|
||||
worldImpact.registerInstantiatedType(cls.rawType);
|
||||
worldImpact.registerTypeUse(
|
||||
new TypeUse.instantiation(cls.rawType));
|
||||
}
|
||||
for (BackendImpact otherImpact in backendImpact.otherImpacts) {
|
||||
registerBackendImpact(worldImpact, otherImpact);
|
||||
|
@ -2965,12 +2976,17 @@ class JavaScriptImpactTransformer extends ImpactTransformer {
|
|||
EagerRegistry registry = impact.registry;
|
||||
Enqueuer world = registry.world;
|
||||
|
||||
for (InterfaceType type in impact.instantiatedTypes) {
|
||||
backend.lookupMapAnalysis.registerInstantiatedType(type, registry);
|
||||
}
|
||||
|
||||
for (DartType type in impact.isChecks) {
|
||||
onIsCheckForCodegen(type, transformed);
|
||||
for (TypeUse typeUse in impact.typeUses) {
|
||||
DartType type = typeUse.type;
|
||||
switch (typeUse.kind) {
|
||||
case TypeUseKind.INSTANTIATION:
|
||||
backend.lookupMapAnalysis.registerInstantiatedType(type, registry);
|
||||
break;
|
||||
case TypeUseKind.IS_CHECK:
|
||||
onIsCheckForCodegen(type, transformed);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
for (ConstantValue constant in impact.compileTimeConstants) {
|
||||
|
|
|
@ -29,7 +29,8 @@ import '../../universe/selector.dart' show
|
|||
Selector;
|
||||
import '../../universe/use.dart' show
|
||||
DynamicUse,
|
||||
StaticUse;
|
||||
StaticUse,
|
||||
TypeUse;
|
||||
import '../../util/maplet.dart';
|
||||
|
||||
class CodegenBailout {
|
||||
|
@ -382,7 +383,7 @@ class CodeGenerator extends tree_ir.StatementVisitor
|
|||
List<js.Expression> typeArguments = visitExpressionList(node.typeArguments);
|
||||
DartType type = node.type;
|
||||
if (type is InterfaceType) {
|
||||
registry.registerIsCheck(type);
|
||||
registry.registerTypeUse(new TypeUse.isCheck(type));
|
||||
//glue.registerIsCheck(type, registry);
|
||||
ClassElement clazz = type.element;
|
||||
|
||||
|
@ -428,8 +429,7 @@ class CodeGenerator extends tree_ir.StatementVisitor
|
|||
function,
|
||||
<js.Expression>[value, isT, typeArgumentArray, asT]);
|
||||
} else if (type is TypeVariableType || type is FunctionType) {
|
||||
registry.registerIsCheck(type);
|
||||
//glue.registerIsCheck(type, registry);
|
||||
registry.registerTypeUse(new TypeUse.isCheck(type));
|
||||
|
||||
Element function = node.isTypeTest
|
||||
? glue.getCheckSubtypeOfRuntimeType()
|
||||
|
@ -450,7 +450,7 @@ class CodeGenerator extends tree_ir.StatementVisitor
|
|||
js.Expression object = visitExpression(node.object);
|
||||
DartType dartType = node.dartType;
|
||||
assert(dartType.isInterfaceType);
|
||||
registry.registerIsCheck(dartType);
|
||||
registry.registerTypeUse(new TypeUse.isCheck(dartType));
|
||||
//glue.registerIsCheck(dartType, registry);
|
||||
js.Expression property = glue.getTypeTestTag(dartType);
|
||||
return js.js(r'#.#', [object, property]);
|
||||
|
|
|
@ -87,7 +87,9 @@ import '../universe/selector.dart' show
|
|||
import '../universe/universe.dart';
|
||||
import '../universe/use.dart' show
|
||||
DynamicUse,
|
||||
StaticUse;
|
||||
StaticUse,
|
||||
TypeUse,
|
||||
TypeUseKind;
|
||||
import '../universe/world_impact.dart' show
|
||||
TransformedWorldImpact,
|
||||
WorldImpact;
|
||||
|
|
|
@ -39,7 +39,8 @@ import '../universe/selector.dart' show
|
|||
Selector;
|
||||
import '../universe/use.dart' show
|
||||
DynamicUse,
|
||||
StaticUse;
|
||||
StaticUse,
|
||||
TypeUse;
|
||||
|
||||
import 'access_semantics.dart';
|
||||
import 'class_members.dart' show MembersCreator;
|
||||
|
@ -401,7 +402,7 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
|||
TypeResult visitTypeAnnotation(TypeAnnotation node) {
|
||||
DartType type = resolveTypeAnnotation(node);
|
||||
if (inCheckContext) {
|
||||
registry.registerCheckedModeCheck(type);
|
||||
registry.registerTypeUse(new TypeUse.checkedModeCheck(type));
|
||||
}
|
||||
return new TypeResult(type);
|
||||
}
|
||||
|
@ -487,7 +488,7 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
|||
});
|
||||
if (inCheckContext) {
|
||||
functionParameters.forEachParameter((ParameterElement element) {
|
||||
registry.registerCheckedModeCheck(element.type);
|
||||
registry.registerTypeUse(new TypeUse.checkedModeCheck(element.type));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1162,7 +1163,7 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
|||
type = resolveTypeAnnotation(typeNode);
|
||||
sendStructure = new IsStructure(type);
|
||||
}
|
||||
registry.registerIsCheck(type);
|
||||
registry.registerTypeUse(new TypeUse.isCheck(type));
|
||||
registry.registerSendStructure(node, sendStructure);
|
||||
return const NoneResult();
|
||||
}
|
||||
|
@ -1174,7 +1175,7 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
|||
|
||||
Node typeNode = node.arguments.head;
|
||||
DartType type = resolveTypeAnnotation(typeNode);
|
||||
registry.registerAsCast(type);
|
||||
registry.registerTypeUse(new TypeUse.asCast(type));
|
||||
registry.registerSendStructure(node, new AsStructure(type));
|
||||
return const NoneResult();
|
||||
}
|
||||
|
@ -3558,28 +3559,32 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
|||
}
|
||||
|
||||
ConstantResult visitLiteralInt(LiteralInt node) {
|
||||
registry.registerInstantiatedType(coreTypes.intType);
|
||||
// TODO(johnniwinther): Make this a feature instead.
|
||||
registry.registerTypeUse(new TypeUse.instantiation(coreTypes.intType));
|
||||
ConstantExpression constant = new IntConstantExpression(node.value);
|
||||
registry.setConstant(node, constant);
|
||||
return new ConstantResult(node, constant);
|
||||
}
|
||||
|
||||
ConstantResult visitLiteralDouble(LiteralDouble node) {
|
||||
registry.registerInstantiatedType(coreTypes.doubleType);
|
||||
// TODO(johnniwinther): Make this a feature instead.
|
||||
registry.registerTypeUse(new TypeUse.instantiation(coreTypes.doubleType));
|
||||
ConstantExpression constant = new DoubleConstantExpression(node.value);
|
||||
registry.setConstant(node, constant);
|
||||
return new ConstantResult(node, constant);
|
||||
}
|
||||
|
||||
ConstantResult visitLiteralBool(LiteralBool node) {
|
||||
registry.registerInstantiatedType(coreTypes.boolType);
|
||||
// TODO(johnniwinther): Make this a feature instead.
|
||||
registry.registerTypeUse(new TypeUse.instantiation(coreTypes.boolType));
|
||||
ConstantExpression constant = new BoolConstantExpression(node.value);
|
||||
registry.setConstant(node, constant);
|
||||
return new ConstantResult(node, constant);
|
||||
}
|
||||
|
||||
ResolutionResult visitLiteralString(LiteralString node) {
|
||||
registry.registerInstantiatedType(coreTypes.stringType);
|
||||
// TODO(johnniwinther): Make this a feature instead.
|
||||
registry.registerTypeUse(new TypeUse.instantiation(coreTypes.stringType));
|
||||
if (node.dartString != null) {
|
||||
// [dartString] might be null on parser errors.
|
||||
ConstantExpression constant =
|
||||
|
@ -3591,13 +3596,14 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
|||
}
|
||||
|
||||
ConstantResult visitLiteralNull(LiteralNull node) {
|
||||
registry.registerInstantiatedType(coreTypes.nullType);
|
||||
registry.registerTypeUse(new TypeUse.instantiation(coreTypes.nullType));
|
||||
ConstantExpression constant = new NullConstantExpression();
|
||||
registry.setConstant(node, constant);
|
||||
return new ConstantResult(node, constant);
|
||||
}
|
||||
|
||||
ConstantResult visitLiteralSymbol(LiteralSymbol node) {
|
||||
// TODO(johnniwinther): Make this a feature instead.
|
||||
String name = node.slowNameString;
|
||||
registry.registerConstSymbol(name);
|
||||
if (!validateSymbol(node, name, reportError: false)) {
|
||||
|
@ -3613,7 +3619,8 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
|||
}
|
||||
|
||||
ResolutionResult visitStringJuxtaposition(StringJuxtaposition node) {
|
||||
registry.registerInstantiatedType(coreTypes.stringType);
|
||||
// TODO(johnniwinther): Make this a feature instead.
|
||||
registry.registerTypeUse(new TypeUse.instantiation(coreTypes.stringType));
|
||||
ResolutionResult first = visit(node.first);
|
||||
ResolutionResult second = visit(node.second);
|
||||
if (first.isConstant && second.isConstant) {
|
||||
|
@ -3747,10 +3754,11 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
|||
|
||||
registry.registerStaticUse(
|
||||
new StaticUse.constructorRedirect(redirectionTarget));
|
||||
// TODO(johnniwinther): Register the effective target type instead.
|
||||
registry.registerInstantiatedType(
|
||||
// TODO(johnniwinther): Register the effective target type as part of the
|
||||
// static use instead.
|
||||
registry.registerTypeUse(new TypeUse.instantiation(
|
||||
redirectionTarget.enclosingClass.thisType
|
||||
.subst(type.typeArguments, targetClass.typeVariables));
|
||||
.subst(type.typeArguments, targetClass.typeVariables)));
|
||||
if (isSymbolConstructor) {
|
||||
registry.registerSymbolConstructor();
|
||||
}
|
||||
|
@ -3911,7 +3919,7 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
|||
}
|
||||
// TODO(johniwinther): Avoid registration of `type` in face of redirecting
|
||||
// factory constructors.
|
||||
registry.registerInstantiatedType(type);
|
||||
registry.registerTypeUse(new TypeUse.instantiation(type));
|
||||
if (constructor.isGenerativeConstructor && cls.isAbstract) {
|
||||
isValidAsConstant = false;
|
||||
}
|
||||
|
@ -4064,7 +4072,7 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
|||
this, node, malformedIsError: malformedIsError,
|
||||
deferredIsMalformed: deferredIsMalformed);
|
||||
if (inCheckContext) {
|
||||
registry.registerCheckedModeCheck(type);
|
||||
registry.registerTypeUse(new TypeUse.checkedModeCheck(type));
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
@ -4156,7 +4164,9 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
|||
}
|
||||
|
||||
ResolutionResult visitStringInterpolation(StringInterpolation node) {
|
||||
registry.registerInstantiatedType(coreTypes.stringType);
|
||||
// TODO(johnniwinther): This should be a consequence of the registration
|
||||
// of [registerStringInterpolation].
|
||||
registry.registerTypeUse(new TypeUse.instantiation(coreTypes.stringType));
|
||||
registry.registerStringInterpolation();
|
||||
registerImplicitInvocation(Selectors.toString_);
|
||||
|
||||
|
@ -4742,7 +4752,7 @@ class ResolverVisitor extends MappingVisitor<ResolutionResult> {
|
|||
registry.getDefinition(exceptionVariable);
|
||||
exceptionElement.variables.type = exceptionType;
|
||||
}
|
||||
registry.registerOnCatchType(exceptionType);
|
||||
registry.registerTypeUse(new TypeUse.catchType(exceptionType));
|
||||
}
|
||||
if (stackTraceDefinition != null) {
|
||||
Node stackTraceVariable = stackTraceDefinition.definitions.nodes.head;
|
||||
|
|
|
@ -31,7 +31,8 @@ import '../universe/selector.dart' show
|
|||
Selector;
|
||||
import '../universe/use.dart' show
|
||||
DynamicUse,
|
||||
StaticUse;
|
||||
StaticUse,
|
||||
TypeUse;
|
||||
import '../universe/world_impact.dart' show
|
||||
WorldImpactBuilder;
|
||||
import '../world.dart' show World;
|
||||
|
@ -315,24 +316,9 @@ class ResolutionRegistry extends Registry {
|
|||
worldImpact.registerFeature(Feature.THROW_NO_SUCH_METHOD);
|
||||
}
|
||||
|
||||
/// Register a checked mode check against [type].
|
||||
void registerCheckedModeCheck(DartType type) {
|
||||
worldImpact.registerCheckedModeCheckedType(type);
|
||||
}
|
||||
|
||||
/// Register an on-catch clause of [type].
|
||||
void registerOnCatchType(DartType type) {
|
||||
worldImpact.registerOnCatchType(type);
|
||||
}
|
||||
|
||||
/// Register an is-test or is-not-test of [type].
|
||||
void registerIsCheck(DartType type) {
|
||||
worldImpact.registerIsCheck(type);
|
||||
}
|
||||
|
||||
/// Register an as-cast of [type].
|
||||
void registerAsCast(DartType type) {
|
||||
worldImpact.registerAsCast(type);
|
||||
/// Register the use of a type.
|
||||
void registerTypeUse(TypeUse typeUse) {
|
||||
worldImpact.registerTypeUse(typeUse);
|
||||
}
|
||||
|
||||
void registerClosure(LocalFunctionElement element) {
|
||||
|
@ -349,7 +335,7 @@ class ResolutionRegistry extends Registry {
|
|||
|
||||
void registerTypeLiteral(Send node, DartType type) {
|
||||
mapping.setType(node, type);
|
||||
worldImpact.registerTypeLiteral(type);
|
||||
worldImpact.registerTypeUse(new TypeUse.typeLiteral(type));
|
||||
}
|
||||
|
||||
void registerLiteralList(Node node,
|
||||
|
@ -391,10 +377,6 @@ class ResolutionRegistry extends Registry {
|
|||
worldImpact.registerFeature(Feature.SYMBOL_CONSTRUCTOR);
|
||||
}
|
||||
|
||||
void registerInstantiatedType(InterfaceType type) {
|
||||
worldImpact.registerInstantiatedType(type);
|
||||
}
|
||||
|
||||
void registerAbstractClassInstantiation() {
|
||||
worldImpact.registerFeature(Feature.ABSTRACT_CLASS_INSTANTIATION);
|
||||
}
|
||||
|
@ -433,7 +415,7 @@ class ResolutionRegistry extends Registry {
|
|||
}
|
||||
|
||||
void registerInstantiation(InterfaceType type) {
|
||||
registerInstantiatedType(type);
|
||||
worldImpact.registerTypeUse(new TypeUse.instantiation(type));
|
||||
}
|
||||
|
||||
void registerAssert(bool hasMessage) {
|
||||
|
@ -493,7 +475,7 @@ class ForeignResolutionResolver implements ForeignResolver {
|
|||
|
||||
@override
|
||||
void registerInstantiatedType(InterfaceType type) {
|
||||
registry.registerInstantiatedType(type);
|
||||
registry.registerInstantiation(type);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -49,7 +49,8 @@ import '../tree/tree.dart';
|
|||
import '../universe/call_structure.dart' show
|
||||
CallStructure;
|
||||
import '../universe/use.dart' show
|
||||
StaticUse;
|
||||
StaticUse,
|
||||
TypeUse;
|
||||
import '../universe/world_impact.dart' show
|
||||
WorldImpact;
|
||||
import '../util/util.dart' show
|
||||
|
@ -377,7 +378,8 @@ class ResolverTask extends CompilerTask {
|
|||
reporter.reportErrorMessage(
|
||||
element, MessageKind.FINAL_WITHOUT_INITIALIZER);
|
||||
} else {
|
||||
registry.registerInstantiatedType(coreTypes.nullType);
|
||||
// TODO(johnniwinther): Register a feature instead.
|
||||
registry.registerTypeUse(new TypeUse.instantiation(coreTypes.nullType));
|
||||
}
|
||||
|
||||
if (Elements.isStaticOrTopLevelField(element)) {
|
||||
|
|
|
@ -18,6 +18,8 @@ import '../elements/modelx.dart' show
|
|||
InitializingFormalElementX,
|
||||
LocalParameterElementX;
|
||||
import '../tree/tree.dart';
|
||||
import '../universe/use.dart' show
|
||||
TypeUse;
|
||||
import '../util/util.dart' show
|
||||
Link,
|
||||
LinkBuilder;
|
||||
|
@ -341,7 +343,7 @@ class SignatureResolver extends MappingVisitor<FormalElementX> {
|
|||
// Because there is no type annotation for the return type of
|
||||
// this element, we explicitly add one.
|
||||
if (compiler.enableTypeAssertions) {
|
||||
registry.registerIsCheck(returnType);
|
||||
registry.registerTypeUse(new TypeUse.checkedModeCheck(returnType));
|
||||
}
|
||||
} else {
|
||||
AsyncMarker asyncMarker = AsyncMarker.SYNC;
|
||||
|
|
|
@ -11,6 +11,8 @@ import '../elements/modelx.dart' show
|
|||
LocalVariableElementX,
|
||||
VariableList;
|
||||
import '../tree/tree.dart';
|
||||
import '../universe/use.dart' show
|
||||
TypeUse;
|
||||
import '../util/util.dart' show
|
||||
Link;
|
||||
|
||||
|
@ -54,7 +56,9 @@ class VariableDefinitionsVisitor extends CommonResolverVisitor<Identifier> {
|
|||
|
||||
Identifier visitIdentifier(Identifier node) {
|
||||
// The variable is initialized to null.
|
||||
registry.registerInstantiatedType(compiler.coreTypes.nullType);
|
||||
// TODO(johnniwinther): Register a feature instead.
|
||||
registry.registerTypeUse(
|
||||
new TypeUse.instantiation(compiler.coreTypes.nullType));
|
||||
if (definitions.modifiers.isConst) {
|
||||
reporter.reportErrorMessage(
|
||||
node, MessageKind.CONST_WITHOUT_INITIALIZER);
|
||||
|
|
|
@ -2590,7 +2590,7 @@ class SsaBuilder extends ast.Visitor
|
|||
assert(type != null);
|
||||
type = localsHandler.substInContext(type);
|
||||
HInstruction other = buildTypeConversion(original, type, kind);
|
||||
registry?.registerIsCheck(type);
|
||||
registry?.registerTypeUse(new TypeUse.isCheck(type));
|
||||
return other;
|
||||
}
|
||||
|
||||
|
|
|
@ -2502,7 +2502,7 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
|
|||
void checkTypeViaProperty(HInstruction input, DartType type,
|
||||
SourceInformation sourceInformation,
|
||||
{bool negative: false}) {
|
||||
registry.registerIsCheck(type);
|
||||
registry.registerTypeUse(new TypeUse.isCheck(type));
|
||||
|
||||
use(input);
|
||||
|
||||
|
@ -2523,7 +2523,7 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
|
|||
HInstruction input, DartType type,
|
||||
SourceInformation sourceInformation,
|
||||
{bool negative: false}) {
|
||||
registry.registerIsCheck(type);
|
||||
registry.registerTypeUse(new TypeUse.isCheck(type));
|
||||
|
||||
use(input);
|
||||
|
||||
|
@ -2615,7 +2615,7 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
|
|||
|
||||
void emitIs(HIs node, String relation, SourceInformation sourceInformation) {
|
||||
DartType type = node.typeExpression;
|
||||
registry.registerIsCheck(type);
|
||||
registry.registerTypeUse(new TypeUse.isCheck(type));
|
||||
HInstruction input = node.expression;
|
||||
|
||||
// If this is changed to single == there are several places below that must
|
||||
|
@ -2787,9 +2787,10 @@ class SsaCodeGenerator implements HVisitor, HBlockInformationVisitor {
|
|||
if (type.isFunctionType) {
|
||||
// TODO(5022): We currently generate $isFunction checks for
|
||||
// function types.
|
||||
registry.registerIsCheck(compiler.coreTypes.functionType);
|
||||
registry.registerTypeUse(
|
||||
new TypeUse.isCheck(compiler.coreTypes.functionType));
|
||||
}
|
||||
registry.registerIsCheck(type);
|
||||
registry.registerTypeUse(new TypeUse.isCheck(type));
|
||||
|
||||
CheckedModeHelper helper;
|
||||
if (node.isBooleanConversionCheck) {
|
||||
|
|
|
@ -62,7 +62,8 @@ import '../universe/side_effects.dart' show
|
|||
SideEffects;
|
||||
import '../universe/use.dart' show
|
||||
DynamicUse,
|
||||
StaticUse;
|
||||
StaticUse,
|
||||
TypeUse;
|
||||
import '../util/util.dart';
|
||||
import '../world.dart' show
|
||||
ClassWorld,
|
||||
|
|
|
@ -10,6 +10,7 @@ library dart2js.universe.use;
|
|||
import '../closure.dart' show
|
||||
BoxFieldElement;
|
||||
import '../common.dart';
|
||||
import '../dart_types.dart';
|
||||
import '../elements/elements.dart';
|
||||
import '../world.dart' show
|
||||
ClassWorld;
|
||||
|
@ -247,3 +248,62 @@ class StaticUse {
|
|||
String toString() => 'StaticUse($element,$kind)';
|
||||
}
|
||||
|
||||
enum TypeUseKind {
|
||||
IS_CHECK,
|
||||
AS_CAST,
|
||||
CHECKED_MODE_CHECK,
|
||||
CATCH_TYPE,
|
||||
TYPE_LITERAL,
|
||||
INSTANTIATION,
|
||||
}
|
||||
|
||||
/// Use of a [DartType].
|
||||
class TypeUse {
|
||||
final DartType type;
|
||||
final TypeUseKind kind;
|
||||
final int hashCode;
|
||||
|
||||
TypeUse._(DartType type, TypeUseKind kind)
|
||||
: this.type = type,
|
||||
this.kind = kind,
|
||||
this.hashCode = Hashing.objectHash(type, Hashing.objectHash(kind));
|
||||
|
||||
/// [type] used in an is check, like `e is T` or `e is! T`.
|
||||
factory TypeUse.isCheck(DartType type) {
|
||||
return new TypeUse._(type, TypeUseKind.IS_CHECK);
|
||||
}
|
||||
|
||||
/// [type] used in an as cast, like `e as T`.
|
||||
factory TypeUse.asCast(DartType type) {
|
||||
return new TypeUse._(type, TypeUseKind.AS_CAST);
|
||||
}
|
||||
|
||||
/// [type] used as a type annotation, like `T foo;`.
|
||||
factory TypeUse.checkedModeCheck(DartType type) {
|
||||
return new TypeUse._(type, TypeUseKind.CHECKED_MODE_CHECK);
|
||||
}
|
||||
|
||||
/// [type] used in a on type catch clause, like `try {} on T catch (e) {}`.
|
||||
factory TypeUse.catchType(DartType type) {
|
||||
return new TypeUse._(type, TypeUseKind.CATCH_TYPE);
|
||||
}
|
||||
|
||||
/// [type] used as a type literal, like `foo() => T;`.
|
||||
factory TypeUse.typeLiteral(DartType type) {
|
||||
return new TypeUse._(type, TypeUseKind.TYPE_LITERAL);
|
||||
}
|
||||
|
||||
/// [type] used in an instantiation, like `new T();`.
|
||||
factory TypeUse.instantiation(InterfaceType type) {
|
||||
return new TypeUse._(type, TypeUseKind.INSTANTIATION);
|
||||
}
|
||||
|
||||
bool operator ==(other) {
|
||||
if (identical(this, other)) return true;
|
||||
if (other is! TypeUse) return false;
|
||||
return type == other.type &&
|
||||
kind == other.kind;
|
||||
}
|
||||
|
||||
String toString() => 'TypeUse($type,$kind)';
|
||||
}
|
|
@ -16,7 +16,8 @@ import '../util/util.dart' show
|
|||
|
||||
import 'use.dart' show
|
||||
DynamicUse,
|
||||
StaticUse;
|
||||
StaticUse,
|
||||
TypeUse;
|
||||
|
||||
class WorldImpact {
|
||||
const WorldImpact();
|
||||
|
@ -28,22 +29,13 @@ class WorldImpact {
|
|||
|
||||
// TODO(johnniwinther): Replace this by called constructors with type
|
||||
// arguments.
|
||||
Iterable<InterfaceType> get instantiatedTypes => const <InterfaceType>[];
|
||||
// TODO(johnniwinther): Collect all checked types for checked mode separately
|
||||
// to support serialization.
|
||||
|
||||
// TODO(johnniwinther): Collect checked types for checked mode separately to
|
||||
// support serialization.
|
||||
Iterable<DartType> get isChecks => const <DartType>[];
|
||||
|
||||
Iterable<DartType> get checkedModeChecks => const <DartType>[];
|
||||
|
||||
Iterable<DartType> get asCasts => const <DartType>[];
|
||||
|
||||
Iterable<DartType> get onCatchTypes => const <DartType>[];
|
||||
Iterable<TypeUse> get typeUses => const <TypeUse>[];
|
||||
|
||||
Iterable<LocalFunctionElement> get closures => const <LocalFunctionElement>[];
|
||||
|
||||
Iterable<DartType> get typeLiterals => const <DartType>[];
|
||||
|
||||
String toString() => dump(this);
|
||||
|
||||
static String dump(WorldImpact worldImpact) {
|
||||
|
@ -62,13 +54,8 @@ class WorldImpact {
|
|||
|
||||
add('dynamic uses', worldImpact.dynamicUses);
|
||||
add('static uses', worldImpact.staticUses);
|
||||
add('instantiated types', worldImpact.instantiatedTypes);
|
||||
add('is-checks', worldImpact.isChecks);
|
||||
add('checked-mode checks', worldImpact.checkedModeChecks);
|
||||
add('as-casts', worldImpact.asCasts);
|
||||
add('on-catch-types', worldImpact.onCatchTypes);
|
||||
add('type uses', worldImpact.typeUses);
|
||||
add('closures', worldImpact.closures);
|
||||
add('type literals', worldImpact.typeLiterals);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,14 +63,9 @@ class WorldImpactBuilder {
|
|||
// TODO(johnniwinther): Do we benefit from lazy initialization of the
|
||||
// [Setlet]s?
|
||||
Setlet<DynamicUse> _dynamicUses;
|
||||
Setlet<InterfaceType> _instantiatedTypes;
|
||||
Setlet<StaticUse> _staticUses;
|
||||
Setlet<DartType> _isChecks;
|
||||
Setlet<DartType> _asCasts;
|
||||
Setlet<DartType> _checkedModeChecks;
|
||||
Setlet<DartType> _onCatchTypes;
|
||||
Setlet<TypeUse> _typeUses;
|
||||
Setlet<LocalFunctionElement> _closures;
|
||||
Setlet<DartType> _typeLiterals;
|
||||
|
||||
void registerDynamicUse(DynamicUse dynamicUse) {
|
||||
assert(dynamicUse != null);
|
||||
|
@ -98,30 +80,17 @@ class WorldImpactBuilder {
|
|||
? _dynamicUses : const <DynamicUse>[];
|
||||
}
|
||||
|
||||
void registerInstantiatedType(InterfaceType type) {
|
||||
assert(type != null);
|
||||
if (_instantiatedTypes == null) {
|
||||
_instantiatedTypes = new Setlet<InterfaceType>();
|
||||
void registerTypeUse(TypeUse typeUse) {
|
||||
assert(typeUse != null);
|
||||
if (_typeUses == null) {
|
||||
_typeUses = new Setlet<TypeUse>();
|
||||
}
|
||||
_instantiatedTypes.add(type);
|
||||
_typeUses.add(typeUse);
|
||||
}
|
||||
|
||||
Iterable<InterfaceType> get instantiatedTypes {
|
||||
return _instantiatedTypes != null
|
||||
? _instantiatedTypes : const <InterfaceType>[];
|
||||
}
|
||||
|
||||
void registerTypeLiteral(DartType type) {
|
||||
assert(type != null);
|
||||
if (_typeLiterals == null) {
|
||||
_typeLiterals = new Setlet<DartType>();
|
||||
}
|
||||
_typeLiterals.add(type);
|
||||
}
|
||||
|
||||
Iterable<DartType> get typeLiterals {
|
||||
return _typeLiterals != null
|
||||
? _typeLiterals : const <DartType>[];
|
||||
Iterable<TypeUse> get typeUses {
|
||||
return _typeUses != null
|
||||
? _typeUses : const <TypeUse>[];
|
||||
}
|
||||
|
||||
void registerStaticUse(StaticUse staticUse) {
|
||||
|
@ -136,56 +105,6 @@ class WorldImpactBuilder {
|
|||
return _staticUses != null ? _staticUses : const <StaticUse>[];
|
||||
}
|
||||
|
||||
void registerIsCheck(DartType type) {
|
||||
assert(type != null);
|
||||
if (_isChecks == null) {
|
||||
_isChecks = new Setlet<DartType>();
|
||||
}
|
||||
_isChecks.add(type);
|
||||
}
|
||||
|
||||
Iterable<DartType> get isChecks {
|
||||
return _isChecks != null
|
||||
? _isChecks : const <DartType>[];
|
||||
}
|
||||
|
||||
void registerAsCast(DartType type) {
|
||||
if (_asCasts == null) {
|
||||
_asCasts = new Setlet<DartType>();
|
||||
}
|
||||
_asCasts.add(type);
|
||||
}
|
||||
|
||||
Iterable<DartType> get asCasts {
|
||||
return _asCasts != null
|
||||
? _asCasts : const <DartType>[];
|
||||
}
|
||||
|
||||
void registerCheckedModeCheckedType(DartType type) {
|
||||
if (_checkedModeChecks == null) {
|
||||
_checkedModeChecks = new Setlet<DartType>();
|
||||
}
|
||||
_checkedModeChecks.add(type);
|
||||
}
|
||||
|
||||
Iterable<DartType> get checkedModeChecks {
|
||||
return _checkedModeChecks != null
|
||||
? _checkedModeChecks : const <DartType>[];
|
||||
}
|
||||
|
||||
void registerOnCatchType(DartType type) {
|
||||
assert(type != null);
|
||||
if (_onCatchTypes == null) {
|
||||
_onCatchTypes = new Setlet<DartType>();
|
||||
}
|
||||
_onCatchTypes.add(type);
|
||||
}
|
||||
|
||||
Iterable<DartType> get onCatchTypes {
|
||||
return _onCatchTypes != null
|
||||
? _onCatchTypes : const <DartType>[];
|
||||
}
|
||||
|
||||
void registerClosure(LocalFunctionElement element) {
|
||||
if (_closures == null) {
|
||||
_closures = new Setlet<LocalFunctionElement>();
|
||||
|
@ -205,31 +124,17 @@ class TransformedWorldImpact implements WorldImpact {
|
|||
final WorldImpact worldImpact;
|
||||
|
||||
Setlet<StaticUse> _staticUses;
|
||||
Setlet<InterfaceType> _instantiatedTypes;
|
||||
Setlet<TypeUse> _typeUses;
|
||||
Setlet<DynamicUse> _dynamicUses;
|
||||
|
||||
TransformedWorldImpact(this.worldImpact);
|
||||
|
||||
@override
|
||||
Iterable<DartType> get asCasts => worldImpact.asCasts;
|
||||
|
||||
@override
|
||||
Iterable<DartType> get checkedModeChecks => worldImpact.checkedModeChecks;
|
||||
|
||||
@override
|
||||
Iterable<DynamicUse> get dynamicUses {
|
||||
return _dynamicUses != null
|
||||
? _dynamicUses : worldImpact.dynamicUses;
|
||||
}
|
||||
|
||||
@override
|
||||
Iterable<DartType> get isChecks => worldImpact.isChecks;
|
||||
|
||||
@override
|
||||
Iterable<DartType> get onCatchTypes => worldImpact.onCatchTypes;
|
||||
|
||||
_unsupported(String message) => throw new UnsupportedError(message);
|
||||
|
||||
void registerDynamicUse(DynamicUse dynamicUse) {
|
||||
if (_dynamicUses == null) {
|
||||
_dynamicUses = new Setlet<DynamicUse>();
|
||||
|
@ -238,23 +143,18 @@ class TransformedWorldImpact implements WorldImpact {
|
|||
_dynamicUses.add(dynamicUse);
|
||||
}
|
||||
|
||||
void registerInstantiatedType(InterfaceType type) {
|
||||
if (_instantiatedTypes == null) {
|
||||
_instantiatedTypes = new Setlet<InterfaceType>();
|
||||
_instantiatedTypes.addAll(worldImpact.instantiatedTypes);
|
||||
void registerTypeUse(TypeUse typeUse) {
|
||||
if (_typeUses == null) {
|
||||
_typeUses = new Setlet<TypeUse>();
|
||||
_typeUses.addAll(worldImpact.typeUses);
|
||||
}
|
||||
_instantiatedTypes.add(type);
|
||||
_typeUses.add(typeUse);
|
||||
}
|
||||
|
||||
@override
|
||||
Iterable<InterfaceType> get instantiatedTypes {
|
||||
return _instantiatedTypes != null
|
||||
? _instantiatedTypes : worldImpact.instantiatedTypes;
|
||||
}
|
||||
|
||||
@override
|
||||
Iterable<DartType> get typeLiterals {
|
||||
return worldImpact.typeLiterals;
|
||||
Iterable<TypeUse> get typeUses {
|
||||
return _typeUses != null
|
||||
? _typeUses : worldImpact.typeUses;
|
||||
}
|
||||
|
||||
void registerStaticUse(StaticUse staticUse) {
|
||||
|
|
Loading…
Reference in a new issue