Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(433)

Unified Diff: pkg/compiler/lib/src/inferrer/builder_kernel.dart

Issue 2746293006: Pulling the element model out of global type inference. (Closed)
Patch Set: . Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/dart2js.dart ('k') | pkg/compiler/lib/src/inferrer/inferrer_engine.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/inferrer/builder_kernel.dart
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
new file mode 100644
index 0000000000000000000000000000000000000000..7c10b3685893c6d4ade47de2d726d2e6691402cf
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -0,0 +1,172 @@
+// Copyright (c) 2017, 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.
+
+import 'package:kernel/ast.dart' as ir;
+
+import '../closure.dart';
+import '../compiler.dart';
+import '../elements/elements.dart';
+import '../elements/entities.dart';
+import '../kernel/kernel.dart';
+import '../ssa/kernel_ast_adapter.dart';
+import '../tree/tree.dart' as ast;
+import '../types/types.dart' show TypeMask;
+import '../universe/side_effects.dart' show SideEffects;
+import 'inferrer_engine.dart';
+import 'locals_handler.dart';
+import 'type_graph_nodes.dart';
+import 'type_system.dart';
+
+/// [KernelTypeGraphBuilder] constructs a type-inference graph for a particular
+/// element.
+///
+/// Calling [run] will start the work of visiting the body of the code to
+/// construct a set of inference-nodes that abstractly represent what the code
+/// is doing.
+class KernelTypeGraphBuilder extends ir.Visitor<TypeInformation> {
+ final Compiler compiler;
+ final AstElement originalElement;
+ // TODO(efortuna): Remove this.
+ final Element outermostElement;
+ final ir.Node analyzedNode;
+ final ResolvedAst resolvedAst;
+ final TypeSystem types;
+ LocalsHandler locals;
+ final InferrerEngine inferrer;
+ SideEffects sideEffects = new SideEffects.empty();
+ int loopLevel = 0;
+ bool get inLoop => loopLevel > 0;
+
+ final Set<Entity> capturedVariables = new Set<Entity>();
+
+ final KernelAstAdapter astAdapter;
+
+ KernelTypeGraphBuilder.internal(
+ this.originalElement,
+ this.resolvedAst,
+ this.outermostElement,
+ this.inferrer,
+ this.compiler,
+ this.locals,
+ this.astAdapter,
+ this.analyzedNode)
+ : this.types = inferrer.types {
+ if (locals != null) return;
+
+ ast.Node node;
+ if (resolvedAst.kind == ResolvedAstKind.PARSED) {
+ node = resolvedAst.node;
+ }
+ FieldInitializationScope fieldScope = (analyzedNode is ir.Constructor)
+ ? new FieldInitializationScope(types)
+ : null;
+ locals =
+ new LocalsHandler(inferrer, types, compiler.options, node, fieldScope);
+ }
+
+ factory KernelTypeGraphBuilder(Element element, ResolvedAst resolvedAst,
+ Compiler compiler, InferrerEngine inferrer,
+ [LocalsHandler handler]) {
+ var adapter = _createKernelAdapter(compiler, resolvedAst);
+ var node = adapter.getInitialKernelNode(element);
+ return new KernelTypeGraphBuilder.internal(
+ element,
+ resolvedAst,
+ element.outermostEnclosingMemberOrTopLevel.implementation,
+ inferrer,
+ compiler,
+ handler,
+ adapter,
+ node);
+ }
+
+ static KernelAstAdapter _createKernelAdapter(
+ Compiler compiler, ResolvedAst resolvedAst) {
+ Kernel kernel = compiler.backend.kernelTask.kernel;
+ return new KernelAstAdapter(kernel, compiler.backend, resolvedAst,
+ kernel.nodeToAst, kernel.nodeToElement);
+ }
+
+ TypeInformation run() {
+ ir.Expression initializer;
+ if (analyzedNode is ir.Field) {
+ ir.Field field = analyzedNode;
+ initializer = field.initializer;
+ if (initializer == null || initializer is ir.NullLiteral) {
+ // Eagerly bailout, because computing the closure data only
+ // works for functions and field assignments.
+ return types.nullType;
+ }
+ }
+
+ // Update the locals that are boxed in [locals]. These locals will
+ // be handled specially, in that we are computing their LUB at
+ // each update, and reading them yields the type that was found in a
+ // previous analysis of [outermostElement].
+ ClosureClassMap closureData =
+ compiler.closureToClassMapper.getClosureToClassMapping(resolvedAst);
+ closureData.forEachCapturedVariable((variable, field) {
+ locals.setCaptured(variable, field);
+ });
+ closureData.forEachBoxedVariable((variable, field) {
+ locals.setCapturedAndBoxed(variable, field);
+ });
+
+ if (analyzedNode is ir.Field) {
+ return initializer.accept(this);
+ }
+ return _processFunctionNode(analyzedNode);
+ }
+
+ TypeInformation _processFunctionNode(ir.FunctionNode funcNode) {
+ // TODO(efortuna): Implement.
+ return types.dynamicType;
+ }
+
+ @override
+ TypeInformation defaultExpression(ir.Expression expression) {
+ // TODO(efortuna): Remove when more is implemented.
+ return types.dynamicType;
+ }
+
+ @override
+ TypeInformation visitNullLiteral(ir.NullLiteral literal) {
+ return types.nullType;
+ }
+
+ @override
+ TypeInformation visitBlock(ir.Block block) {
+ for (ir.Statement statement in block.statements) {
+ statement.accept(this);
+ if (locals.aborts) break;
+ }
+ return null;
+ }
+
+ @override
+ TypeInformation visitListLiteral(ir.ListLiteral listLiteral) {
+ // We only set the type once. We don't need to re-visit the children
+ // when re-analyzing the node.
+ return inferrer.concreteKernelTypes.putIfAbsent(listLiteral, () {
+ TypeInformation elementType;
+ int length = 0;
+ for (ir.Expression element in listLiteral.expressions) {
+ TypeInformation type = element.accept(this);
+ elementType = elementType == null
+ ? types.allocatePhi(null, null, type)
+ : types.addPhiInput(null, elementType, type);
+ length++;
+ }
+ elementType = elementType == null
+ ? types.nonNullEmpty()
+ : types.simplifyPhi(null, null, elementType);
+ TypeInformation containerType =
+ listLiteral.isConst ? types.constListType : types.growableListType;
+ // TODO(efortuna): Change signature of allocateList and the rest of
+ // type_system to deal with Kernel elements.
+ return types.allocateList(containerType, astAdapter.getNode(listLiteral),
+ outermostElement, elementType, length);
+ });
+ }
+}
« no previous file with comments | « pkg/compiler/lib/src/dart2js.dart ('k') | pkg/compiler/lib/src/inferrer/inferrer_engine.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698