| 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 /** | 5 /** |
| 6 * Top level generator object for writing code and keeping track of | 6 * Top level generator object for writing code and keeping track of |
| 7 * dependencies. | 7 * dependencies. |
| 8 * | 8 * |
| 9 * Should have two compilation models, but only one implemented so far. | 9 * Should have two compilation models, but only one implemented so far. |
| 10 * | 10 * |
| (...skipping 814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 825 } | 825 } |
| 826 } | 826 } |
| 827 | 827 |
| 828 var body = method.definition.body; | 828 var body = method.definition.body; |
| 829 | 829 |
| 830 if (body == null && !method.isConstructor) { | 830 if (body == null && !method.isConstructor) { |
| 831 world.error('unexpected empty body for ${method.name}', | 831 world.error('unexpected empty body for ${method.name}', |
| 832 method.definition.span); | 832 method.definition.span); |
| 833 } | 833 } |
| 834 | 834 |
| 835 var initializerCall = null; |
| 836 final declaredInitializers = method.definition.initializers; |
| 835 if (initializers != null) { | 837 if (initializers != null) { |
| 836 for (var i in initializers) { | 838 for (var i in initializers) { |
| 837 writer.writeln(i); | 839 writer.writeln(i); |
| 838 } | 840 } |
| 839 final declaredInitializers = method.definition.initializers; | |
| 840 if (declaredInitializers != null) { | 841 if (declaredInitializers != null) { |
| 841 var initializerCall = null; | |
| 842 for (var init in declaredInitializers) { | 842 for (var init in declaredInitializers) { |
| 843 // TODO(jimhug): Lot's of correctness to verify here. | 843 // TODO(jimhug): Lot's of correctness to verify here. |
| 844 if (init is CallExpression) { | 844 if (init is CallExpression) { |
| 845 if (initializerCall != null) { | 845 if (initializerCall != null) { |
| 846 world.error('only one initializer redirecting call is allowed', | 846 world.error('only one initializer redirecting call is allowed', |
| 847 init.span); | 847 init.span); |
| 848 } | 848 } |
| 849 initializerCall = init; | 849 initializerCall = init; |
| 850 } else if (init is BinaryExpression | 850 } else if (init is BinaryExpression |
| 851 && TokenKind.kindFromAssign(init.op.kind) == 0) { | 851 && TokenKind.kindFromAssign(init.op.kind) == 0) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 866 left.span); | 866 left.span); |
| 867 continue; | 867 continue; |
| 868 } | 868 } |
| 869 | 869 |
| 870 initializedFields.add(f.name); | 870 initializedFields.add(f.name); |
| 871 writer.writeln('this.${f.jsname} = ${visitValue(init.y).code};'); | 871 writer.writeln('this.${f.jsname} = ${visitValue(init.y).code};'); |
| 872 } else { | 872 } else { |
| 873 world.error('invalid initializer', init.span); | 873 world.error('invalid initializer', init.span); |
| 874 } | 874 } |
| 875 } | 875 } |
| 876 | |
| 877 if (initializerCall != null) { | |
| 878 var target = _writeInitializerCall(initializerCall); | |
| 879 if (!target.isSuper) { | |
| 880 // when calling another constructor on the same class | |
| 881 // no other initialization is allowed | |
| 882 if (initializers.length > 0) { | |
| 883 for (var p in method.parameters) { | |
| 884 if (p.isInitializer) { | |
| 885 world.error( | |
| 886 'no initialization allowed on redirecting constructors', | |
| 887 p.definition.span); | |
| 888 break; | |
| 889 } | |
| 890 } | |
| 891 } | |
| 892 if (declaredInitializers.length > 1) { | |
| 893 var init = declaredInitializers[0] == initializerCall | |
| 894 ? declaredInitializers[1] : declaredInitializers[0]; | |
| 895 world.error( | |
| 896 'no initialization allowed on redirecting constructors', | |
| 897 init.span); | |
| 898 } | |
| 899 initializedFields = null; | |
| 900 } | |
| 901 // TODO(sigmund): check for initialization cycles | |
| 902 } else { | |
| 903 // TODO(jimhug): Is it an error not to have an initializerCall? | |
| 904 } | |
| 905 } | 876 } |
| 906 writer.comment('// Initializers done'); | 877 writer.comment('// Initializers done'); |
| 907 } | 878 } |
| 908 | 879 |
| 880 if (method.isConstructor && initializerCall == null) { |
| 881 var parentType = method.declaringType.parent; |
| 882 if (parentType != null && !parentType.isObject) { |
| 883 // TODO(jmesserly): we could omit this if all supertypes are using |
| 884 // default constructors. |
| 885 initializerCall = new CallExpression( |
| 886 new SuperExpression(method.span), [], method.span); |
| 887 } |
| 888 } |
| 889 |
| 890 if (initializerCall != null) { |
| 891 var target = _writeInitializerCall(initializerCall); |
| 892 if (!target.isSuper) { |
| 893 // when calling another constructor on the same class |
| 894 // no other initialization is allowed |
| 895 if (initializers.length > 0) { |
| 896 for (var p in method.parameters) { |
| 897 if (p.isInitializer) { |
| 898 world.error( |
| 899 'no initialization allowed on redirecting constructors', |
| 900 p.definition.span); |
| 901 break; |
| 902 } |
| 903 } |
| 904 } |
| 905 if (declaredInitializers != null && declaredInitializers.length > 1) { |
| 906 var init = declaredInitializers[0] == initializerCall |
| 907 ? declaredInitializers[1] : declaredInitializers[0]; |
| 908 world.error( |
| 909 'no initialization allowed on redirecting constructors', |
| 910 init.span); |
| 911 } |
| 912 initializedFields = null; |
| 913 } |
| 914 } |
| 915 |
| 909 // check that initialization was correct | 916 // check that initialization was correct |
| 910 if (initializedFields != null) { | 917 if (initializedFields != null) { |
| 911 for (var name in method.declaringType.members.getKeys()) { | 918 for (var name in method.declaringType.members.getKeys()) { |
| 912 var member = method.declaringType.members[name]; | 919 var member = method.declaringType.members[name]; |
| 913 if (member is FieldMember && member.isFinal && !member.isStatic | 920 if (member is FieldMember && member.isFinal && !member.isStatic |
| 914 && !initializedFields.contains(name)) { | 921 && !initializedFields.contains(name)) { |
| 915 world.error('Field "${name}" is final and was not initialized', | 922 world.error('Field "${name}" is final and was not initialized', |
| 916 method.definition.span); | 923 method.definition.span); |
| 917 } | 924 } |
| 918 } | 925 } |
| (...skipping 1333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2252 result.add(new Value(world.varType, '\$$i', null, /*needsTemp:*/false)); | 2259 result.add(new Value(world.varType, '\$$i', null, /*needsTemp:*/false)); |
| 2253 } | 2260 } |
| 2254 for (int i = bareCount; i < length; i++) { | 2261 for (int i = bareCount; i < length; i++) { |
| 2255 var name = getName(i); | 2262 var name = getName(i); |
| 2256 if (name == null) name = '\$$i'; | 2263 if (name == null) name = '\$$i'; |
| 2257 result.add(new Value(world.varType, name, null, /*needsTemp:*/false)); | 2264 result.add(new Value(world.varType, name, null, /*needsTemp:*/false)); |
| 2258 } | 2265 } |
| 2259 return new Arguments(nodes, result); | 2266 return new Arguments(nodes, result); |
| 2260 } | 2267 } |
| 2261 } | 2268 } |
| OLD | NEW |