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

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
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..06f9b5e3e0e01d76d1138df417829b147baf5844
--- /dev/null
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -0,0 +1,160 @@
+// 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] can be thought of as a type-inference graph
Siggi Cherem (dart-lang) 2017/03/16 00:37:44 BTW - we should be able to update these comments a
Emily Fortuna 2017/03/17 01:03:02 Done.
+/// builder for a single element.
+///
+/// Calling [run] will start the work of visiting the body of the code to
+/// construct a set of infernece-nodes that abstractly represent what the code
+/// is doing.
+///
+/// This visitor is parameterized by an [InferenceEngine], which internally
Siggi Cherem (dart-lang) 2017/03/16 00:37:44 similarly note the engine parameter is now gone (J
Emily Fortuna 2017/03/17 01:03:01 Done.
+/// decides how to represent inference nodes.
+class KernelTypeGraphBuilder extends ir.Visitor<TypeInformation> {
+ final Compiler compiler;
+ final AstElement originalElement;
+ // TODO(efortuna): Remove this.
+ final Element outermostElement;
+ ir.Node analyzedNode;
+ final ResolvedAst resolvedAst;
+ final TypeSystem types;
+ LocalsHandler locals;
+ final InferrerEngine inferrer;
+ SideEffects sideEffects = new SideEffects.empty();
+ int loopLevel = 0;
+ final Set<Entity> capturedVariables = new Set<Entity>();
+
+ KernelAstAdapter astAdapter;
+
+ bool get inLoop => loopLevel > 0;
Siggi Cherem (dart-lang) 2017/03/16 00:37:44 nit: I'd move htis up next to loopLevel (it mixes
Emily Fortuna 2017/03/17 01:03:02 Done.
+
+ KernelTypeGraphBuilder.internal(this.originalElement, this.resolvedAst,
+ this.outermostElement, this.inferrer, this.compiler, this.locals)
+ : this.types = inferrer.types {
+ if (locals != null) return;
+
+ Kernel kernel = compiler.backend.kernelTask.kernel;
+ this.astAdapter = new KernelAstAdapter(kernel, compiler.backend,
Siggi Cherem (dart-lang) 2017/03/16 00:37:45 it might not be worth making this change because t
Emily Fortuna 2017/03/17 01:03:02 Done.
+ resolvedAst, kernel.nodeToAst, kernel.nodeToElement);
+
+ analyzedNode = astAdapter.getInitialKernelNode(originalElement);
Siggi Cherem (dart-lang) 2017/03/16 00:37:44 will analyzerNode ever change? If not, then maybe
Emily Fortuna 2017/03/17 01:03:02 Done.
+
+ ast.Node node;
Siggi Cherem (dart-lang) 2017/03/16 00:37:45 I'm guessing the idea is this will be replaced by
Emily Fortuna 2017/03/17 01:03:01 yep. The list of things to do grows very quickly!
+ 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);
+ }
+
+ KernelTypeGraphBuilder(Element element, ResolvedAst resolvedAst,
+ Compiler compiler, InferrerEngine inferrer, [LocalsHandler handler])
+ : this.internal(
+ element,
+ resolvedAst,
+ element.outermostEnclosingMemberOrTopLevel.implementation,
+ inferrer,
+ compiler,
+ handler);
+
+ TypeInformation run() {
+ ir.Expression initializer;
+ if (analyzedNode is ir.Field) {
+ initializer = (analyzedNode as ir.Field).initializer;
Siggi Cherem (dart-lang) 2017/03/16 00:37:45 If we can make analyzerNode final above, then this
Emily Fortuna 2017/03/17 01:03:02 Hmm I made this change complete with the finals, a
Siggi Cherem (dart-lang) 2017/03/17 21:10:17 interesting - I think I understand why now - this
+ if (initializer == null) {
+ // 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);
+ });
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698