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

Side by Side Diff: lib/compiler/implementation/typechecker.dart

Issue 10095014: Implement interface types. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 8 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « lib/compiler/implementation/ssa/optimize.dart ('k') | tests/co19/co19-leg.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 class TypeCheckerTask extends CompilerTask { 5 class TypeCheckerTask extends CompilerTask {
6 TypeCheckerTask(Compiler compiler) : super(compiler); 6 TypeCheckerTask(Compiler compiler) : super(compiler);
7 String get name() => "Type checker"; 7 String get name() => "Type checker";
8 8
9 static final bool LOG_FAILURES = false; 9 static final bool LOG_FAILURES = false;
10 10
(...skipping 15 matching lines...) Expand all
26 26
27 interface Type { 27 interface Type {
28 SourceString get name(); 28 SourceString get name();
29 Element get element(); 29 Element get element();
30 } 30 }
31 31
32 class TypeVariableType implements Type { 32 class TypeVariableType implements Type {
33 final SourceString name; 33 final SourceString name;
34 Element element; 34 Element element;
35 TypeVariableType(this.name, [this.element]); 35 TypeVariableType(this.name, [this.element]);
36
37 toString() => name.toString();
36 } 38 }
37 39
38 /** 40 /**
39 * A statement type tracks whether a statement returns or may return. 41 * A statement type tracks whether a statement returns or may return.
40 */ 42 */
41 class StatementType implements Type { 43 class StatementType implements Type {
42 final String stringName; 44 final String stringName;
43 Element get element() => null; 45 Element get element() => null;
44 46
45 SourceString get name() => new SourceString(stringName); 47 SourceString get name() => new SourceString(stringName);
46 48
47 const StatementType(this.stringName); 49 const StatementType(this.stringName);
48 50
49 static final RETURNING = const StatementType('<returning>'); 51 static final RETURNING = const StatementType('<returning>');
50 static final NOT_RETURNING = const StatementType('<not returning>'); 52 static final NOT_RETURNING = const StatementType('<not returning>');
51 static final MAYBE_RETURNING = const StatementType('<maybe returning>'); 53 static final MAYBE_RETURNING = const StatementType('<maybe returning>');
52 54
53 /** Combine the information about two control-flow edges that are joined. */ 55 /** Combine the information about two control-flow edges that are joined. */
54 StatementType join(StatementType other) { 56 StatementType join(StatementType other) {
55 return (this === other) ? this : MAYBE_RETURNING; 57 return (this === other) ? this : MAYBE_RETURNING;
56 } 58 }
57 59
58 String toString() => stringName; 60 String toString() => stringName;
59 } 61 }
60 62
61 class SimpleType implements Type { 63 class InterfaceType implements Type {
62 final SourceString name; 64 final SourceString name;
63 final Element element; 65 final ClassElement element;
66 final Link<Type> arguments;
64 67
65 const SimpleType(SourceString this.name, Element this.element); 68 const InterfaceType(this.name, this.element, this.arguments);
66 69
70 toString() {
71 StringBuffer sb = new StringBuffer();
72 sb.add(name.slowToString());
73 if (!arguments.isEmpty()) {
74 sb.add('<');
75 arguments.printOn(sb);
76 sb.add('>');
77 }
78 return sb.toString();
79 }
80 }
81
82 // TODO(karlklose): merge into InterfaceType as a named constructor.
83 class SimpleType extends InterfaceType {
84 const SimpleType(SourceString name, Element element)
85 : super(name, element, const EmptyLink<Type>());
67 String toString() => name.slowToString(); 86 String toString() => name.slowToString();
68 } 87 }
69 88
70 class FunctionType implements Type { 89 class FunctionType implements Type {
71 final Element element; 90 final Element element;
72 final Type returnType; 91 final Type returnType;
73 final Link<Type> parameterTypes; 92 final Link<Type> parameterTypes;
74 93
75 const FunctionType(Type this.returnType, Link<Type> this.parameterTypes, 94 const FunctionType(Type this.returnType, Link<Type> this.parameterTypes,
76 Element this.element); 95 Element this.element);
(...skipping 17 matching lines...) Expand all
94 static final DYNAMIC = const SourceString('Dynamic'); 113 static final DYNAMIC = const SourceString('Dynamic');
95 static final STRING = const SourceString('String'); 114 static final STRING = const SourceString('String');
96 static final BOOL = const SourceString('bool'); 115 static final BOOL = const SourceString('bool');
97 static final OBJECT = const SourceString('Object'); 116 static final OBJECT = const SourceString('Object');
98 static final LIST = const SourceString('List'); 117 static final LIST = const SourceString('List');
99 118
100 final SimpleType voidType; 119 final SimpleType voidType;
101 final SimpleType dynamicType; 120 final SimpleType dynamicType;
102 121
103 Types() : this.with(new LibraryElement(new Script(null, null))); 122 Types() : this.with(new LibraryElement(new Script(null, null)));
123
104 Types.with(LibraryElement library) 124 Types.with(LibraryElement library)
105 : voidType = new SimpleType(VOID, new ClassElement(VOID, library)), 125 : voidType = new SimpleType(VOID, new ClassElement(VOID, library)),
106 dynamicType = new SimpleType(DYNAMIC, new ClassElement(DYNAMIC, library)); 126 dynamicType = new SimpleType(DYNAMIC, new ClassElement(DYNAMIC, library));
107 127
108 Type lookup(SourceString s) { 128 Type lookup(SourceString s) {
109 if (VOID == s) { 129 if (VOID == s) {
110 return voidType; 130 return voidType;
111 } else if (DYNAMIC == s || s.stringValue === 'var') { 131 } else if (DYNAMIC == s || s.stringValue === 'var') {
112 return dynamicType; 132 return dynamicType;
113 } 133 }
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 Element element = compiler.coreLibrary.find(name); 185 Element element = compiler.coreLibrary.find(name);
166 if (element !== null && element.kind === ElementKind.CLASS) { 186 if (element !== null && element.kind === ElementKind.CLASS) {
167 return element.computeType(compiler); 187 return element.computeType(compiler);
168 } 188 }
169 return null; 189 return null;
170 } 190 }
171 191
172 class TypeCheckerVisitor implements Visitor<Type> { 192 class TypeCheckerVisitor implements Visitor<Type> {
173 final Compiler compiler; 193 final Compiler compiler;
174 final TreeElements elements; 194 final TreeElements elements;
175 Node lastSeenNode;
176 final Types types; 195 final Types types;
177 196
197 Node lastSeenNode;
178 Type expectedReturnType; 198 Type expectedReturnType;
179 ClassElement currentClass; 199 ClassElement currentClass;
180 200
181 Link<Type> cascadeTypes = const EmptyLink<Type>(); 201 Link<Type> cascadeTypes = const EmptyLink<Type>();
182 202
183 Type intType; 203 Type intType;
184 Type doubleType; 204 Type doubleType;
185 Type boolType; 205 Type boolType;
186 Type stringType; 206 Type stringType;
187 Type objectType; 207 Type objectType;
188 Type listType; 208 Type listType;
189 209
190 TypeCheckerVisitor(Compiler this.compiler, TreeElements this.elements, 210 TypeCheckerVisitor(this.compiler, this.elements, this.types) {
191 Types this.types) {
192 intType = lookupType(Types.INT, compiler, types); 211 intType = lookupType(Types.INT, compiler, types);
193 doubleType = lookupType(Types.DOUBLE, compiler, types); 212 doubleType = lookupType(Types.DOUBLE, compiler, types);
194 boolType = lookupType(Types.BOOL, compiler, types); 213 boolType = lookupType(Types.BOOL, compiler, types);
195 stringType = lookupType(Types.STRING, compiler, types); 214 stringType = lookupType(Types.STRING, compiler, types);
196 objectType = lookupType(Types.OBJECT, compiler, types); 215 objectType = lookupType(Types.OBJECT, compiler, types);
197 listType = lookupType(Types.LIST, compiler, types); 216 listType = lookupType(Types.LIST, compiler, types);
198 } 217 }
199 218
200 Type fail(node, [reason]) { 219 Type fail(node, [reason]) {
201 String message = 'cannot type-check'; 220 String message = 'cannot type-check';
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 if (element === null) fail(node.selector, 'unresolved property'); 468 if (element === null) fail(node.selector, 'unresolved property');
450 return computeType(element); 469 return computeType(element);
451 470
452 } else if (node.isFunctionObjectInvocation) { 471 } else if (node.isFunctionObjectInvocation) {
453 fail(node.receiver, 'function object invocation unimplemented'); 472 fail(node.receiver, 'function object invocation unimplemented');
454 473
455 } else { 474 } else {
456 FunctionType computeFunType() { 475 FunctionType computeFunType() {
457 if (node.receiver !== null) { 476 if (node.receiver !== null) {
458 Type receiverType = analyze(node.receiver); 477 Type receiverType = analyze(node.receiver);
459 if (receiverType === types.dynamicType) return null; 478 if (receiverType.element == compiler.dynamicClass) return null;
460 if (receiverType === null) { 479 if (receiverType === null) {
461 fail(node.receiver, 'receivertype is null'); 480 fail(node.receiver, 'receivertype is null');
462 } 481 }
463 if (receiverType.element.kind !== ElementKind.CLASS) { 482 if (receiverType.element.kind !== ElementKind.CLASS) {
464 fail(node.receiver, 'receivertype is not a class'); 483 fail(node.receiver, 'receivertype is not a class');
465 } 484 }
466 ClassElement classElement = receiverType.element; 485 ClassElement classElement = receiverType.element;
467 // TODO(karlklose): substitute type arguments. 486 // TODO(karlklose): substitute type arguments.
468 Type memberType = 487 Type memberType =
469 lookupMethodType(selector, classElement, selector.source); 488 lookupMethodType(selector, classElement, selector.source);
470 if (memberType === types.dynamicType) return null; 489 if (memberType.element === compiler.dynamicClass) return null;
471 return memberType; 490 return memberType;
472 } else { 491 } else {
473 Element element = elements[node]; 492 Element element = elements[node];
474 if (element === null) { 493 if (element === null) {
475 fail(node, 'unresolved ${node.selector}'); 494 fail(node, 'unresolved ${node.selector}');
476 } else if (element.kind === ElementKind.FUNCTION) { 495 } else if (element.kind === ElementKind.FUNCTION) {
477 return computeType(element); 496 return computeType(element);
478 } else if (element.kind === ElementKind.FOREIGN) { 497 } else if (element.kind === ElementKind.FOREIGN) {
479 return null; 498 return null;
480 } else { 499 } else {
481 fail(node, 'unexpected element kind ${element.kind}'); 500 fail(node, 'unexpected element kind ${element.kind}');
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 } 749 }
731 750
732 visitCatchBlock(CatchBlock node) { 751 visitCatchBlock(CatchBlock node) {
733 fail(node); 752 fail(node);
734 } 753 }
735 754
736 visitTypedef(Typedef node) { 755 visitTypedef(Typedef node) {
737 fail(node); 756 fail(node);
738 } 757 }
739 } 758 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/ssa/optimize.dart ('k') | tests/co19/co19-leg.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698