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

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

Issue 10911006: Collect the types used in is-checks in the resolver phase. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 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
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 const bool LOG_FAILURES = false; 9 static const bool LOG_FAILURES = false;
10 10
11 void check(Node tree, TreeElements elements) { 11 void check(Node tree, TreeElements elements) {
12 measure(() { 12 measure(() {
13 Visitor visitor = 13 Visitor visitor =
14 new TypeCheckerVisitor(compiler, elements, compiler.types); 14 new TypeCheckerVisitor(compiler, elements, compiler.types);
15 try { 15 try {
16 tree.accept(visitor); 16 tree.accept(visitor);
17 } on CancelTypeCheckException catch (e) { 17 } on CancelTypeCheckException catch (e) {
18 if (LOG_FAILURES) { 18 if (LOG_FAILURES) {
19 // Do not warn about unimplemented features; log message instead. 19 // Do not warn about unimplemented features; log message instead.
20 compiler.log("'${e.node}': ${e.reason}"); 20 compiler.log("'${e.node}': ${e.reason}");
21 } 21 }
22 } 22 }
23 }); 23 });
24 } 24 }
25 } 25 }
26 26
27 interface Type { 27 abstract class Type implements Hashable {
28 SourceString get name(); 28 abstract SourceString get name();
29 Element get element(); 29 abstract Element get element();
30 30
31 /** 31 /**
32 * Returns the unaliased type of this type. 32 * Returns the unaliased type of this type.
33 * 33 *
34 * The unaliased type of a typedef'd type is the unaliased type to which its 34 * The unaliased type of a typedef'd type is the unaliased type to which its
35 * name is bound. The unaliased version of any other type is the type itself. 35 * name is bound. The unaliased version of any other type is the type itself.
36 * 36 *
37 * For example, the unaliased type of [: typedef A Func<A,B>(B b) :] is the 37 * For example, the unaliased type of [: typedef A Func<A,B>(B b) :] is the
38 * function type [: (B) -> A :] and the unaliased type of 38 * function type [: (B) -> A :] and the unaliased type of
39 * [: Func<int,String> :] is the function type [: (String) -> int :]. 39 * [: Func<int,String> :] is the function type [: (String) -> int :].
40 */ 40 */
41 Type unalias(Compiler compiler); 41 abstract Type unalias(Compiler compiler);
42
43 abstract bool equals(other);
42 } 44 }
43 45
44 class TypeVariableType implements Type { 46 class TypeVariableType implements Type {
45 final TypeVariableElement element; 47 final TypeVariableElement element;
46 48
47 TypeVariableType(this.element); 49 TypeVariableType(this.element);
48 50
49 SourceString get name => element.name; 51 SourceString get name => element.name;
50 52
51 Type unalias(Compiler compiler) => this; 53 Type unalias(Compiler compiler) => this;
52 54
55 int hashCode() => 17 * element.hashCode();
56
57 bool equals(other) {
58 if (other is !TypeVariableType) return false;
59 return other.element == element;
60 }
61
53 String toString() => name.slowToString(); 62 String toString() => name.slowToString();
54 } 63 }
55 64
56 /** 65 /**
57 * A statement type tracks whether a statement returns or may return. 66 * A statement type tracks whether a statement returns or may return.
58 */ 67 */
59 class StatementType implements Type { 68 class StatementType implements Type {
60 final String stringName; 69 final String stringName;
61 Element get element => null; 70 Element get element => null;
62 71
63 SourceString get name => new SourceString(stringName); 72 SourceString get name => new SourceString(stringName);
64 73
65 const StatementType(this.stringName); 74 const StatementType(this.stringName);
66 75
67 static const RETURNING = const StatementType('<returning>'); 76 static const RETURNING = const StatementType('<returning>');
68 static const NOT_RETURNING = const StatementType('<not returning>'); 77 static const NOT_RETURNING = const StatementType('<not returning>');
69 static const MAYBE_RETURNING = const StatementType('<maybe returning>'); 78 static const MAYBE_RETURNING = const StatementType('<maybe returning>');
70 79
71 /** Combine the information about two control-flow edges that are joined. */ 80 /** Combine the information about two control-flow edges that are joined. */
72 StatementType join(StatementType other) { 81 StatementType join(StatementType other) {
73 return (this === other) ? this : MAYBE_RETURNING; 82 return (this === other) ? this : MAYBE_RETURNING;
74 } 83 }
75 84
76 Type unalias(Compiler compiler) => this; 85 Type unalias(Compiler compiler) => this;
77 86
87 int hashCode() => 17 * stringName.hashCode();
88
89 bool equals(other) {
90 if (other is !StatementType) return false;
91 return other.stringName == stringName;
92 }
93
78 String toString() => stringName; 94 String toString() => stringName;
79 } 95 }
80 96
81 class VoidType implements Type { 97 class VoidType implements Type {
82 const VoidType(this.element); 98 const VoidType(this.element);
83 SourceString get name => element.name; 99 SourceString get name => element.name;
84 final VoidElement element; 100 final VoidElement element;
85 101
86 Type unalias(Compiler compiler) => this; 102 Type unalias(Compiler compiler) => this;
87 103
104 int hashCode() => 1729;
105
106 bool equals(other) => other is VoidType;
107
88 String toString() => name.slowToString(); 108 String toString() => name.slowToString();
89 } 109 }
90 110
91 class InterfaceType implements Type { 111 class InterfaceType implements Type {
92 final Element element; 112 final Element element;
93 final Link<Type> arguments; 113 final Link<Type> arguments;
94 114
95 const InterfaceType(this.element, 115 const InterfaceType(this.element,
96 [this.arguments = const EmptyLink<Type>()]); 116 [this.arguments = const EmptyLink<Type>()]);
97 117
98 SourceString get name => element.name; 118 SourceString get name => element.name;
99 119
100 Type unalias(Compiler compiler) => this; 120 Type unalias(Compiler compiler) => this;
101 121
102 String toString() { 122 String toString() {
103 StringBuffer sb = new StringBuffer(); 123 StringBuffer sb = new StringBuffer();
104 sb.add(name.slowToString()); 124 sb.add(name.slowToString());
105 if (!arguments.isEmpty()) { 125 if (!arguments.isEmpty()) {
106 sb.add('<'); 126 sb.add('<');
107 arguments.printOn(sb, ', '); 127 arguments.printOn(sb, ', ');
108 sb.add('>'); 128 sb.add('>');
109 } 129 }
110 return sb.toString(); 130 return sb.toString();
111 } 131 }
132
133 int hashCode() {
134 int hash = element.hashCode();
135 for (Link<Type> arguments = this.arguments;
136 !arguments.isEmpty();
137 arguments = arguments.tail) {
138 hash = 17 * hash + 3 * arguments.head.hashCode();
139 }
140 return hash;
141 }
142
143 bool equals(other) {
144 if (other is !InterfaceType) return false;
145 return arguments == other.arguments;
146 }
112 } 147 }
113 148
114 class FunctionType implements Type { 149 class FunctionType implements Type {
115 final Element element; 150 final Element element;
116 Type returnType; 151 Type returnType;
117 Link<Type> parameterTypes; 152 Link<Type> parameterTypes;
118 153
119 FunctionType(Type this.returnType, Link<Type> this.parameterTypes, 154 FunctionType(Type this.returnType, Link<Type> this.parameterTypes,
120 Element this.element); 155 Element this.element);
121 156
(...skipping 15 matching lines...) Expand all
137 parameterTypes.forEach((_) { arity++; }); 172 parameterTypes.forEach((_) { arity++; });
138 return arity; 173 return arity;
139 } 174 }
140 175
141 void initializeFrom(FunctionType other) { 176 void initializeFrom(FunctionType other) {
142 assert(returnType === null); 177 assert(returnType === null);
143 assert(parameterTypes === null); 178 assert(parameterTypes === null);
144 returnType = other.returnType; 179 returnType = other.returnType;
145 parameterTypes = other.parameterTypes; 180 parameterTypes = other.parameterTypes;
146 } 181 }
182
183 int hashCode() {
184 int hash = 17 * element.hashCode() + 3 * returnType.hashCode();
185 for (Link<Type> parameters = parameterTypes;
186 !parameters.isEmpty();
187 parameters = parameters.tail) {
188 hash = 17 * hash + 3 * parameters.head.hashCode();
189 }
190 return hash;
191 }
192
193 bool equals(other) {
194 if (other is !FunctionType) return false;
195 return returnType == other.returnType
196 && parameterTypes == other.parameterTypes;
197 }
147 } 198 }
148 199
149 class TypedefType implements Type { 200 class TypedefType implements Type {
150 final TypedefElement element; 201 final TypedefElement element;
151 final Link<Type> typeArguments; 202 final Link<Type> typeArguments;
152 203
153 const TypedefType(this.element, 204 const TypedefType(this.element,
154 [this.typeArguments = const EmptyLink<Type>()]); 205 [this.typeArguments = const EmptyLink<Type>()]);
155 206
156 SourceString get name => element.name; 207 SourceString get name => element.name;
157 208
158 Type unalias(Compiler compiler) { 209 Type unalias(Compiler compiler) {
159 // TODO(ahe): This should be [ensureResolved]. 210 // TODO(ahe): This should be [ensureResolved].
160 compiler.resolveTypedef(element); 211 compiler.resolveTypedef(element);
161 return element.alias.unalias(compiler); 212 return element.alias.unalias(compiler);
162 } 213 }
163 214
164 String toString() { 215 String toString() {
165 StringBuffer sb = new StringBuffer(); 216 StringBuffer sb = new StringBuffer();
166 sb.add(name.slowToString()); 217 sb.add(name.slowToString());
167 if (!typeArguments.isEmpty()) { 218 if (!typeArguments.isEmpty()) {
168 sb.add('<'); 219 sb.add('<');
169 typeArguments.printOn(sb, ', '); 220 typeArguments.printOn(sb, ', ');
170 sb.add('>'); 221 sb.add('>');
171 } 222 }
172 return sb.toString(); 223 return sb.toString();
173 } 224 }
225
226 int hashCode() => 17 * element.hashCode();
227
228 bool equals(other) {
229 if (other is !TypedefType) return false;
230 return other.element == element;
231 }
174 } 232 }
175 233
176 class Types { 234 class Types {
177 final Compiler compiler; 235 final Compiler compiler;
178 // TODO(karlklose): should we have a class Void? 236 // TODO(karlklose): should we have a class Void?
179 final VoidType voidType; 237 final VoidType voidType;
180 final InterfaceType dynamicType; 238 final InterfaceType dynamicType;
181 239
182 Types(Compiler compiler, Element dynamicElement) 240 Types(Compiler compiler, Element dynamicElement)
183 : this.with(compiler, dynamicElement, 241 : this.with(compiler, dynamicElement,
(...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after
843 } 901 }
844 902
845 visitCatchBlock(CatchBlock node) { 903 visitCatchBlock(CatchBlock node) {
846 return unhandledStatement(); 904 return unhandledStatement();
847 } 905 }
848 906
849 visitTypedef(Typedef node) { 907 visitTypedef(Typedef node) {
850 return unhandledStatement(); 908 return unhandledStatement();
851 } 909 }
852 } 910 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698