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

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

Issue 10832136: Skeleton typedef type implementation (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebased and updated cf. 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « lib/compiler/implementation/resolver.dart ('k') | pkg/dartdoc/mirrors/dart2js_mirror.dart » ('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
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 } catch (CancelTypeCheckException e) { 17 } catch (CancelTypeCheckException 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 interface Type {
28 SourceString get name(); 28 SourceString get name();
29 Element get element(); 29 Element get element();
30
31 /**
32 * Returns the unaliased type of this type.
33 *
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.
36 *
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
39 * [: Func<int,String> :] is the function type [: (String) -> int :].
40 */
41 Type unalias(Compiler compiler);
30 } 42 }
31 43
32 class TypeVariableType implements Type { 44 class TypeVariableType implements Type {
33 final TypeVariableElement element; 45 final TypeVariableElement element;
34 46
35 TypeVariableType(this.element); 47 TypeVariableType(this.element);
36 48
37 SourceString get name() => element.name; 49 SourceString get name() => element.name;
38 50
39 toString() => name.slowToString(); 51 Type unalias(Compiler compiler) => this;
52
53 String toString() => name.slowToString();
40 } 54 }
41 55
42 /** 56 /**
43 * A statement type tracks whether a statement returns or may return. 57 * A statement type tracks whether a statement returns or may return.
44 */ 58 */
45 class StatementType implements Type { 59 class StatementType implements Type {
46 final String stringName; 60 final String stringName;
47 Element get element() => null; 61 Element get element() => null;
48 62
49 SourceString get name() => new SourceString(stringName); 63 SourceString get name() => new SourceString(stringName);
50 64
51 const StatementType(this.stringName); 65 const StatementType(this.stringName);
52 66
53 static final RETURNING = const StatementType('<returning>'); 67 static final RETURNING = const StatementType('<returning>');
54 static final NOT_RETURNING = const StatementType('<not returning>'); 68 static final NOT_RETURNING = const StatementType('<not returning>');
55 static final MAYBE_RETURNING = const StatementType('<maybe returning>'); 69 static final MAYBE_RETURNING = const StatementType('<maybe returning>');
56 70
57 /** Combine the information about two control-flow edges that are joined. */ 71 /** Combine the information about two control-flow edges that are joined. */
58 StatementType join(StatementType other) { 72 StatementType join(StatementType other) {
59 return (this === other) ? this : MAYBE_RETURNING; 73 return (this === other) ? this : MAYBE_RETURNING;
60 } 74 }
61 75
76 Type unalias(Compiler compiler) => this;
77
62 String toString() => stringName; 78 String toString() => stringName;
63 } 79 }
64 80
65 class VoidType implements Type { 81 class VoidType implements Type {
66 const VoidType(this.element); 82 const VoidType(this.element);
67 SourceString get name() => element.name; 83 SourceString get name() => element.name;
68 final VoidElement element; 84 final VoidElement element;
69 85
70 toString() => name.slowToString(); 86 Type unalias(Compiler compiler) => this;
87
88 String toString() => name.slowToString();
71 } 89 }
72 90
73 class InterfaceType implements Type { 91 class InterfaceType implements Type {
74 final Element element; 92 final Element element;
75 final Link<Type> arguments; 93 final Link<Type> arguments;
76 94
77 const InterfaceType(this.element, 95 const InterfaceType(this.element,
78 [this.arguments = const EmptyLink<Type>()]); 96 [this.arguments = const EmptyLink<Type>()]);
79 97
80 SourceString get name() => element.name; 98 SourceString get name() => element.name;
81 99
82 toString() { 100 Type unalias(Compiler compiler) => this;
101
102 String toString() {
83 StringBuffer sb = new StringBuffer(); 103 StringBuffer sb = new StringBuffer();
84 sb.add(name.slowToString()); 104 sb.add(name.slowToString());
85 if (!arguments.isEmpty()) { 105 if (!arguments.isEmpty()) {
86 sb.add('<'); 106 sb.add('<');
87 arguments.printOn(sb, ', '); 107 arguments.printOn(sb, ', ');
88 sb.add('>'); 108 sb.add('>');
89 } 109 }
90 return sb.toString(); 110 return sb.toString();
91 } 111 }
92 } 112 }
93 113
94 class FunctionType implements Type { 114 class FunctionType implements Type {
95 final Element element; 115 final Element element;
96 Type returnType; 116 Type returnType;
97 Link<Type> parameterTypes; 117 Link<Type> parameterTypes;
98 118
99 FunctionType(Type this.returnType, Link<Type> this.parameterTypes, 119 FunctionType(Type this.returnType, Link<Type> this.parameterTypes,
100 Element this.element); 120 Element this.element);
101 121
102 toString() { 122 Type unalias(Compiler compiler) => this;
123
124 String toString() {
103 StringBuffer sb = new StringBuffer(); 125 StringBuffer sb = new StringBuffer();
104 bool first = true; 126 bool first = true;
105 sb.add('('); 127 sb.add('(');
106 parameterTypes.printOn(sb, ', '); 128 parameterTypes.printOn(sb, ', ');
107 sb.add(') -> ${returnType}'); 129 sb.add(') -> ${returnType}');
108 return sb.toString(); 130 return sb.toString();
109 } 131 }
110 132
111 SourceString get name() => const SourceString('Function'); 133 SourceString get name() => const SourceString('Function');
112 134
113 int computeArity() { 135 int computeArity() {
114 int arity = 0; 136 int arity = 0;
115 parameterTypes.forEach((_) { arity++; }); 137 parameterTypes.forEach((_) { arity++; });
116 return arity; 138 return arity;
117 } 139 }
118 140
119 void initializeFrom(FunctionType other) { 141 void initializeFrom(FunctionType other) {
120 assert(returnType === null); 142 assert(returnType === null);
121 assert(parameterTypes === null); 143 assert(parameterTypes === null);
122 returnType = other.returnType; 144 returnType = other.returnType;
123 parameterTypes = other.parameterTypes; 145 parameterTypes = other.parameterTypes;
124 } 146 }
125 } 147 }
126 148
149 class TypedefType implements Type {
150 final TypedefElement element;
151 final Link<Type> typeArguments;
152
153 const TypedefType(this.element,
154 [this.typeArguments = const EmptyLink<Type>()]);
155
156 SourceString get name() => element.name;
157
158 Type unalias(Compiler compiler) {
159 // TODO(ahe): This should be [ensureResolved].
160 compiler.resolveTypedef(element);
161 return element.alias.unalias(compiler);
162 }
163
164 String toString() {
165 StringBuffer sb = new StringBuffer();
166 sb.add(name.slowToString());
167 if (!typeArguments.isEmpty()) {
168 sb.add('<');
169 typeArguments.printOn(sb, ', ');
170 sb.add('>');
171 }
172 return sb.toString();
173 }
174 }
175
127 class Types { 176 class Types {
177 final Compiler compiler;
178 // TODO(karlklose): should we have a class Void?
128 final VoidType voidType; 179 final VoidType voidType;
129 final InterfaceType dynamicType; 180 final InterfaceType dynamicType;
130 181
131 Types(Element dynamicElement) 182 Types(Compiler compiler, Element dynamicElement)
132 : this.with(dynamicElement, new LibraryElement(new Script(null, null))); 183 : this.with(compiler, dynamicElement,
184 new LibraryElement(new Script(null, null)));
133 185
134 // TODO(karlklose): should we have a class Void? 186 Types.with(Compiler this.compiler,
135 Types.with(Element dynamicElement, LibraryElement library) 187 Element dynamicElement,
136 : voidType = new VoidType(new VoidElement(library.entryCompilationUnit)), 188 LibraryElement library)
189 : voidType = new VoidType(new VoidElement(library)),
137 dynamicType = new InterfaceType(dynamicElement); 190 dynamicType = new InterfaceType(dynamicElement);
138 191
139 /** Returns true if t is a subtype of s */ 192 /** Returns true if t is a subtype of s */
140 bool isSubtype(Type t, Type s) { 193 bool isSubtype(Type t, Type s) {
141 if (t === s || t === dynamicType || s === dynamicType || 194 if (t === s ||
142 // TODO(karlklose): Test for s.element === compiler.objectClass. 195 t === dynamicType ||
143 s.name == const SourceString('Object')) return true; 196 s === dynamicType ||
197 s.element === compiler.objectClass) {
198 return true;
199 }
200 t = t.unalias(compiler);
201 s = s.unalias(compiler);
202
144 if (t is VoidType) { 203 if (t is VoidType) {
145 return false; 204 return false;
146 } else if (t is InterfaceType) { 205 } else if (t is InterfaceType) {
147 if (s is !InterfaceType) return false; 206 if (s is !InterfaceType) return false;
148 ClassElement tc = t.element; 207 ClassElement tc = t.element;
149 if (tc === s.element) return true; 208 if (tc === s.element) return true;
150 for (Link<Type> supertypes = tc.allSupertypes; 209 for (Link<Type> supertypes = tc.allSupertypes;
151 supertypes != null && !supertypes.isEmpty(); 210 supertypes != null && !supertypes.isEmpty();
152 supertypes = supertypes.tail) { 211 supertypes = supertypes.tail) {
153 Type supertype = supertypes.head; 212 Type supertype = supertypes.head;
154 if (supertype.element === s.element) return true; 213 if (supertype.element === s.element) return true;
155 } 214 }
156 return false; 215 return false;
157 } else if (t is FunctionType) { 216 } else if (t is FunctionType) {
217 if (s.element === compiler.functionClass) return true;
158 if (s is !FunctionType) return false; 218 if (s is !FunctionType) return false;
159 FunctionType tf = t; 219 FunctionType tf = t;
160 FunctionType sf = s; 220 FunctionType sf = s;
161 Link<Type> tps = tf.parameterTypes; 221 Link<Type> tps = tf.parameterTypes;
162 Link<Type> sps = sf.parameterTypes; 222 Link<Type> sps = sf.parameterTypes;
163 while (!tps.isEmpty() && !sps.isEmpty()) { 223 while (!tps.isEmpty() && !sps.isEmpty()) {
164 if (!isAssignable(tps.head, sps.head)) return false; 224 if (!isAssignable(tps.head, sps.head)) return false;
165 tps = tps.tail; 225 tps = tps.tail;
166 sps = sps.tail; 226 sps = sps.tail;
167 } 227 }
(...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 } 841 }
782 842
783 visitCatchBlock(CatchBlock node) { 843 visitCatchBlock(CatchBlock node) {
784 return unhandledStatement(); 844 return unhandledStatement();
785 } 845 }
786 846
787 visitTypedef(Typedef node) { 847 visitTypedef(Typedef node) {
788 return unhandledStatement(); 848 return unhandledStatement();
789 } 849 }
790 } 850 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/resolver.dart ('k') | pkg/dartdoc/mirrors/dart2js_mirror.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698