| OLD | NEW |
| 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 | 8 |
| 9 String name; | 9 String name; |
| 10 Type type; | 10 Type type; |
| 11 | 11 |
| 12 Value value; | 12 Value value; |
| 13 | 13 |
| 14 Parameter(this.definition); | 14 Parameter(this.definition); |
| 15 | 15 |
| 16 resolve(Type inType) { | 16 resolve(Member method, Type inType) { |
| 17 name = definition.name.name; | 17 name = definition.name.name; |
| 18 type = inType.resolveType(definition.type, false); | 18 type = inType.resolveType(definition.type, false); |
| 19 |
| 20 if (method.isStatic && type.hasTypeParams) { |
| 21 world.error('using type parameter in static context', definition.span); |
| 22 } |
| 23 |
| 24 if (definition.value != null) { |
| 25 // To match VM, detect cases where value was not actually specified in |
| 26 // code and don't signal errors. |
| 27 // TODO(jimhug): Clean up after issue #352 is resolved. |
| 28 if (definition.value is NullExpression && |
| 29 definition.value.span.start == definition.span.start) { |
| 30 return; |
| 31 } |
| 32 if (method.isAbstract) { |
| 33 world.error('default value not allowed on abstract methods', |
| 34 definition.span); |
| 35 } else if (!inType.isClass) { |
| 36 world.error('default value not allowed on interface methods', |
| 37 definition.span); |
| 38 } else if (method.name == '\$call' && method.definition.body == null) { |
| 39 // TODO(jimhug): Need simpler way to detect "true" function types vs. |
| 40 // regular methods being used as function types for closures. |
| 41 world.error('default value not allowed on function type', |
| 42 definition.span); |
| 43 } |
| 44 } |
| 19 } | 45 } |
| 20 | 46 |
| 21 genValue(MethodMember method, MethodGenerator context) { | 47 genValue(MethodMember method, MethodGenerator context) { |
| 22 if (definition.value == null || value != null) return; | 48 if (definition.value == null || value != null) return; |
| 23 | 49 |
| 24 if (context == null) { // interface method | 50 if (context == null) { // interface method |
| 25 context = new MethodGenerator(method, null); | 51 context = new MethodGenerator(method, null); |
| 26 } | 52 } |
| 27 value = definition.value.visit(context); | 53 value = definition.value.visit(context); |
| 28 value = value.convertTo(context, type, definition.value); | 54 value = value.convertTo(context, type, definition.value); |
| 29 } | 55 } |
| 30 | 56 |
| 31 Parameter copyWithNewType(Type newType) { | 57 Parameter copyWithNewType(Type newType) { |
| 32 var ret = new Parameter(definition); | 58 var ret = new Parameter(definition); |
| 33 ret.type = newType; | 59 ret.type = newType; |
| 34 ret.name = name; | 60 ret.name = name; |
| 35 return ret; | 61 return ret; |
| 36 //ret.value = value; // TODO(jimhug): Any interaction with generics? | |
| 37 } | 62 } |
| 38 | 63 |
| 39 bool get isOptional() => definition != null && definition.value != null; | 64 bool get isOptional() => definition != null && definition.value != null; |
| 40 } | 65 } |
| 41 | 66 |
| 42 | 67 |
| 43 interface Named { | 68 interface Named { |
| 44 String get name(); | 69 String get name(); |
| 45 Library get library(); | 70 Library get library(); |
| 46 bool get isNative(); | 71 bool get isNative(); |
| (...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 if (definition.returnType.names != null) { | 598 if (definition.returnType.names != null) { |
| 574 return definition.returnType.names[0].name; | 599 return definition.returnType.names[0].name; |
| 575 } else if (definition.returnType.name != null) { | 600 } else if (definition.returnType.name != null) { |
| 576 return definition.returnType.name.name; | 601 return definition.returnType.name.name; |
| 577 } | 602 } |
| 578 world.internalError('no valid constructor name', definition.span); | 603 world.internalError('no valid constructor name', definition.span); |
| 579 } | 604 } |
| 580 | 605 |
| 581 Type get functionType() { | 606 Type get functionType() { |
| 582 if (_functionType == null) { | 607 if (_functionType == null) { |
| 583 _functionType = declaringType.library.getOrAddFunctionType(name, | 608 _functionType = library.getOrAddFunctionType(name, |
| 584 definition, declaringType); | 609 definition, declaringType); |
| 585 // TODO(jimhug): Better resolution checks. | 610 // TODO(jimhug): Better resolution checks. |
| 586 if (parameters == null) { | 611 if (parameters == null) { |
| 587 resolve(declaringType); | 612 resolve(declaringType); |
| 588 } | 613 } |
| 589 } | 614 } |
| 590 return _functionType; | 615 return _functionType; |
| 591 } | 616 } |
| 592 | 617 |
| 593 bool override(Member other) { | 618 bool override(Member other) { |
| (...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1183 returnType = inType.resolveType(definition.returnType, false); | 1208 returnType = inType.resolveType(definition.returnType, false); |
| 1184 | 1209 |
| 1185 if (isStatic && returnType.hasTypeParams) { | 1210 if (isStatic && returnType.hasTypeParams) { |
| 1186 world.error('using type parameter in static context', | 1211 world.error('using type parameter in static context', |
| 1187 definition.returnType.span); | 1212 definition.returnType.span); |
| 1188 } | 1213 } |
| 1189 } | 1214 } |
| 1190 parameters = []; | 1215 parameters = []; |
| 1191 for (var formal in definition.formals) { | 1216 for (var formal in definition.formals) { |
| 1192 var param = new Parameter(formal); | 1217 var param = new Parameter(formal); |
| 1193 param.resolve(inType); | 1218 param.resolve(this, inType); |
| 1194 parameters.add(param); | 1219 parameters.add(param); |
| 1195 if (isStatic && param.type.hasTypeParams) { | |
| 1196 world.error('using type parameter in static context', | |
| 1197 formal.span); | |
| 1198 } | |
| 1199 } | 1220 } |
| 1200 | 1221 |
| 1201 if (!isLambda) { | 1222 if (!isLambda) { |
| 1202 library._addMember(this); | 1223 library._addMember(this); |
| 1203 } | 1224 } |
| 1204 } | 1225 } |
| 1205 } | 1226 } |
| 1206 | 1227 |
| 1207 | 1228 |
| 1208 class MemberSet { | 1229 class MemberSet { |
| 1209 final String name; | 1230 final String name; |
| 1210 final List<Member> members; | 1231 final List<Member> members; |
| 1211 final String jsname; | 1232 final String jsname; |
| 1212 | 1233 |
| 1213 MemberSet(Member member): | 1234 MemberSet(Member member): |
| 1214 name = member.name, members = [member], jsname = member.jsname; | 1235 name = member.name, members = [member], jsname = member.jsname; |
| 1215 | 1236 |
| 1216 toString() => '$name:${members.length}'; | 1237 toString() => '$name:${members.length}'; |
| 1217 | 1238 |
| 1218 // TODO(jimhug): Still working towards the right logic for conflicts... | 1239 // TODO(jimhug): Still working towards the right logic for conflicts... |
| 1219 bool get containsProperties() => members.some((m) => m is PropertyMember); | 1240 bool get containsProperties() => members.some((m) => m is PropertyMember); |
| 1220 bool get containsMethods() => members.some((m) => m is MethodMember); | 1241 bool get containsMethods() => members.some((m) => m is MethodMember); |
| 1221 | 1242 |
| 1222 void add(Member member) => members.add(member); | 1243 void add(Member member) => members.add(member); |
| 1223 | 1244 |
| 1224 bool canInvoke(MethodGenerator context, Arguments args) => | 1245 bool canInvoke(MethodGenerator context, Arguments args) => |
| 1225 members.some((m) => m.canInvoke(context, args)); | 1246 members.some((m) => m.canInvoke(context, args)); |
| 1226 | 1247 |
| 1227 Library get library() { | |
| 1228 var ret = members[0].declaringType.library; | |
| 1229 for (var m in members) { | |
| 1230 if (m.declaringType.library != ret) return null; | |
| 1231 } | |
| 1232 return ret; | |
| 1233 } | |
| 1234 | |
| 1235 Value _makeError(Node node, Value target, String action) { | 1248 Value _makeError(Node node, Value target, String action) { |
| 1236 if (!target.type.isVar) { | 1249 if (!target.type.isVar) { |
| 1237 world.warning('could not find applicable $action for "$name"', node.span); | 1250 world.warning('could not find applicable $action for "$name"', node.span); |
| 1238 } | 1251 } |
| 1239 return new Value(null, '${target.code}.$jsname() /*no applicable $action*/')
; | 1252 return new Value(null, '${target.code}.$jsname() /*no applicable $action*/')
; |
| 1240 } | 1253 } |
| 1241 | 1254 |
| 1242 bool _treatAsField; | 1255 bool _treatAsField; |
| 1243 bool get treatAsField() { | 1256 bool get treatAsField() { |
| 1244 if (_treatAsField == null) { | 1257 if (_treatAsField == null) { |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1477 } | 1490 } |
| 1478 | 1491 |
| 1479 void forEach(void f(Member member)) { | 1492 void forEach(void f(Member member)) { |
| 1480 factories.forEach((_, Map constructors) { | 1493 factories.forEach((_, Map constructors) { |
| 1481 constructors.forEach((_, Member member) { | 1494 constructors.forEach((_, Member member) { |
| 1482 f(member); | 1495 f(member); |
| 1483 }); | 1496 }); |
| 1484 }); | 1497 }); |
| 1485 } | 1498 } |
| 1486 } | 1499 } |
| OLD | NEW |