| 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 |
| 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 |