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

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

Issue 10832029: Substitution implemented for the class hierarchy. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 5 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 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 * Performs the substitution [arguments[i]/parameters[i]]this.
33 * The notation is known from this lambda calculus rule:
34 * (lambda x.e0)e1 -> [e1/x]e0.
35 *
36 * See [TypeVariableType] for a motivation for this method.
37 */
38 Type subst(Link<Type> arguments, List<Type> parameters);
30 } 39 }
31 40
41 /**
42 * Represents a type variable, that is the type parameters of a class
43 * or interface type. For example, in class Array<E> { ... }`,
44 * E is a type variable.
45 *
46 * Each class/interface should have its own unique type variables,
47 * one for each type parameter. A class/interface with type parameters
48 * is said to be parameterized or generic.
49 *
50 * Non-static members, constructors, and factories of generic
51 * class/interface can refer to type variables of the current class
52 * (not of supertypes).
53 *
54 * When using a generic type, also known as an application or
55 * instantiation of the type, the actual type arguments should be
56 * substituted for the type variables in the class declaration.
57 *
58 * For example, given a box, `class Box<T> { T value; }`, the
59 * type of the expression `new Box<String>().value` is
60 * [String] because we must substitute `String` for the
61 * the type variable `T`.
62 */
32 class TypeVariableType implements Type { 63 class TypeVariableType implements Type {
33 final SourceString name; 64 final SourceString name;
34 TypeVariableElement element; 65 TypeVariableElement element;
35 TypeVariableType(this.name, [this.element]); 66 TypeVariableType(this.name, [this.element]);
36 67
37 toString() => name.slowToString(); 68 Type subst(Link<Type> arguments, List<Type> parameters) {
69 if (arguments.isEmpty()) {
70 // Return fast on empty substitutions.
71 return this;
72 }
73 Link<Type> argumentLink = arguments;
74 Iterator<Type> parameterIterator = parameters.iterator();
75 while (!argumentLink.isEmpty() && parameterIterator.hasNext()) {
76 Type parameter = parameterIterator.next();
77 Type argument = argumentLink.head;
78 if (parameter === this) {
79 return argument;
80 }
81 argumentLink = argumentLink.tail;
82 }
83 // The type variable was not substituted.
84 return this;
85 }
86
87 String toString() => name.slowToString();
38 } 88 }
39 89
40 /** 90 /**
41 * A statement type tracks whether a statement returns or may return. 91 * A statement type tracks whether a statement returns or may return.
42 */ 92 */
43 class StatementType implements Type { 93 class StatementType implements Type {
44 final String stringName; 94 final String stringName;
45 Element get element() => null; 95 Element get element() => null;
46 96
47 SourceString get name() => new SourceString(stringName); 97 SourceString get name() => new SourceString(stringName);
48 98
49 const StatementType(this.stringName); 99 const StatementType(this.stringName);
50 100
51 static final RETURNING = const StatementType('<returning>'); 101 static final RETURNING = const StatementType('<returning>');
52 static final NOT_RETURNING = const StatementType('<not returning>'); 102 static final NOT_RETURNING = const StatementType('<not returning>');
53 static final MAYBE_RETURNING = const StatementType('<maybe returning>'); 103 static final MAYBE_RETURNING = const StatementType('<maybe returning>');
54 104
55 /** Combine the information about two control-flow edges that are joined. */ 105 /** Combine the information about two control-flow edges that are joined. */
56 StatementType join(StatementType other) { 106 StatementType join(StatementType other) {
57 return (this === other) ? this : MAYBE_RETURNING; 107 return (this === other) ? this : MAYBE_RETURNING;
58 } 108 }
59 109
110 Type subst(Link<Type> arguments, List<Type> parameters) {
111 // Statement types are not substitutable.
112 return this;
113 }
114
60 String toString() => stringName; 115 String toString() => stringName;
61 } 116 }
62 117
63 class VoidType implements Type { 118 class VoidType implements Type {
64 const VoidType(this.element); 119 const VoidType(this.element);
65 SourceString get name() => element.name; 120 SourceString get name() => element.name;
66 final VoidElement element; 121 final VoidElement element;
67 122
68 toString() => name.slowToString(); 123 Type subst(Link<Type> arguments, List<Type> parameters) {
124 // Void cannot be substituted.
125 return this;
126 }
127
128 String toString() => name.slowToString();
69 } 129 }
70 130
71 class InterfaceType implements Type { 131 class InterfaceType implements Type {
72 final Element element; 132 final Element element;
73 final Link<Type> arguments; 133 final Link<Type> arguments;
74 134
75 const InterfaceType(this.element, 135 const InterfaceType(this.element,
76 [this.arguments = const EmptyLink<Type>()]); 136 [this.arguments = const EmptyLink<Type>()]);
77 137
78 SourceString get name() => element.name; 138 SourceString get name() => element.name;
79 139
80 toString() { 140 Type subst(Link<Type> replacements, List<Type> parameters) {
141 if (arguments.isEmpty()) {
142 // Return fast on non-generic types.
143 return this;
144 }
145 if (replacements.isEmpty()) {
146 // Return fast on empty substitutions.
147 return this;
148 }
149 bool changed = false;
150 var argumentsBuilder = new LinkBuilder<Type>();
151 Link<Type> argument = arguments;
152 while (!argument.isEmpty()) {
153 var replacement = argument.head.subst(replacements, parameters);
154 if (!changed && replacement !== argument.head) {
155 changed = true;
156 }
157 argumentsBuilder.addLast(replacement);
158 argument = argument.tail;
159 }
160 if (changed) {
161 // Create a new type only if necessary.
162 return new InterfaceType(element, argumentsBuilder.toLink());
163 }
164 return this;
165 }
166
167 String toString() {
81 StringBuffer sb = new StringBuffer(); 168 StringBuffer sb = new StringBuffer();
82 sb.add(name.slowToString()); 169 sb.add(name.slowToString());
83 if (!arguments.isEmpty()) { 170 if (!arguments.isEmpty()) {
84 sb.add('<'); 171 sb.add('<');
85 arguments.printOn(sb, ', '); 172 arguments.printOn(sb, ', ');
86 sb.add('>'); 173 sb.add('>');
87 } 174 }
88 return sb.toString(); 175 return sb.toString();
89 } 176 }
90 } 177 }
91 178
92 class FunctionType implements Type { 179 class FunctionType implements Type {
93 final Element element; 180 final Element element;
94 final Type returnType; 181 final Type returnType;
95 final Link<Type> parameterTypes; 182 final Link<Type> parameterTypes;
96 183
97 const FunctionType(Type this.returnType, Link<Type> this.parameterTypes, 184 const FunctionType(Type this.returnType, Link<Type> this.parameterTypes,
98 Element this.element); 185 Element this.element);
99 186
100 toString() { 187 Type subst(Link<Type> arguments, List<Type> parameters) {
188 if (arguments.isEmpty()) {
189 // Return fast on empty substitutions.
190 return this;
191 }
192 var newReturnType = returnType.subst(arguments, parameters);
193 bool changed = newReturnType !== returnType;
194 var parameterBuilder = new LinkBuilder<Type>();
195 Link<Type> parameterType = parameterTypes;
196 while (!parameterType.isEmpty()) {
197 var replacement = parameterType.head.subst(arguments, parameters);
198 if (!changed && replacement !== parameterType.head) {
199 changed = true;
200 }
201 parameterBuilder.addLast(replacement);
202 parameterType = parameterType.tail;
203 }
204 if (changed) {
205 // Create a new type only if necessary.
206 return new FunctionType(newReturnType, parameterBuilder.toLink(),
207 element);
208 }
209 return this;
210 }
211
212 String toString() {
101 StringBuffer sb = new StringBuffer(); 213 StringBuffer sb = new StringBuffer();
102 bool first = true; 214 bool first = true;
103 sb.add('('); 215 sb.add('(');
104 parameterTypes.printOn(sb, ', '); 216 parameterTypes.printOn(sb, ', ');
105 sb.add(') -> ${returnType}'); 217 sb.add(') -> ${returnType}');
106 return sb.toString(); 218 return sb.toString();
107 } 219 }
108 220
109 SourceString get name() => const SourceString('Function'); 221 SourceString get name() => const SourceString('Function');
110 222
(...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 } 884 }
773 885
774 visitCatchBlock(CatchBlock node) { 886 visitCatchBlock(CatchBlock node) {
775 return unhandledStatement(); 887 return unhandledStatement();
776 } 888 }
777 889
778 visitTypedef(Typedef node) { 890 visitTypedef(Typedef node) {
779 return unhandledStatement(); 891 return unhandledStatement();
780 } 892 }
781 } 893 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698