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 Member method; | 8 Member method; |
9 | 9 |
10 String name; | 10 String name; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
51 genValue(MethodMember method, MethodGenerator context) { | 51 genValue(MethodMember method, MethodGenerator context) { |
52 if (definition.value == null || value != null) return; | 52 if (definition.value == null || value != null) return; |
53 | 53 |
54 if (context == null) { // interface method | 54 if (context == null) { // interface method |
55 context = new MethodGenerator(method, null); | 55 context = new MethodGenerator(method, null); |
56 } | 56 } |
57 value = definition.value.visit(context); | 57 value = definition.value.visit(context); |
58 if (!value.isConst) { | 58 if (!value.isConst) { |
59 world.error('default parameter values must be constant', value.span); | 59 world.error('default parameter values must be constant', value.span); |
60 } | 60 } |
61 value = value.convertTo(context, type, definition.value); | 61 value = value.convertTo(context, type); |
62 } | 62 } |
63 | 63 |
64 Parameter copyWithNewType(Member newMethod, Type newType) { | 64 Parameter copyWithNewType(Member newMethod, Type newType) { |
65 var ret = new Parameter(definition, newMethod); | 65 var ret = new Parameter(definition, newMethod); |
66 ret.type = newType; | 66 ret.type = newType; |
67 ret.name = name; | 67 ret.name = name; |
68 ret.isInitializer = isInitializer; | 68 ret.isInitializer = isInitializer; |
69 return ret; | 69 return ret; |
70 } | 70 } |
71 | 71 |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
402 declaringType.markUsed(); | 402 declaringType.markUsed(); |
403 | 403 |
404 // Make sure to compute the value of all static fields, even if we don't | 404 // Make sure to compute the value of all static fields, even if we don't |
405 // use this value immediately. | 405 // use this value immediately. |
406 var cv = computeValue(); | 406 var cv = computeValue(); |
407 if (isFinal) { | 407 if (isFinal) { |
408 return cv; | 408 return cv; |
409 } | 409 } |
410 world.gen.hasStatics = true; | 410 world.gen.hasStatics = true; |
411 if (declaringType.isTop) { | 411 if (declaringType.isTop) { |
412 if (declaringType.library == world.dom) { | 412 if (declaringType.library.isDom) { |
413 // TODO(jmesserly): this check doesn't look right. | |
413 return new Value(type, '$jsname', node.span); | 414 return new Value(type, '$jsname', node.span); |
414 } else { | 415 } else { |
415 return new Value(type, '\$globals.$jsname', node.span); | 416 return new Value(type, '\$globals.$jsname', node.span); |
416 } | 417 } |
417 } else if (declaringType.isNative) { | 418 } else if (declaringType.isNative) { |
418 if (declaringType.isHiddenNativeType) { | 419 if (declaringType.isHiddenNativeType) { |
419 // TODO: Could warn at parse time. | 420 // TODO: Could warn at parse time. |
420 world.error('static field of hidden native type is inaccessible', | 421 world.error('static field of hidden native type is inaccessible', |
421 node.span); | 422 node.span); |
422 } | 423 } |
(...skipping 10 matching lines...) Expand all Loading... | |
433 } else if (constTarget.type == world.stringType && name == 'length') { | 434 } else if (constTarget.type == world.stringType && name == 'length') { |
434 return new Value(type, '${constTarget.actualValue.length}', node.span); | 435 return new Value(type, '${constTarget.actualValue.length}', node.span); |
435 } | 436 } |
436 } | 437 } |
437 return new Value(type, '${target.code}.$jsname', node.span); | 438 return new Value(type, '${target.code}.$jsname', node.span); |
438 } | 439 } |
439 | 440 |
440 Value _set(MethodGenerator context, Node node, Value target, Value value, | 441 Value _set(MethodGenerator context, Node node, Value target, Value value, |
441 [bool isDynamic=false]) { | 442 [bool isDynamic=false]) { |
442 var lhs = _get(context, node, target, isDynamic); | 443 var lhs = _get(context, node, target, isDynamic); |
443 value = value.convertTo(context, type, node, isDynamic); | 444 value = value.convertTo(context, type, isDynamic); |
444 return new Value(type, '${lhs.code} = ${value.code}', node.span); | 445 return new Value(type, '${lhs.code} = ${value.code}', node.span); |
445 } | 446 } |
446 } | 447 } |
447 | 448 |
448 class PropertyMember extends Member { | 449 class PropertyMember extends Member { |
449 MethodMember getter; | 450 MethodMember getter; |
450 MethodMember setter; | 451 MethodMember setter; |
451 | 452 |
452 Member _overriddenField; | 453 Member _overriddenField; |
453 | 454 |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
934 argsCode.add('this'); | 935 argsCode.add('this'); |
935 } | 936 } |
936 | 937 |
937 int bareCount = args.bareCount; | 938 int bareCount = args.bareCount; |
938 for (int i = 0; i < bareCount; i++) { | 939 for (int i = 0; i < bareCount; i++) { |
939 var arg = args.values[i]; | 940 var arg = args.values[i]; |
940 if (i >= parameters.length) { | 941 if (i >= parameters.length) { |
941 var msg = _argCountMsg(args.length, parameters.length); | 942 var msg = _argCountMsg(args.length, parameters.length); |
942 return _argError(context, node, target, args, msg, i); | 943 return _argError(context, node, target, args, msg, i); |
943 } | 944 } |
944 arg = arg.convertTo(context, parameters[i].type, node, isDynamic); | 945 arg = arg.convertTo(context, parameters[i].type, isDynamic); |
945 if (isConst && arg.isConst) { | 946 if (isConst && arg.isConst) { |
946 argsCode.add(arg.canonicalCode); | 947 argsCode.add(arg.canonicalCode); |
947 } else { | 948 } else { |
948 argsCode.add(arg.code); | 949 argsCode.add(arg.code); |
949 } | 950 } |
950 } | 951 } |
951 | 952 |
952 int namedArgsUsed = 0; | 953 int namedArgsUsed = 0; |
953 if (bareCount < parameters.length) { | 954 if (bareCount < parameters.length) { |
954 genParameterValues(); | 955 genParameterValues(); |
955 | 956 |
956 for (int i = bareCount; i < parameters.length; i++) { | 957 for (int i = bareCount; i < parameters.length; i++) { |
957 var arg = args.getValue(parameters[i].name); | 958 var arg = args.getValue(parameters[i].name); |
958 if (arg == null) { | 959 if (arg == null) { |
959 arg = parameters[i].value; | 960 arg = parameters[i].value; |
960 } else { | 961 } else { |
961 arg = arg.convertTo(context, parameters[i].type, node, isDynamic); | 962 arg = arg.convertTo(context, parameters[i].type, isDynamic); |
962 namedArgsUsed++; | 963 namedArgsUsed++; |
963 } | 964 } |
964 | 965 |
965 if (arg == null || !parameters[i].isOptional) { | 966 if (arg == null || !parameters[i].isOptional) { |
966 var msg = _argCountMsg(Math.min(i, args.length), i + 1, atLeast:true); | 967 var msg = _argCountMsg(Math.min(i, args.length), i + 1, atLeast:true); |
967 return _argError(context, node, target, args, msg, i); | 968 return _argError(context, node, target, args, msg, i); |
968 } else { | 969 } else { |
969 argsCode.add(isConst && arg.isConst | 970 argsCode.add(isConst && arg.isConst |
970 ? arg.canonicalCode : arg.code); | 971 ? arg.canonicalCode : arg.code); |
971 } | 972 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1041 code = '${target.dynamic.values.length}'; | 1042 code = '${target.dynamic.values.length}'; |
1042 } | 1043 } |
1043 } else if (name == 'isEmpty') { | 1044 } else if (name == 'isEmpty') { |
1044 if (target is ConstListValue || target is ConstMapValue) { | 1045 if (target is ConstListValue || target is ConstMapValue) { |
1045 code = '${target.dynamic.values.isEmpty()}'; | 1046 code = '${target.dynamic.values.isEmpty()}'; |
1046 } | 1047 } |
1047 } | 1048 } |
1048 } | 1049 } |
1049 | 1050 |
1050 // TODO(jmesserly): factor this better | 1051 // TODO(jmesserly): factor this better |
1051 if (name == 'get:typeName' && declaringType.library == world.dom) { | 1052 if (name == 'get:typeName' && declaringType.library.isDom) { |
1052 world.gen.corejs.ensureTypeNameOf(); | 1053 world.gen.corejs.ensureTypeNameOf(); |
1053 } | 1054 } |
1054 | 1055 |
1055 return new Value(inferredResult, code, node.span); | 1056 return new Value(inferredResult, code, node.span); |
1056 } | 1057 } |
1057 | 1058 |
1058 Value _invokeConstructor(MethodGenerator context, Node node, | 1059 Value _invokeConstructor(MethodGenerator context, Node node, |
1059 Value target, Arguments args, argsString) { | 1060 Value target, Arguments args, argsString) { |
1060 declaringType.markUsed(); | 1061 declaringType.markUsed(); |
1061 | 1062 |
1063 String ctor = constructorName; | |
1064 if (ctor != '') ctor = '.${ctor}\$ctor'; | |
1065 | |
1062 if (!target.isType) { | 1066 if (!target.isType) { |
1063 // initializer call to another constructor | 1067 // initializer call to another constructor |
1064 var code = (constructorName != '') | 1068 var code = '${declaringType.nativeName}${ctor}.call($argsString)'; |
1065 ? '${declaringType.jsname}.${constructorName}\$ctor.call($argsString)' | |
1066 : '${declaringType.jsname}.call($argsString)'; | |
1067 return new Value(target.type, code, node.span); | 1069 return new Value(target.type, code, node.span); |
1068 } else { | 1070 } else { |
1069 // If a hidden native class has a direct (non-factory) constructor, use | 1071 |
1070 // the native name. This will work if the name is available in the | 1072 var code = 'new ${declaringType.nativeName}${ctor}($argsString)'; |
1071 // execution environment, and will fail at run-time if the name is really | 1073 |
1072 // hidden. This lets the generated code run on some browsers before the | |
1073 // browser compat issue is finalized. | |
1074 var typeName = declaringType.isNative | |
1075 ? declaringType.nativeType.name | |
1076 : declaringType.jsname; | |
1077 var code = (constructorName != '') | |
1078 ? 'new ${typeName}.${constructorName}\$ctor($argsString)' | |
1079 : 'new ${typeName}($argsString)'; | |
1080 // TODO(jmesserly): using the "node" here feels really hacky | 1074 // TODO(jmesserly): using the "node" here feels really hacky |
Jennifer Messerly
2012/01/06 21:36:29
one cleanup I'd like to do:
if we're in visitNewE
jimhug
2012/01/11 19:09:53
Yes!
On 2012/01/06 21:36:29, John Messerly wrote:
| |
1081 if (isConst && node is NewExpression && node.dynamic.isConst) { | 1075 if (isConst && node is NewExpression && node.dynamic.isConst) { |
1082 return _invokeConstConstructor(node, code, target, args); | 1076 return _invokeConstConstructor(node, code, target, args); |
1083 } else { | 1077 } else { |
1084 return new Value(target.type, code, node.span); | 1078 final span = node != null ? node.span : target.span; |
1079 return new Value(target.type, code, span); | |
1085 } | 1080 } |
1086 } | 1081 } |
1087 } | 1082 } |
1088 | 1083 |
1089 /** | 1084 /** |
1090 * Special handling for const constructors so that so that: | 1085 * Special handling for const constructors so that so that: |
1091 * [: const B() === const B.a(0, 1) === const B.b(0) :] | 1086 * [: const B() === const B.a(0, 1) === const B.b(0) :] |
1092 * where: [: | 1087 * where: [: |
1093 * class A { | 1088 * class A { |
1094 * final int x; | 1089 * final int x; |
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1782 } | 1777 } |
1783 | 1778 |
1784 void forEach(void f(Member member)) { | 1779 void forEach(void f(Member member)) { |
1785 factories.forEach((_, Map constructors) { | 1780 factories.forEach((_, Map constructors) { |
1786 constructors.forEach((_, Member member) { | 1781 constructors.forEach((_, Member member) { |
1787 f(member); | 1782 f(member); |
1788 }); | 1783 }); |
1789 }); | 1784 }); |
1790 } | 1785 } |
1791 } | 1786 } |
OLD | NEW |