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

Unified Diff: dart/lib/compiler/implementation/types/types.dart

Issue 10823184: Basic type inference skeleton (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address review comments Created 8 years, 4 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: dart/lib/compiler/implementation/types/types.dart
diff --git a/dart/lib/compiler/implementation/types/types.dart b/dart/lib/compiler/implementation/types/types.dart
new file mode 100644
index 0000000000000000000000000000000000000000..17dc39b429b3620f77e21ff36111416cf844f2c3
--- /dev/null
+++ b/dart/lib/compiler/implementation/types/types.dart
@@ -0,0 +1,172 @@
+// Copyright (c) 2012, 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.
+
+#library('types');
+
+#import('../leg.dart');
+#import('../tree/tree.dart');
+#import('../elements/elements.dart');
+
+/**
+ * The types task infers guaranteed types globally.
+ */
+class TypesTask extends CompilerTask {
+ final String name = 'Type inference';
+ final bool enabled = false;
+
+ TypesTask(Compiler compiler) : super(compiler);
+
+ /**
+ * Called once for each method during the resolution phase of the
+ * compiler.
+ */
+ void analyze(Node node, TreeElements elements) {
+ measure(() {
+ node.accept(new ConcreteTypeInferencer(this, elements));
+ });
+ }
+
+ /**
+ * Called when resolution is complete.
+ */
+ void onResolutionComplete() {
+ measure(() {
+ // TODO(ahe): Do something here.
+ });
+ }
+
+ /**
+ * Return the (inferred) guaranteed type of [element].
+ */
+ Element getGuaranteedTypeOfElement(Element element) {
+ if (!enabled) return null;
+ return measure(() {
+ // TODO(ahe): Do something real here.
+ if (element.enclosingElement.name.slowToString() == 'print') {
+ return compiler.stringClass;
+ }
+ return null;
+ });
+ }
+
+ /**
+ * Return the (inferred) guaranteed type of [node].
+ * [node] must be an AST node of [owner].
+ */
+ Element getGuaranteedTypeOfNode(Node node, Element owner) {
+ if (!enabled) return null;
+ return measure(() {
+ // TODO(ahe): Do something real here.
+ return null;
+ });
+ }
+}
+
+/**
+ * Infers concrete types for a single method or expression.
+ */
+class ConcreteTypeInferencer extends AbstractVisitor {
+ final TypesTask task;
+ final TreeElements elements;
+ final ClassElement boolClass;
+ final ClassElement doubleClass;
+ final ClassElement intClass;
+ final ClassElement listClass;
+ final ClassElement nullClass;
+ final ClassElement stringClass;
+
+ final Map<Node, ClassElement> concreteTypes;
+
+ ConcreteTypeInferencer(TypesTask task, this.elements)
+ : this.task = task,
+ this.boolClass = task.compiler.boolClass,
+ this.doubleClass = task.compiler.doubleClass,
+ this.intClass = task.compiler.intClass,
+ this.listClass = task.compiler.listClass,
+ this.nullClass = task.compiler.nullClass,
+ this.stringClass = task.compiler.stringClass,
+ this.concreteTypes = new Map<Node, ClassElement>();
+
+ visitNode(Node node) => node.visitChildren(this);
+
+ visitLiteralString(LiteralString node) {
+ recordConcreteType(node, stringClass);
+ }
+
+ visitStringInterpolation(StringInterpolation node) {
+ node.visitChildren(this);
+ recordConcreteType(node, stringClass);
+ }
+
+ visitStringJuxtaposition(StringJuxtaposition node) {
+ node.visitChildren(this);
+ recordConcreteType(node, stringClass);
+ }
+
+ recordConcreteType(Node node, ClassElement cls) {
+ concreteTypes[node] = cls;
+ }
+
+ visitLiteralBool(LiteralBool node) {
+ recordConcreteType(node, boolClass);
+ }
+
+ visitLiteralDouble(LiteralDouble node) {
+ recordConcreteType(node, doubleClass);
+ }
+
+ visitLiteralInt(LiteralInt node) {
+ recordConcreteType(node, intClass);
+ }
+
+ visitLiteralList(LiteralList node) {
+ node.visitChildren(this);
+ recordConcreteType(node, listClass);
+ }
+
+ visitLiteralMap(LiteralMap node) {
+ node.visitChildren(this);
+ // TODO(ahe): map class?
+ }
+
+ visitLiteralNull(LiteralNull node) {
+ recordConcreteType(node, nullClass);
+ }
+
+ isConcreteSend(Send node) {
+ if (node.argumentsNode === null) return true;
+ if (node.arguments.isEmpty()) return true;
+ if (node.receiver !== null && concreteTypes[node.receiver] === null) {
+ return false;
+ }
+ for (Node argument in node.arguments) {
+ if (concreteTypes[argument] === null) return false;
+ }
+ return true;
+ }
+
+ visitSend(Send node) {
+ if (node.argumentsNode === null) return;
+ if (node.arguments.isEmpty()) return;
+ if (node.selector.toString() != 'print') return;
+ node.visitChildren(this);
+ if (isConcreteSend(node)) {
+ interest(node, 'all arguments are concrete');
+ } else {
+ interest(node, 'not all arguments are concrete');
+ }
+ }
+
+ visitSendSet(SendSet node) {
+ // TODO(ahe): Implement this. For now, overridden to avoid calling
+ // visitSend through super.
+ node.visitChildren(this);
+ }
+
+ interest(Node node, String note) {
+ if (!task.enabled) return;
+ var message = MessageKind.GENERIC.message([note]);
+ task.compiler.reportWarning(node, message);
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698