| 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; |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 List<Parameter> get parameters() => []; | 144 List<Parameter> get parameters() => []; |
| 145 | 145 |
| 146 // TODO(jmesserly): isDynamic isn't a great name for this, something better? | 146 // TODO(jmesserly): isDynamic isn't a great name for this, something better? |
| 147 abstract Value _get(MethodGenerator context, Node node, Value target, | 147 abstract Value _get(MethodGenerator context, Node node, Value target, |
| 148 [bool isDynamic]); | 148 [bool isDynamic]); |
| 149 | 149 |
| 150 abstract Value _set(MethodGenerator context, Node node, Value target, | 150 abstract Value _set(MethodGenerator context, Node node, Value target, |
| 151 Value value, [bool isDynamic]); | 151 Value value, [bool isDynamic]); |
| 152 | 152 |
| 153 bool canInvoke(MethodGenerator context, Arguments args) { | 153 bool canInvoke(MethodGenerator context, Arguments args) { |
| 154 // TODO(jimhug): Needs better source location? | 154 // No source location needed because canInvoke may not produce errors. |
| 155 return canGet && | 155 return canGet && |
| 156 new Value(returnType, null, null).canInvoke(context, '\$call', args); | 156 new Value(returnType, null, null).canInvoke(context, '\$call', args); |
| 157 } | 157 } |
| 158 | 158 |
| 159 Value invoke(MethodGenerator context, Node node, Value target, Arguments args, | 159 Value invoke(MethodGenerator context, Node node, Value target, Arguments args, |
| 160 [bool isDynamic=false]) { | 160 [bool isDynamic=false]) { |
| 161 var newTarget = _get(context, node, target, isDynamic); | 161 var newTarget = _get(context, node, target, isDynamic); |
| 162 return newTarget.invoke(context, '\$call', node, args, isDynamic); | 162 return newTarget.invoke(context, '\$call', node, args, isDynamic); |
| 163 } | 163 } |
| 164 | 164 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 | 217 |
| 218 bool canInvoke(MethodGenerator context, Arguments args) => false; | 218 bool canInvoke(MethodGenerator context, Arguments args) => false; |
| 219 bool get canGet() => true; | 219 bool get canGet() => true; |
| 220 bool get canSet() => false; | 220 bool get canSet() => false; |
| 221 | 221 |
| 222 void resolve(Type inType) {} | 222 void resolve(Type inType) {} |
| 223 | 223 |
| 224 Value _get(MethodGenerator context, Node node, Value target, | 224 Value _get(MethodGenerator context, Node node, Value target, |
| 225 [bool isDynamic=false]) { | 225 [bool isDynamic=false]) { |
| 226 // TODO(jmesserly): named args | 226 // TODO(jmesserly): named args |
| 227 return new Value(type, type.jsname, node.span, false, false, true); | 227 var ret = new Value(type, type.jsname, node.span, false); |
| 228 // TODO(jimhug): Replace with TypeValue. |
| 229 ret.isType = true; |
| 230 return ret; |
| 228 } | 231 } |
| 229 | 232 |
| 230 Value _set(MethodGenerator context, Node node, Value target, Value value, | 233 Value _set(MethodGenerator context, Node node, Value target, Value value, |
| 231 [bool isDynamic=false]) { | 234 [bool isDynamic=false]) { |
| 232 world.error('can not set type', type.definition.span); | 235 world.error('can not set type', type.definition.span); |
| 233 } | 236 } |
| 234 | 237 |
| 235 Value invoke(MethodGenerator context, Node node, Value target, Arguments args, | 238 Value invoke(MethodGenerator context, Node node, Value target, Arguments args, |
| 236 [bool isDynamic=false]) { | 239 [bool isDynamic=false]) { |
| 237 world.error('can not invoke type', type.definition.span); | 240 world.error('can not invoke type', type.definition.span); |
| (...skipping 918 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1156 | 1159 |
| 1157 // Ensure we generate toString on the right side | 1160 // Ensure we generate toString on the right side |
| 1158 args.values[0].invoke(context, 'toString', node, Arguments.EMPTY); | 1161 args.values[0].invoke(context, 'toString', node, Arguments.EMPTY); |
| 1159 return new Value(declaringType, '${target.code} + ${argsCode[0]}', | 1162 return new Value(declaringType, '${target.code} + ${argsCode[0]}', |
| 1160 node.span); | 1163 node.span); |
| 1161 } | 1164 } |
| 1162 } else if (declaringType.isNativeType) { | 1165 } else if (declaringType.isNativeType) { |
| 1163 if (name == '\$index') { | 1166 if (name == '\$index') { |
| 1164 // Note: this could technically propagate constness, but that's not | 1167 // Note: this could technically propagate constness, but that's not |
| 1165 // specified explicitly and the VM doesn't do that. | 1168 // specified explicitly and the VM doesn't do that. |
| 1166 // TODO(jmesserly): why are we using a return type of "var"? | 1169 return new Value(returnType, '${target.code}[${argsCode[0]}]', node.span
); |
| 1167 return new Value(null, '${target.code}[${argsCode[0]}]', node.span); | |
| 1168 } else if (name == '\$setindex') { | 1170 } else if (name == '\$setindex') { |
| 1169 return new Value(null, | 1171 return new Value(returnType, |
| 1170 '${target.code}[${argsCode[0]}] = ${argsCode[1]}', node.span); | 1172 '${target.code}[${argsCode[0]}] = ${argsCode[1]}', node.span); |
| 1171 } | 1173 } |
| 1172 } | 1174 } |
| 1173 | 1175 |
| 1174 // TODO(jimhug): Optimize null on lhs as well. | 1176 // TODO(jimhug): Optimize null on lhs as well. |
| 1175 if (name == '\$eq' || name == '\$ne') { | 1177 if (name == '\$eq' || name == '\$ne') { |
| 1176 final op = name == '\$eq' ? '==' : '!='; | 1178 final op = name == '\$eq' ? '==' : '!='; |
| 1177 if (allConst) { | 1179 if (allConst) { |
| 1178 var val0 = target.dynamic.actualValue; | 1180 var val0 = target.dynamic.actualValue; |
| 1179 var val1 = args.values[0].dynamic.actualValue; | 1181 var val1 = args.values[0].dynamic.actualValue; |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1323 // TODO(jimhug): Always false, or is this needed? | 1325 // TODO(jimhug): Always false, or is this needed? |
| 1324 bool get isStatic() => members.length == 1 && members[0].isStatic; | 1326 bool get isStatic() => members.length == 1 && members[0].isStatic; |
| 1325 | 1327 |
| 1326 bool canInvoke(MethodGenerator context, Arguments args) => | 1328 bool canInvoke(MethodGenerator context, Arguments args) => |
| 1327 members.some((m) => m.canInvoke(context, args)); | 1329 members.some((m) => m.canInvoke(context, args)); |
| 1328 | 1330 |
| 1329 Value _makeError(Node node, Value target, String action) { | 1331 Value _makeError(Node node, Value target, String action) { |
| 1330 if (!target.type.isVar) { | 1332 if (!target.type.isVar) { |
| 1331 world.warning('could not find applicable $action for "$name"', node.span); | 1333 world.warning('could not find applicable $action for "$name"', node.span); |
| 1332 } | 1334 } |
| 1333 return new Value(null, '${target.code}.$jsname() /*no applicable $action*/', | 1335 return new Value(world.varType, |
| 1334 node.span); | 1336 '${target.code}.$jsname() /*no applicable $action*/', node.span); |
| 1335 } | 1337 } |
| 1336 | 1338 |
| 1337 bool _treatAsField; | 1339 bool _treatAsField; |
| 1338 bool get treatAsField() { | 1340 bool get treatAsField() { |
| 1339 if (_treatAsField == null) { | 1341 if (_treatAsField == null) { |
| 1340 _treatAsField = true; | 1342 _treatAsField = true; |
| 1341 for (var member in members) { | 1343 for (var member in members) { |
| 1342 if (member.requiresFieldSyntax) { | 1344 if (member.requiresFieldSyntax) { |
| 1343 _treatAsField = true; | 1345 _treatAsField = true; |
| 1344 break; | 1346 break; |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1466 | 1468 |
| 1467 Value _tryUnion(Value x, Value y, Node node) { | 1469 Value _tryUnion(Value x, Value y, Node node) { |
| 1468 if (x == null) return y; | 1470 if (x == null) return y; |
| 1469 var type = Type.union(x.type, y.type); | 1471 var type = Type.union(x.type, y.type); |
| 1470 if (x.code == y.code) { | 1472 if (x.code == y.code) { |
| 1471 if (type == x.type) { | 1473 if (type == x.type) { |
| 1472 return x; | 1474 return x; |
| 1473 } else if (x.isConst || y.isConst) { | 1475 } else if (x.isConst || y.isConst) { |
| 1474 world.internalError("unexpected: union of const values "); | 1476 world.internalError("unexpected: union of const values "); |
| 1475 } else { | 1477 } else { |
| 1476 return new Value(type, x.code, node.span, | 1478 // TODO(jimhug): This is icky - but this whole class needs cleanup. |
| 1477 x.isSuper && y.isSuper, | 1479 var ret = new Value(type, x.code, node.span); |
| 1478 x.needsTemp || y.needsTemp, | 1480 ret.isSuper = x.isSuper && y.isSuper; |
| 1479 x.isType && y.isType); | 1481 ret.needsTemp = x.needsTemp || y.needsTemp; |
| 1482 ret.isType = x.isType && y.isType; |
| 1483 return ret; |
| 1480 } | 1484 } |
| 1481 } else { | 1485 } else { |
| 1482 return new Value(type, null, node.span); | 1486 return new Value(type, null, node.span); |
| 1483 } | 1487 } |
| 1484 } | 1488 } |
| 1485 | 1489 |
| 1486 dumpAllMembers() { | 1490 dumpAllMembers() { |
| 1487 for (var member in members) { | 1491 for (var member in members) { |
| 1488 world.warning('hard-multi $name on ${member.declaringType.name}', | 1492 world.warning('hard-multi $name on ${member.declaringType.name}', |
| 1489 member.span); | 1493 member.span); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1574 } | 1578 } |
| 1575 | 1579 |
| 1576 void forEach(void f(Member member)) { | 1580 void forEach(void f(Member member)) { |
| 1577 factories.forEach((_, Map constructors) { | 1581 factories.forEach((_, Map constructors) { |
| 1578 constructors.forEach((_, Member member) { | 1582 constructors.forEach((_, Member member) { |
| 1579 f(member); | 1583 f(member); |
| 1580 }); | 1584 }); |
| 1581 }); | 1585 }); |
| 1582 } | 1586 } |
| 1583 } | 1587 } |
| OLD | NEW |