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

Side by Side Diff: frog/member.dart

Issue 8681027: Fix bug 578 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: prereviewed Created 9 years 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 | « frog/library.dart ('k') | frog/parser.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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 /** A formal parameter to a [Method]. */ 5 /** A formal parameter to a [Method]. */
6 class Parameter { 6 class Parameter {
7 FormalNode definition; 7 FormalNode definition;
8 Member method;
8 9
9 String name; 10 String name;
10 Type type; 11 Type type;
11 bool isInitializer = false; 12 bool isInitializer = false;
12 13
13 Value value; 14 Value value;
14 15
15 Parameter(this.definition); 16 Parameter(this.definition, this.method);
16 17
17 resolve(Member method, Type inType) { 18 resolve() {
18 name = definition.name.name; 19 name = definition.name.name;
19 if (name.startsWith('this.')) { 20 if (name.startsWith('this.')) {
20 name = name.substring(5); 21 name = name.substring(5);
21 isInitializer = true; 22 isInitializer = true;
22 } 23 }
23 24
24 type = inType.resolveType(definition.type, false); 25 type = method.resolveType(definition.type, false);
25 26
26 if (method.isStatic && type.hasTypeParams) { 27 if (method.isStatic && method.typeParameters === null && type.hasTypeParams) {
27 world.error('using type parameter in static context', definition.span); 28 world.error('using type parameter in static context', definition.span);
28 } 29 }
29 30
30 if (definition.value != null) { 31 if (definition.value != null) {
31 // To match VM, detect cases where value was not actually specified in 32 // To match VM, detect cases where value was not actually specified in
32 // code and don't signal errors. 33 // code and don't signal errors.
33 // TODO(jimhug): Clean up after issue #352 is resolved. 34 // TODO(jimhug): Clean up after issue #352 is resolved.
34 if (definition.value is NullExpression && 35 if (definition.value is NullExpression &&
35 definition.value.span.start == definition.span.start) { 36 definition.value.span.start == definition.span.start) {
36 return; 37 return;
(...skipping 18 matching lines...) Expand all
55 genValue(MethodMember method, MethodGenerator context) { 56 genValue(MethodMember method, MethodGenerator context) {
56 if (definition.value == null || value != null) return; 57 if (definition.value == null || value != null) return;
57 58
58 if (context == null) { // interface method 59 if (context == null) { // interface method
59 context = new MethodGenerator(method, null); 60 context = new MethodGenerator(method, null);
60 } 61 }
61 value = definition.value.visit(context); 62 value = definition.value.visit(context);
62 value = value.convertTo(context, type, definition.value); 63 value = value.convertTo(context, type, definition.value);
63 } 64 }
64 65
65 Parameter copyWithNewType(Type newType) { 66 Parameter copyWithNewType(Member newMethod, Type newType) {
66 var ret = new Parameter(definition); 67 var ret = new Parameter(definition, newMethod);
67 ret.type = newType; 68 ret.type = newType;
68 ret.name = name; 69 ret.name = name;
69 ret.isInitializer = isInitializer; 70 ret.isInitializer = isInitializer;
70 return ret; 71 return ret;
71 } 72 }
72 73
73 bool get isOptional() => definition != null && definition.value != null; 74 bool get isOptional() => definition != null && definition.value != null;
74 } 75 }
75 76
76 77
77 interface Named { 78 class Member extends Element {
78 String get name();
79 Library get library();
80 bool get isNative();
81 String get jsname();
82 set jsname(String name);
83
84 SourceSpan get span();
85 }
86
87 class Member implements Named {
88 final String name;
89 final Type declaringType; 79 final Type declaringType;
90 80
91 String _jsname;
92
93 bool isGenerated; 81 bool isGenerated;
94 MethodGenerator generator; 82 MethodGenerator generator;
95 83
96 Member(this.name, this.declaringType): isGenerated = false; 84 Member(String name, Type declaringType)
97 85 : isGenerated = false, this.declaringType = declaringType,
98 abstract SourceSpan get span(); 86 super(name, declaringType);
99 87
100 abstract bool get isStatic(); 88 abstract bool get isStatic();
101 abstract Type get returnType(); 89 abstract Type get returnType();
102 90
103 abstract bool get canGet(); 91 abstract bool get canGet();
104 abstract bool get canSet(); 92 abstract bool get canSet();
105 93
106 abstract void resolve(Type inType);
107
108 String get jsname() => _jsname == null ? name : _jsname;
109
110 set jsname(String name) => _jsname = name;
111
112 Library get library() => declaringType.library; 94 Library get library() => declaringType.library;
113 95
114 bool get isPrivate() => name.startsWith('_'); 96 bool get isPrivate() => name.startsWith('_');
115 97
116 bool get isConstructor() => false; 98 bool get isConstructor() => false;
117 bool get isField() => false; 99 bool get isField() => false;
118 bool get isMethod() => false; 100 bool get isMethod() => false;
119 bool get isProperty() => false; 101 bool get isProperty() => false;
120 bool get isAbstract() => false; 102 bool get isAbstract() => false;
121 103
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 String get generatedFactoryName() { 186 String get generatedFactoryName() {
205 assert(this.isFactory); 187 assert(this.isFactory);
206 String prefix = '${declaringType.jsname}.${constructorName}\$'; 188 String prefix = '${declaringType.jsname}.${constructorName}\$';
207 if (name == '') { 189 if (name == '') {
208 return '${prefix}factory'; 190 return '${prefix}factory';
209 } else { 191 } else {
210 return '${prefix}$name\$factory'; 192 return '${prefix}$name\$factory';
211 } 193 }
212 } 194 }
213 195
214 Type resolveType(TypeReference node, bool isRequired) {
215 var type = declaringType.resolveType(node, isRequired);
216 if (isStatic && type.hasTypeParams) {
217 // TODO(jimhug): Is this really so hard?
218 world.error('using type parameter in static context',
219 node.span);
220 }
221 return type;
222 }
223
224 int hashCode() => (declaringType.hashCode() << 4) ^ name.hashCode(); 196 int hashCode() => (declaringType.hashCode() << 4) ^ name.hashCode();
225 } 197 }
226 198
227 199
228 /** 200 /**
229 * Types are treated as first class members of their library's top type. 201 * Types are treated as first class members of their library's top type.
230 */ 202 */
231 // TODO(jmesserly): perhaps Type should extend Member, but that can get 203 // TODO(jmesserly): perhaps Type should extend Member, but that can get
232 // complicated. 204 // complicated.
233 class TypeMember extends Member { 205 class TypeMember extends Member {
234 final DefinedType type; 206 final DefinedType type;
235 207
236 TypeMember(DefinedType type) 208 TypeMember(DefinedType type)
237 : super(type.name, type.library.topType), 209 : super(type.name, type.library.topType),
238 this.type = type; 210 this.type = type;
239 211
240 SourceSpan get span() => type.definition.span; 212 SourceSpan get span() => type.definition.span;
241 213
242 bool get isStatic() => true; 214 bool get isStatic() => true;
243 215
244 // If this really becomes first class, this should return typeof(Type) 216 // If this really becomes first class, this should return typeof(Type)
245 Type get returnType() => world.varType; 217 Type get returnType() => world.varType;
246 218
247 bool canInvoke(MethodGenerator context, Arguments args) => false; 219 bool canInvoke(MethodGenerator context, Arguments args) => false;
248 bool get canGet() => true; 220 bool get canGet() => true;
249 bool get canSet() => false; 221 bool get canSet() => false;
250 222
251 void resolve(Type inType) {}
252
253 Value _get(MethodGenerator context, Node node, Value target, 223 Value _get(MethodGenerator context, Node node, Value target,
254 [bool isDynamic=false]) { 224 [bool isDynamic=false]) {
255 return new Value.type(type, node.span); 225 return new Value.type(type, node.span);
256 } 226 }
257 227
258 Value _set(MethodGenerator context, Node node, Value target, Value value, 228 Value _set(MethodGenerator context, Node node, Value target, Value value,
259 [bool isDynamic=false]) { 229 [bool isDynamic=false]) {
260 world.error('cannot set type', node.span); 230 world.error('cannot set type', node.span);
261 } 231 }
262 232
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 290
321 SourceSpan get span() => definition == null ? null : definition.span; 291 SourceSpan get span() => definition == null ? null : definition.span;
322 292
323 Type get returnType() => type; 293 Type get returnType() => type;
324 294
325 bool get canGet() => true; 295 bool get canGet() => true;
326 bool get canSet() => !isFinal; 296 bool get canSet() => !isFinal;
327 297
328 bool get isField() => true; 298 bool get isField() => true;
329 299
330 resolve(Type inType) { 300 resolve() {
331 isStatic = declaringType.isTop; 301 isStatic = declaringType.isTop;
332 isFinal = false; 302 isFinal = false;
333 if (definition.modifiers != null) { 303 if (definition.modifiers != null) {
334 for (var mod in definition.modifiers) { 304 for (var mod in definition.modifiers) {
335 if (mod.kind == TokenKind.STATIC) { 305 if (mod.kind == TokenKind.STATIC) {
336 if (isStatic) { 306 if (isStatic) {
337 world.error('duplicate static modifier', mod.span); 307 world.error('duplicate static modifier', mod.span);
338 } 308 }
339 isStatic = true; 309 isStatic = true;
340 } else if (mod.kind == TokenKind.FINAL) { 310 } else if (mod.kind == TokenKind.FINAL) {
341 if (isFinal) { 311 if (isFinal) {
342 world.error('duplicate final modifier', mod.span); 312 world.error('duplicate final modifier', mod.span);
343 } 313 }
344 isFinal = true; 314 isFinal = true;
345 } else { 315 } else {
346 world.error('${mod} modifier not allowed on field', mod.span); 316 world.error('${mod} modifier not allowed on field', mod.span);
347 } 317 }
348 } 318 }
349 } 319 }
350 type = inType.resolveType(definition.type, false); 320 type = resolveType(definition.type, false);
351 if (isStatic && type.hasTypeParams) { 321 if (isStatic && type.hasTypeParams) {
352 world.error('using type parameter in static context', 322 world.error('using type parameter in static context',
353 definition.type.span); 323 definition.type.span);
354 } 324 }
355 325
356 if (isStatic && isFinal && value == null) { 326 if (isStatic && isFinal && value == null) {
357 world.error('static final field is missing initializer', span); 327 world.error('static final field is missing initializer', span);
358 } 328 }
359 329
360 library._addMember(this); 330 library._addMember(this);
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 ConcreteMember c = parentMember; 497 ConcreteMember c = parentMember;
528 parent = c.baseMember; 498 parent = c.baseMember;
529 } else { 499 } else {
530 parent = parentMember; 500 parent = parentMember;
531 } 501 }
532 502
533 if (getter == null) getter = parent.getter; 503 if (getter == null) getter = parent.getter;
534 if (setter == null) setter = parent.setter; 504 if (setter == null) setter = parent.setter;
535 } 505 }
536 506
537 resolve(Type inType) { 507 resolve() {
538 if (getter != null) getter.resolve(inType); 508 if (getter != null) getter.resolve();
539 if (setter != null) setter.resolve(inType); 509 if (setter != null) setter.resolve();
540 510
541 library._addMember(this); 511 library._addMember(this);
542 } 512 }
543 } 513 }
544 514
545 515
546 class ConcreteMember extends Member { 516 class ConcreteMember extends Member {
547 final Member baseMember; 517 final Member baseMember;
548 Type returnType; 518 Type returnType;
549 List<Parameter> parameters; 519 List<Parameter> parameters;
550 520
551 ConcreteMember(String name, ConcreteType declaringType, this.baseMember) 521 ConcreteMember(String name, ConcreteType declaringType, this.baseMember)
552 : super(name, declaringType) { 522 : super(name, declaringType) {
553 parameters = []; 523 parameters = [];
554 returnType = baseMember.returnType.resolveTypeParams(declaringType); 524 returnType = baseMember.returnType.resolveTypeParams(declaringType);
555 // TODO(jimhug): Optimize not creating new array if new param types. 525 // TODO(jimhug): Optimize not creating new array if no new param types.
556 for (var p in baseMember.parameters) { 526 for (var p in baseMember.parameters) {
557 var newType = p.type.resolveTypeParams(declaringType); 527 var newType = p.type.resolveTypeParams(declaringType);
558 if (newType != p.type) { 528 if (newType != p.type) {
559 parameters.add(p.copyWithNewType(newType)); 529 parameters.add(p.copyWithNewType(this, newType));
560 } else { 530 } else {
561 parameters.add(p); 531 parameters.add(p);
562 } 532 }
563 } 533 }
564 } 534 }
565 535
566 SourceSpan get span() => baseMember.span; 536 SourceSpan get span() => baseMember.span;
567 537
568 bool get isStatic() => baseMember.isStatic; 538 bool get isStatic() => baseMember.isStatic;
569 bool get isAbstract() => baseMember.isAbstract; 539 bool get isAbstract() => baseMember.isAbstract;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 } 611 }
642 } 612 }
643 613
644 614
645 /** Represents a Dart method or top-level function. */ 615 /** Represents a Dart method or top-level function. */
646 class MethodMember extends Member { 616 class MethodMember extends Member {
647 FunctionDefinition definition; 617 FunctionDefinition definition;
648 Type returnType; 618 Type returnType;
649 List<Parameter> parameters; 619 List<Parameter> parameters;
650 620
621 // Could support generic methods in general. Right now only used for
622 // strange corner case of factory methods for generic types.
623 List<ParameterType> typeParameters;
624
651 625
652 Type _functionType; 626 Type _functionType;
653 bool isStatic = false; 627 bool isStatic = false;
654 bool isAbstract = false; 628 bool isAbstract = false;
655 629
656 // Note: these two modifiers are only legal on constructors 630 // Note: these two modifiers are only legal on constructors
657 bool isConst = false; 631 bool isConst = false;
658 bool isFactory = false; 632 bool isFactory = false;
659 633
660 /** True if this is a function defined inside another method. */ 634 /** True if this is a function defined inside another method. */
(...skipping 21 matching lines...) Expand all
682 bool get isMethod() => !isConstructor; 656 bool get isMethod() => !isConstructor;
683 657
684 bool get isNative() => definition.body is NativeStatement; 658 bool get isNative() => definition.body is NativeStatement;
685 659
686 bool get canGet() => false; // TODO(jimhug): get bound method support. 660 bool get canGet() => false; // TODO(jimhug): get bound method support.
687 bool get canSet() => false; 661 bool get canSet() => false;
688 662
689 SourceSpan get span() => definition == null ? null : definition.span; 663 SourceSpan get span() => definition == null ? null : definition.span;
690 664
691 String get constructorName() { 665 String get constructorName() {
692 NameTypeReference returnType = definition.returnType; 666 var returnType = definition.returnType;
693 if (returnType == null) return ''; 667 if (returnType == null) return '';
668 if (returnType is GenericTypeReference) {
669 return '';
670 }
694 671
695 // TODO(jmesserly): make this easier? 672 // TODO(jmesserly): make this easier?
696 if (returnType.names != null) { 673 if (returnType.names != null) {
697 return returnType.names[0].name; 674 return returnType.names[0].name;
698 } else if (returnType.name != null) { 675 } else if (returnType.name != null) {
699 return returnType.name.name; 676 return returnType.name.name;
700 } 677 }
701 world.internalError('no valid constructor name', definition.span); 678 world.internalError('no valid constructor name', definition.span);
702 } 679 }
703 680
704 Type get functionType() { 681 Type get functionType() {
705 if (_functionType == null) { 682 if (_functionType == null) {
706 _functionType = library.getOrAddFunctionType(name, 683 _functionType = library.getOrAddFunctionType(declaringType, name, definiti on);
707 definition, declaringType);
708 // TODO(jimhug): Better resolution checks. 684 // TODO(jimhug): Better resolution checks.
709 if (parameters == null) { 685 if (parameters == null) {
710 resolve(declaringType); 686 resolve();
711 } 687 }
712 } 688 }
713 return _functionType; 689 return _functionType;
714 } 690 }
715 691
716 bool override(Member other) { 692 bool override(Member other) {
717 if (!super.override(other)) return false; 693 if (!super.override(other)) return false;
718 694
719 // methods can only override other methods 695 // methods can only override other methods
720 if (other.isMethod) { 696 if (other.isMethod) {
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 829
854 /** 830 /**
855 * Invokes this method on the given [target] with the given [args]. 831 * Invokes this method on the given [target] with the given [args].
856 * [node] provides a [SourceSpan] for any error messages. 832 * [node] provides a [SourceSpan] for any error messages.
857 */ 833 */
858 Value invoke(MethodGenerator context, Node node, Value target, 834 Value invoke(MethodGenerator context, Node node, Value target,
859 Arguments args, [bool isDynamic=false]) { 835 Arguments args, [bool isDynamic=false]) {
860 // TODO(jimhug): Fix this hack for ensuring a method is resolved. 836 // TODO(jimhug): Fix this hack for ensuring a method is resolved.
861 if (parameters == null) { 837 if (parameters == null) {
862 world.info('surprised to need to resolve: ${declaringType.name}.$name'); 838 world.info('surprised to need to resolve: ${declaringType.name}.$name');
863 this.resolve(declaringType); 839 resolve();
864 } 840 }
865 841
866 declaringType.genMethod(this); 842 declaringType.genMethod(this);
867 843
868 if (isStatic || isFactory) { 844 if (isStatic || isFactory) {
869 // TODO(sigmund): can we avoid generating the entire type, but only what 845 // TODO(sigmund): can we avoid generating the entire type, but only what
870 // we need? 846 // we need?
871 declaringType.markUsed(); 847 declaringType.markUsed();
872 } 848 }
873 849
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
1208 var value = '${val0}${val1}'; 1184 var value = '${val0}${val1}';
1209 value = '"' + value.replaceAll('"', '\\"') + '"'; 1185 value = '"' + value.replaceAll('"', '\\"') + '"';
1210 return new EvaluatedValue(world.stringType, value, value, node.span); 1186 return new EvaluatedValue(world.stringType, value, value, node.span);
1211 } 1187 }
1212 1188
1213 // Ensure we generate toString on the right side 1189 // Ensure we generate toString on the right side
1214 args.values[0].invoke(context, 'toString', node, Arguments.EMPTY); 1190 args.values[0].invoke(context, 'toString', node, Arguments.EMPTY);
1215 return new Value(declaringType, '${target.code} + ${argsCode[0]}', 1191 return new Value(declaringType, '${target.code} + ${argsCode[0]}',
1216 node.span); 1192 node.span);
1217 } 1193 }
1218 } else if (declaringType.isNativeType) { 1194 } else if (declaringType.isNative) {
1219 if (name == '\$index') { 1195 if (name == '\$index') {
1220 // Note: this could technically propagate constness, but that's not 1196 // Note: this could technically propagate constness, but that's not
1221 // specified explicitly and the VM doesn't do that. 1197 // specified explicitly and the VM doesn't do that.
1222 return new Value(returnType, '${target.code}[${argsCode[0]}]', node.span ); 1198 return new Value(returnType, '${target.code}[${argsCode[0]}]', node.span );
1223 } else if (name == '\$setindex') { 1199 } else if (name == '\$setindex') {
1224 return new Value(returnType, 1200 return new Value(returnType,
1225 '${target.code}[${argsCode[0]}] = ${argsCode[1]}', node.span); 1201 '${target.code}[${argsCode[0]}] = ${argsCode[1]}', node.span);
1226 } 1202 }
1227 } 1203 }
1228 1204
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1267 world.gen.corejs.useSetIndex = true; 1243 world.gen.corejs.useSetIndex = true;
1268 } 1244 }
1269 1245
1270 // Fall back to normal method invocation. 1246 // Fall back to normal method invocation.
1271 var argsString = Strings.join(argsCode, ', '); 1247 var argsString = Strings.join(argsCode, ', ');
1272 return new Value(inferredResult, '${target.code}.$jsname($argsString)', 1248 return new Value(inferredResult, '${target.code}.$jsname($argsString)',
1273 node.span); 1249 node.span);
1274 } 1250 }
1275 1251
1276 1252
1277 resolve(Type inType) { 1253 resolve() {
1278 // TODO(jimhug): cut-and-paste-and-edit from Field.resolve 1254 // TODO(jimhug): cut-and-paste-and-edit from Field.resolve
1279 isStatic = inType.isTop; 1255 isStatic = declaringType.isTop;
1280 isConst = false; 1256 isConst = false;
1281 isFactory = false; 1257 isFactory = false;
1282 isAbstract = !declaringType.isClass; 1258 isAbstract = !declaringType.isClass;
1283 if (definition.modifiers != null) { 1259 if (definition.modifiers != null) {
1284 for (var mod in definition.modifiers) { 1260 for (var mod in definition.modifiers) {
1285 if (mod.kind == TokenKind.STATIC) { 1261 if (mod.kind == TokenKind.STATIC) {
1286 if (isStatic) { 1262 if (isStatic) {
1287 world.error('duplicate static modifier', mod.span); 1263 world.error('duplicate static modifier', mod.span);
1288 } 1264 }
1289 isStatic = true; 1265 isStatic = true;
(...skipping 20 matching lines...) Expand all
1310 } else { 1286 } else {
1311 world.error('${mod} modifier not allowed on method', mod.span); 1287 world.error('${mod} modifier not allowed on method', mod.span);
1312 } 1288 }
1313 } 1289 }
1314 } 1290 }
1315 1291
1316 if (isFactory) { 1292 if (isFactory) {
1317 isStatic = true; 1293 isStatic = true;
1318 } 1294 }
1319 1295
1296 if (definition.typeParameters != null) {
1297 if (!isFactory) {
1298 world.error(
1299 'Only factories are allowed to have explicit type parameters',
1300 definition.typeParameters[0].span);
1301 } else {
1302 typeParameters = definition.typeParameters;
1303 for (var tp in definition.typeParameters) {
1304 tp.enclosingElement = this;
1305 tp.resolve();
1306 }
1307 }
1308 }
1309
1320 // TODO(jimhug): need a better annotation for being an operator method 1310 // TODO(jimhug): need a better annotation for being an operator method
1321 if (isOperator && isStatic && !isCallMethod) { 1311 if (isOperator && isStatic && !isCallMethod) {
1322 world.error('operator method may not be static "${name}"', span); 1312 world.error('operator method may not be static "${name}"', span);
1323 } 1313 }
1324 1314
1325 if (isAbstract) { 1315 if (isAbstract) {
1326 if (definition.body != null && 1316 if (definition.body != null &&
1327 declaringType.definition is! FunctionTypeDefinition) { 1317 declaringType.definition is! FunctionTypeDefinition) {
1328 // TODO(jimhug): Creating function types for concrete methods is 1318 // TODO(jimhug): Creating function types for concrete methods is
1329 // steadily feeling uglier... 1319 // steadily feeling uglier...
1330 world.error('abstract method can not have a body', span); 1320 world.error('abstract method can not have a body', span);
1331 } 1321 }
1332 if (isStatic && 1322 if (isStatic &&
1333 declaringType.definition is! FunctionTypeDefinition) { 1323 declaringType.definition is! FunctionTypeDefinition) {
1334 world.error('static method can not be abstract', span); 1324 world.error('static method can not be abstract', span);
1335 } 1325 }
1336 } else { 1326 } else {
1337 if (definition.body == null && !isConstructor) { 1327 if (definition.body == null && !isConstructor) {
1338 world.error('method needs a body', span); 1328 world.error('method needs a body', span);
1339 } 1329 }
1340 } 1330 }
1341 1331
1342 if (isConstructor) { 1332 if (isConstructor && !isFactory) {
1343 returnType = declaringType; 1333 returnType = declaringType;
1344 } else { 1334 } else {
1345 // TODO(jimhug): Unify this check and the below with method's 1335 returnType = resolveType(definition.returnType, false);
1346 // resolveType method - requires cleaning up inType stuff.
1347 returnType = inType.resolveType(definition.returnType, false);
1348
1349 if (isStatic && returnType.hasTypeParams) {
1350 world.error('using type parameter in static context',
1351 definition.returnType.span);
1352 }
1353 } 1336 }
1354 parameters = []; 1337 parameters = [];
1355 for (var formal in definition.formals) { 1338 for (var formal in definition.formals) {
1356 var param = new Parameter(formal); 1339 // TODO(jimhug): Clean up construction of Parameters.
1357 param.resolve(this, inType); 1340 var param = new Parameter(formal, this);
1341 param.resolve();
1358 parameters.add(param); 1342 parameters.add(param);
1359 } 1343 }
1360 1344
1361 if (!isLambda) { 1345 if (!isLambda) {
1362 library._addMember(this); 1346 library._addMember(this);
1363 } 1347 }
1364 } 1348 }
1365
1366 Type findTypeVariable(TypeReference node, bool isRequired) {
1367 if (!this.isFactory || node is! NameTypeReference) {
1368 return super.resolveType(node, isRequired);
1369 } else {
1370 // TODO(ahe): We cannot find any type variables as they aren't
1371 // recorded. So we turn this in to a warning instead.
1372 return super.resolveType(node, false);
1373 }
1374 }
1375
1376 Type resolveType(TypeReference node, bool isRequired) {
1377 if (node !== null && this.isFactory && isRequired) {
1378 if (node is GenericTypeReference) {
1379 // TODO(ahe): This is bascially a copy of code in
1380 // DefinedType.resolveType. More checks should be performed,
1381 // such as bounds check, but the code is structured in a way
1382 // that makes this hard.
1383 GenericTypeReference genericReference = node;
1384 var baseType = super.resolveType(genericReference.baseType, isRequired);
1385 var typeArguments = [];
1386 for (TypeReference ref in genericReference.typeArguments) {
1387 // TODO(ahe): This let us ignore T in new Foo<T>, but not in
1388 // new Foo<Foo<T>>.
1389 typeArguments.add(findTypeVariable(ref, isRequired));
1390 }
1391 node.type = baseType.getOrMakeConcreteType(typeArguments);
1392 return node.type;
1393 }
1394 }
1395 return super.resolveType(node, isRequired);
1396 }
1397 } 1349 }
1398 1350
1399 1351
1400 class MemberSet { 1352 class MemberSet {
1401 final String name; 1353 final String name;
1402 final List<Member> members; 1354 final List<Member> members;
1403 final String jsname; 1355 final String jsname;
1404 final bool isVar; 1356 final bool isVar;
1405 1357
1406 MemberSet(Member member, [bool isVar=false]): 1358 MemberSet(Member member, [bool isVar=false]):
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
1706 } 1658 }
1707 1659
1708 void forEach(void f(Member member)) { 1660 void forEach(void f(Member member)) {
1709 factories.forEach((_, Map constructors) { 1661 factories.forEach((_, Map constructors) {
1710 constructors.forEach((_, Member member) { 1662 constructors.forEach((_, Member member) {
1711 f(member); 1663 f(member);
1712 }); 1664 });
1713 }); 1665 });
1714 } 1666 }
1715 } 1667 }
OLDNEW
« no previous file with comments | « frog/library.dart ('k') | frog/parser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698