diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart index 8ea98e335a3..b5a458c26db 100644 --- a/pkg/compiler/lib/src/ssa/builder_kernel.dart +++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart @@ -9,7 +9,12 @@ import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; import '../common/names.dart'; import '../common/tasks.dart' show CompilerTask; import '../compiler.dart'; -import '../constants/values.dart' show StringConstantValue; +import '../constants/values.dart' + show + ConstantValue, + InterceptorConstantValue, + StringConstantValue, + TypeConstantValue; import '../dart_types.dart'; import '../elements/elements.dart'; import '../io/source_information.dart'; @@ -867,6 +872,24 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder { mapEntry.key.accept(this); } + @override + void visitTypeLiteral(ir.TypeLiteral typeLiteral) { + ir.DartType type = typeLiteral.type; + if (type is ir.InterfaceType) { + ConstantValue constant = astAdapter.getConstantForType(type); + stack.add(graph.addConstant(constant, compiler)); + return; + } + if (type is ir.TypeParameterType) { + // TODO(27394): Load type parameter from current 'this' object. + defaultExpression(typeLiteral); + return; + } + // TODO(27394): 'dynamic' and function types observed. Where are they from? + defaultExpression(typeLiteral); + return; + } + @override void visitStaticGet(ir.StaticGet staticGet) { ir.Member staticTarget = staticGet.target; @@ -1311,7 +1334,30 @@ class KernelSsaBuilder extends ir.Visitor with GraphBuilder { } void handleJsInterceptorConstant(ir.StaticInvocation invocation) { - unhandledForeign(invocation); + // Single argument must be a TypeConstant which is converted into a + // InterceptorConstant. + if (_unexpectedForeignArguments(invocation, 1, 1)) { + stack.add(graph.addConstantNull(compiler)); // Result expected on stack. + return; + } + ir.Expression argument = invocation.arguments.positional.single; + argument.accept(this); + HInstruction argumentInstruction = pop(); + if (argumentInstruction is HConstant) { + ConstantValue argumentConstant = argumentInstruction.constant; + if (argumentConstant is TypeConstantValue) { + // TODO(sra): Check that type is a subclass of [Interceptor]. + ConstantValue constant = + new InterceptorConstantValue(argumentConstant.representedType); + HInstruction instruction = graph.addConstant(constant, compiler); + stack.add(instruction); + return; + } + } + + compiler.reporter.reportErrorMessage(astAdapter.getNode(invocation), + MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); + stack.add(graph.addConstantNull(compiler)); } void handleForeignJs(ir.StaticInvocation invocation) { diff --git a/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart b/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart index 028b7a8f294..5f89b8e73d1 100644 --- a/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart +++ b/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart @@ -255,6 +255,11 @@ class KernelAstAdapter { return constantValue; } + ConstantValue getConstantForType(ir.DartType irType) { + DartType type = getDartType(irType); + return _backend.constantSystem.createType(_compiler, type.asRaw()); + } + bool isIntercepted(ir.Node node) { Selector selector = getSelector(node); return _backend.isInterceptedSelector(selector);