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

Side by Side Diff: frog/member.dart

Issue 9143001: Fixes 2 tests and a crash (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 11 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) 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 Member method;
9 9
10 String name; 10 String name;
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 if (declaringType.isHiddenNativeType) { 414 if (declaringType.isHiddenNativeType) {
415 // TODO: Could warn at parse time. 415 // TODO: Could warn at parse time.
416 world.error('static field of hidden native type is inaccessible', 416 world.error('static field of hidden native type is inaccessible',
417 node.span); 417 node.span);
418 } 418 }
419 return new Value(type, '${declaringType.jsname}.$jsname', node.span); 419 return new Value(type, '${declaringType.jsname}.$jsname', node.span);
420 } else { 420 } else {
421 return new Value(type, 421 return new Value(type,
422 '\$globals.${declaringType.jsname}_$jsname', node.span); 422 '\$globals.${declaringType.jsname}_$jsname', node.span);
423 } 423 }
424 } else if (target.isConst && isFinal) { 424 }
425 /*else if (target.isConst && isFinal) {
Jennifer Messerly 2012/01/09 19:06:54 remove? or is this a todo
jimhug 2012/01/09 21:34:30 Was a todo - but then I decided on something diffe
425 // take advantage of consts and retrieve the value directly if possible 426 // take advantage of consts and retrieve the value directly if possible
426 var constTarget = target is GlobalValue ? target.dynamic.exp : target; 427 var constTarget = target is GlobalValue ? target.dynamic.exp : target;
427 if (constTarget is ConstObjectValue) { 428 if (constTarget is ConstObjectValue) {
428 return constTarget.fields[name]; 429 return constTarget.fields[name];
429 } else if (constTarget.type == world.stringType && name == 'length') { 430 } else if (constTarget.type == world.stringType && name == 'length') {
430 return new Value(type, '${constTarget.actualValue.length}', node.span); 431 return new Value(type, '${constTarget.actualValue.length}', node.span);
431 } 432 }
432 } 433 }*/
433 return new Value(type, '${target.code}.$jsname', node.span); 434 return new Value(type, '${target.code}.$jsname', node.span);
434 } 435 }
435 436
436 Value _set(MethodGenerator context, Node node, Value target, Value value, 437 Value _set(MethodGenerator context, Node node, Value target, Value value,
437 [bool isDynamic=false]) { 438 [bool isDynamic=false]) {
438 var lhs = _get(context, node, target, isDynamic); 439 var lhs = _get(context, node, target, isDynamic);
439 value = value.convertTo(context, type, isDynamic); 440 value = value.convertTo(context, type, isDynamic);
440 return new Value(type, '${lhs.code} = ${value.code}', node.span); 441 return new Value(type, '${lhs.code} = ${value.code}', node.span);
441 } 442 }
442 } 443 }
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
931 } 932 }
932 933
933 int bareCount = args.bareCount; 934 int bareCount = args.bareCount;
934 for (int i = 0; i < bareCount; i++) { 935 for (int i = 0; i < bareCount; i++) {
935 var arg = args.values[i]; 936 var arg = args.values[i];
936 if (i >= parameters.length) { 937 if (i >= parameters.length) {
937 var msg = _argCountMsg(args.length, parameters.length); 938 var msg = _argCountMsg(args.length, parameters.length);
938 return _argError(context, node, target, args, msg, i); 939 return _argError(context, node, target, args, msg, i);
939 } 940 }
940 arg = arg.convertTo(context, parameters[i].type, isDynamic); 941 arg = arg.convertTo(context, parameters[i].type, isDynamic);
941 if (isConst && arg.isConst) { 942 argsCode.add(arg.code);
Jennifer Messerly 2012/01/09 19:06:54 yay
942 argsCode.add(arg.canonicalCode);
943 } else {
944 argsCode.add(arg.code);
945 }
946 } 943 }
947 944
948 int namedArgsUsed = 0; 945 int namedArgsUsed = 0;
949 if (bareCount < parameters.length) { 946 if (bareCount < parameters.length) {
950 genParameterValues(); 947 genParameterValues();
951 948
952 for (int i = bareCount; i < parameters.length; i++) { 949 for (int i = bareCount; i < parameters.length; i++) {
953 var arg = args.getValue(parameters[i].name); 950 var arg = args.getValue(parameters[i].name);
954 if (arg == null) { 951 if (arg == null) {
955 arg = parameters[i].value; 952 arg = parameters[i].value;
956 } else { 953 } else {
957 arg = arg.convertTo(context, parameters[i].type, isDynamic); 954 arg = arg.convertTo(context, parameters[i].type, isDynamic);
958 namedArgsUsed++; 955 namedArgsUsed++;
959 } 956 }
960 957
961 if (arg == null || !parameters[i].isOptional) { 958 if (arg == null || !parameters[i].isOptional) {
962 var msg = _argCountMsg(Math.min(i, args.length), i + 1, atLeast:true); 959 var msg = _argCountMsg(Math.min(i, args.length), i + 1, atLeast:true);
963 return _argError(context, node, target, args, msg, i); 960 return _argError(context, node, target, args, msg, i);
964 } else { 961 } else {
965 argsCode.add(isConst && arg.isConst 962 argsCode.add(arg.code);
966 ? arg.canonicalCode : arg.code);
967 } 963 }
968 } 964 }
969 Arguments.removeTrailingNulls(argsCode); 965 Arguments.removeTrailingNulls(argsCode);
970 } 966 }
971 967
972 if (namedArgsUsed < args.nameCount) { 968 if (namedArgsUsed < args.nameCount) {
973 // Find the unused argument name 969 // Find the unused argument name
974 var seen = new Set<String>(); 970 var seen = new Set<String>();
975 for (int i = bareCount; i < args.length; i++) { 971 for (int i = bareCount; i < args.length; i++) {
976 var name = args.getName(i); 972 var name = args.getName(i);
(...skipping 29 matching lines...) Expand all
1006 node.span); 1002 node.span);
1007 } 1003 }
1008 1004
1009 if (isOperator) { 1005 if (isOperator) {
1010 return _invokeBuiltin(context, node, target, args, argsCode, isDynamic); 1006 return _invokeBuiltin(context, node, target, args, argsCode, isDynamic);
1011 } 1007 }
1012 1008
1013 if (isFactory) { 1009 if (isFactory) {
1014 assert(target.isType); 1010 assert(target.isType);
1015 return new Value(target.type, '$generatedFactoryName($argsString)', 1011 return new Value(target.type, '$generatedFactoryName($argsString)',
1016 node.span); 1012 node !== null ? node.span : null);
1017 } 1013 }
1018 1014
1019 if (isStatic) { 1015 if (isStatic) {
1020 if (declaringType.isTop) { 1016 if (declaringType.isTop) {
1021 // TODO(jimhug): Explore moving libraries into their own namespaces 1017 // TODO(jimhug): Explore moving libraries into their own namespaces
1022 return new Value(inferredResult, 1018 return new Value(inferredResult,
1023 '$jsname($argsString)', node != null ? node.span : node); 1019 '$jsname($argsString)', node !== null ? node.span : null);
1024 } 1020 }
1025 return new Value(inferredResult, 1021 return new Value(inferredResult,
1026 '${declaringType.jsname}.$jsname($argsString)', node.span); 1022 '${declaringType.jsname}.$jsname($argsString)', node.span);
1027 } 1023 }
1028 1024
1029 var code = '${target.code}.$jsname($argsString)'; 1025 var code = '${target.code}.$jsname($argsString)';
1030 // optimize expressions which we know statically their value. 1026 // optimize expressions which we know statically their value.
1027 // ????
Jennifer Messerly 2012/01/09 19:06:54 is this a TODO?
jimhug 2012/01/09 21:34:30 Done.
1028 /*
1031 if (target.isConst) { 1029 if (target.isConst) {
1032 if (target is GlobalValue) { 1030 if (target is GlobalValue) {
1033 target = target.dynamic.exp; // TODO: an inline "cast" would be nice. 1031 target = target.dynamic.exp; // TODO: an inline "cast" would be nice.
1034 } 1032 }
1035 if (name == 'get:length') { 1033 if (name == 'get:length') {
1036 if (target is ConstListValue || target is ConstMapValue) { 1034 if (target is ConstListValue || target is ConstMapValue) {
1037 code = '${target.dynamic.values.length}'; 1035 code = '${target.dynamic.values.length}';
1038 } 1036 }
1039 } else if (name == 'isEmpty') { 1037 } else if (name == 'isEmpty') {
1040 if (target is ConstListValue || target is ConstMapValue) { 1038 if (target is ConstListValue || target is ConstMapValue) {
1041 code = '${target.dynamic.values.isEmpty()}'; 1039 code = '${target.dynamic.values.isEmpty()}';
1042 } 1040 }
1043 } 1041 }
1044 } 1042 }
1043 */
1045 1044
1046 // TODO(jmesserly): factor this better 1045 // TODO(jmesserly): factor this better
Jennifer Messerly 2012/01/09 19:06:54 Not your change, but I noticed that this block of
jimhug 2012/01/09 21:34:30 I'm not sure I understand the ramifications of rem
1047 if (name == 'get:typeName' && declaringType.library.isDom) { 1046 if (name == 'get:typeName' && declaringType.library.isDom) {
1048 world.gen.corejs.ensureTypeNameOf(); 1047 world.gen.corejs.ensureTypeNameOf();
1049 } 1048 }
1050 1049
1051 return new Value(inferredResult, code, node.span); 1050 return new Value(inferredResult, code, node.span);
1052 } 1051 }
1053 1052
1054 Value _invokeConstructor(MethodGenerator context, Node node, 1053 Value _invokeConstructor(MethodGenerator context, Node node,
1055 Value target, Arguments args, argsString) { 1054 Value target, Arguments args, argsString) {
1056 declaringType.markUsed(); 1055 declaringType.markUsed();
1057 1056
1058 String ctor = constructorName; 1057 String ctor = constructorName;
1059 if (ctor != '') ctor = '.${ctor}\$ctor'; 1058 if (ctor != '') ctor = '.${ctor}\$ctor';
1060 1059
1061 if (!target.isType) { 1060 if (!target.isType) {
1062 // initializer call to another constructor 1061 // initializer call to another constructor
1063 var code = '${declaringType.nativeName}${ctor}.call($argsString)'; 1062 var code = '${declaringType.nativeName}${ctor}.call($argsString)';
1064 return new Value(target.type, code, node.span); 1063 return new Value(target.type, code, node.span);
1065 } else { 1064 } else {
1066
1067 var code = 'new ${declaringType.nativeName}${ctor}($argsString)'; 1065 var code = 'new ${declaringType.nativeName}${ctor}($argsString)';
1068 1066
1069 // TODO(jmesserly): using the "node" here feels really hacky 1067 // TODO(jmesserly): using the "node" here feels really hacky
1070 if (isConst && node is NewExpression && node.dynamic.isConst) { 1068 if (isConst && node is NewExpression && node.dynamic.isConst) {
1071 return _invokeConstConstructor(node, code, target, args); 1069 return _invokeConstConstructor(node, code, target, args);
1072 } else { 1070 } else {
1073 final span = node != null ? node.span : target.span; 1071 final span = node != null ? node.span : target.span;
1074 return new Value(target.type, code, span); 1072 return new Value(target.type, code, span);
1075 } 1073 }
1076 } 1074 }
(...skipping 11 matching lines...) Expand all
1088 * class B { 1086 * class B {
1089 * final int y; 1087 * final int y;
1090 * const B() : y = 0, super(1); 1088 * const B() : y = 0, super(1);
1091 * const B.a(this.y, x) : super(x); 1089 * const B.a(this.y, x) : super(x);
1092 * const B.b(v) : this.a(v, 1); 1090 * const B.b(v) : this.a(v, 1);
1093 * } 1091 * }
1094 * :] 1092 * :]
1095 */ 1093 */
1096 Value _invokeConstConstructor( 1094 Value _invokeConstConstructor(
1097 Node node, String code, Value target, Arguments args) { 1095 Node node, String code, Value target, Arguments args) {
1096 // TODO(jimhug): This should be low-hanging fruit for abstract eval!
1097
1098 // Statically compute the actual value for every field in the const object. 1098 // Statically compute the actual value for every field in the const object.
1099 final fields = new Map<String, EvaluatedValue>(); 1099 final fields = new Map<String, Value>();
1100 1100
1101 // First deduce the value for fields initialized with the 'this.x' syntax. 1101 // First deduce the value for fields initialized with the 'this.x' syntax.
1102 for (int i = 0; i < parameters.length; i++) { 1102 for (int i = 0; i < parameters.length; i++) {
1103 var param = parameters[i]; 1103 var param = parameters[i];
1104 if (param.isInitializer) { 1104 if (param.isInitializer) {
1105 var value = null; 1105 var value = null;
1106 if (i < args.length) { 1106 if (i < args.length) {
1107 value = args.values[i]; 1107 value = args.values[i];
1108 } else { // named arguments 1108 } else { // named arguments
1109 value = args.getValue(param.name); 1109 value = args.getValue(param.name);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1176 world.error('const class "${declaringType.name}" has non-final ' 1176 world.error('const class "${declaringType.name}" has non-final '
1177 + 'field "${f.name}"', f.span); 1177 + 'field "${f.name}"', f.span);
1178 } 1178 }
1179 if (f.value != null) { 1179 if (f.value != null) {
1180 fields[f.name] = f.computeValue(); 1180 fields[f.name] = f.computeValue();
1181 } 1181 }
1182 } 1182 }
1183 } 1183 }
1184 1184
1185 return world.gen.globalForConst( 1185 return world.gen.globalForConst(
1186 new ConstObjectValue(target.type, fields, code, node.span), 1186 new ObjectValue(fields, true, target.type, code, node.span),
1187 args.values); 1187 args.values);
1188 } 1188 }
1189 1189
1190 1190
1191 Value _invokeBuiltin(MethodGenerator context, Node node, Value target, 1191 Value _invokeBuiltin(MethodGenerator context, Node node, Value target,
1192 Arguments args, argsCode, bool isDynamic) { 1192 Arguments args, argsCode, bool isDynamic) {
1193 var allConst = target.isConst && args.values.every((arg) => arg.isConst); 1193 var allConst = target.isConst && args.values.every((arg) => arg.isConst);
1194 1194
1195 // Handle some fast paths for Number, String, List and DOM. 1195 // Handle some fast paths for Number, String, List and DOM.
1196 if (declaringType.isNum) { 1196 if (declaringType.isNum) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1237 1237
1238 // Note: unfortunatelly bit operations fail on doubles in dartvm 1238 // Note: unfortunatelly bit operations fail on doubles in dartvm
1239 case ':bit_not': value = (~ival0).toDouble(); break; 1239 case ':bit_not': value = (~ival0).toDouble(); break;
1240 case ':bit_or': value = (ival0 | ival1).toDouble(); break; 1240 case ':bit_or': value = (ival0 | ival1).toDouble(); break;
1241 case ':bit_xor': value = (ival0 ^ ival1).toDouble(); break; 1241 case ':bit_xor': value = (ival0 ^ ival1).toDouble(); break;
1242 case ':bit_and': value = (ival0 & ival1).toDouble(); break; 1242 case ':bit_and': value = (ival0 & ival1).toDouble(); break;
1243 case ':shl': value = (ival0 << ival1).toDouble(); break; 1243 case ':shl': value = (ival0 << ival1).toDouble(); break;
1244 case ':sar': value = (ival0 >> ival1).toDouble(); break; 1244 case ':sar': value = (ival0 >> ival1).toDouble(); break;
1245 case ':shr': value = (ival0 >>> ival1).toDouble(); break; 1245 case ':shr': value = (ival0 >>> ival1).toDouble(); break;
1246 } 1246 }
1247 return new EvaluatedValue(inferredResult, value, "$value", node.span); 1247 if (inferredResult.isInt) {
1248 return Value.fromInt(value.toInt(), node.span);
1249 } else if (inferredResult.isDouble) {
1250 return Value.fromDouble(value.toDouble(), node.span);
1251 } else if (inferredResult.isNum) {
1252 // TODO(jimhug): Number type system is flawed here...
1253 return Value.fromDouble(value.toDouble(), node.span);
1254 } else if (inferredResult.isBool) {
1255 return Value.fromBool(value, node.span);
1256 } else {
1257 world.internalError(
1258 'unsupported const result type "${inferredResult.name}"',
1259 node.span);
1260 }
1248 } 1261 }
1249 } else if (declaringType.isString) { 1262 } else if (declaringType.isString) {
1250 if (name == ':index') { 1263 if (name == ':index') {
1251 // Note: this could technically propagate constness, but that's not 1264 // Note: this could technically propagate constness, but that's not
1252 // specified explicitly and the VM doesn't do that. 1265 // specified explicitly and the VM doesn't do that.
1253 return new Value(declaringType, '${target.code}[${argsCode[0]}]', 1266 return new Value(declaringType, '${target.code}[${argsCode[0]}]',
1254 node.span); 1267 node.span);
1255 } else if (name == ':add') { 1268 } else if (name == ':add') {
1256 if (allConst) { 1269 if (allConst) {
1257 final value = target.dynamic.actualValue + 1270 final value = target.dynamic.actualValue +
(...skipping 22 matching lines...) Expand all
1280 1293
1281 if (name == ':ne') { 1294 if (name == ':ne') {
1282 // Ensure == is generated. 1295 // Ensure == is generated.
1283 target.invoke(context, ':eq', node, args, isDynamic); 1296 target.invoke(context, ':eq', node, args, isDynamic);
1284 } 1297 }
1285 1298
1286 if (allConst) { 1299 if (allConst) {
1287 var val0 = target.dynamic.actualValue; 1300 var val0 = target.dynamic.actualValue;
1288 var val1 = args.values[0].dynamic.actualValue; 1301 var val1 = args.values[0].dynamic.actualValue;
1289 var newVal = name == ':eq' ? val0 == val1 : val0 != val1; 1302 var newVal = name == ':eq' ? val0 == val1 : val0 != val1;
1290 return new EvaluatedValue(world.nonNullBool, 1303 return Value.fromBool(newVal, node.span);
1291 newVal, "$newVal", node.span);
1292 } 1304 }
1293 // Optimize test when null is on the rhs. 1305 // Optimize test when null is on the rhs.
1294 if (argsCode[0] == 'null') { 1306 if (argsCode[0] == 'null') {
1295 return new Value(inferredResult, '${target.code} $op null', node.span); 1307 return new Value(inferredResult, '${target.code} $op null', node.span);
1296 } else if (target.type.isNum || target.type.isString) { 1308 } else if (target.type.isNum || target.type.isString) {
1297 // TODO(jimhug): Maybe check rhs. 1309 // TODO(jimhug): Maybe check rhs.
1298 return new Value(inferredResult, '${target.code} $op ${argsCode[0]}', 1310 return new Value(inferredResult, '${target.code} $op ${argsCode[0]}',
1299 node.span); 1311 node.span);
1300 } 1312 }
1301 world.gen.corejs.useOperator(name); 1313 world.gen.corejs.useOperator(name);
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after
1740 } 1752 }
1741 1753
1742 void forEach(void f(Member member)) { 1754 void forEach(void f(Member member)) {
1743 factories.forEach((_, Map constructors) { 1755 factories.forEach((_, Map constructors) {
1744 constructors.forEach((_, Member member) { 1756 constructors.forEach((_, Member member) {
1745 f(member); 1757 f(member);
1746 }); 1758 });
1747 }); 1759 });
1748 } 1760 }
1749 } 1761 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698