| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library dart2js.js_emitter.full_emitter.container_builder; | 5 library dart2js.js_emitter.full_emitter.container_builder; |
| 6 | 6 |
| 7 import '../../constants/values.dart'; | 7 import '../../constants/values.dart'; |
| 8 import '../../elements/elements.dart' | 8 import '../../elements/elements.dart' |
| 9 show | 9 show Element, Elements, MetadataAnnotation, MethodElement; |
| 10 Element, | 10 import '../../elements/entities.dart'; |
| 11 Elements, | 11 import '../../elements/names.dart'; |
| 12 FunctionSignature, | |
| 13 MetadataAnnotation, | |
| 14 MethodElement; | |
| 15 import '../../js/js.dart' as jsAst; | 12 import '../../js/js.dart' as jsAst; |
| 16 import '../../js/js.dart' show js; | 13 import '../../js/js.dart' show js; |
| 17 import '../js_emitter.dart' hide Emitter, EmitterFactory; | 14 import '../js_emitter.dart' hide Emitter, EmitterFactory; |
| 18 import '../model.dart'; | 15 import '../model.dart'; |
| 19 import 'emitter.dart'; | 16 import 'emitter.dart'; |
| 20 | 17 |
| 21 /// This class should morph into something that makes it easy to build | 18 /// This class should morph into something that makes it easy to build |
| 22 /// JavaScript representations of libraries, class-sides, and instance-sides. | 19 /// JavaScript representations of libraries, class-sides, and instance-sides. |
| 23 /// Initially, it is just a placeholder for code that is moved from | 20 /// Initially, it is just a placeholder for code that is moved from |
| 24 /// [CodeEmitterTask]. | 21 /// [CodeEmitterTask]. |
| 25 class ContainerBuilder extends CodeEmitterHelper { | 22 class ContainerBuilder extends CodeEmitterHelper { |
| 26 void addMemberMethod(DartMethod method, ClassBuilder builder) { | 23 void addMemberMethod(DartMethod method, ClassBuilder builder) { |
| 27 MethodElement member = method.element; | 24 FunctionEntity member = method.element; |
| 28 jsAst.Name name = method.name; | 25 jsAst.Name name = method.name; |
| 29 FunctionSignature parameters = member.functionSignature; | 26 ParameterStructure parameters = member.parameterStructure; |
| 30 jsAst.Expression code = method.code; | 27 jsAst.Expression code = method.code; |
| 31 bool needsStubs = method.parameterStubs.isNotEmpty; | 28 bool needsStubs = method.parameterStubs.isNotEmpty; |
| 32 bool canBeApplied = method.canBeApplied; | 29 bool canBeApplied = method.canBeApplied; |
| 33 bool canBeReflected = method.canBeReflected; | 30 bool canBeReflected = method.canBeReflected; |
| 34 bool canTearOff = method.needsTearOff; | 31 bool canTearOff = method.needsTearOff; |
| 35 jsAst.Name tearOffName = method.tearOffName; | 32 jsAst.Name tearOffName = method.tearOffName; |
| 36 bool isClosure = method is InstanceMethod && method.isClosureCallMethod; | 33 bool isClosure = method is InstanceMethod && method.isClosureCallMethod; |
| 37 jsAst.Name superAlias = method is InstanceMethod ? method.aliasName : null; | 34 jsAst.Name superAlias = method is InstanceMethod ? method.aliasName : null; |
| 38 bool hasSuperAlias = superAlias != null; | 35 bool hasSuperAlias = superAlias != null; |
| 39 jsAst.Expression memberTypeExpression = method.functionType; | 36 jsAst.Expression memberTypeExpression = method.functionType; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 | 105 |
| 109 jsAst.Literal callSelectorString; | 106 jsAst.Literal callSelectorString; |
| 110 if (method.callName == null) { | 107 if (method.callName == null) { |
| 111 callSelectorString = new jsAst.LiteralNull(); | 108 callSelectorString = new jsAst.LiteralNull(); |
| 112 } else { | 109 } else { |
| 113 callSelectorString = js.quoteName(method.callName); | 110 callSelectorString = js.quoteName(method.callName); |
| 114 } | 111 } |
| 115 | 112 |
| 116 // On [requiredParameterCount], the lower bit is set if this method can be | 113 // On [requiredParameterCount], the lower bit is set if this method can be |
| 117 // called reflectively. | 114 // called reflectively. |
| 118 int requiredParameterCount = parameters.requiredParameterCount << 1; | 115 int requiredParameterCount = parameters.requiredParameters << 1; |
| 119 if (member.isAccessor) requiredParameterCount++; | 116 if (member.isGetter || member.isSetter) requiredParameterCount++; |
| 120 | 117 |
| 121 int optionalParameterCount = parameters.optionalParameterCount << 1; | 118 int optionalParameterCount = parameters.optionalParameters << 1; |
| 122 if (parameters.optionalParametersAreNamed) optionalParameterCount++; | 119 if (parameters.namedParameters.isNotEmpty) optionalParameterCount++; |
| 123 | 120 |
| 124 List tearOffInfo = [callSelectorString]; | 121 List tearOffInfo = [callSelectorString]; |
| 125 | 122 |
| 126 for (ParameterStubMethod stub in method.parameterStubs) { | 123 for (ParameterStubMethod stub in method.parameterStubs) { |
| 127 jsAst.Name invocationName = stub.name; | 124 jsAst.Name invocationName = stub.name; |
| 128 emitter.interceptorEmitter | 125 emitter.interceptorEmitter |
| 129 .recordMangledNameOfMemberMethod(member, invocationName); | 126 .recordMangledNameOfMemberMethod(member, invocationName); |
| 130 | 127 |
| 131 expressions.add(stub.code); | 128 expressions.add(stub.code); |
| 132 if (member.isInstanceMember) { | 129 if (member.isInstanceMember) { |
| 133 expressions.add(js.quoteName(invocationName)); | 130 expressions.add(js.quoteName(invocationName)); |
| 134 } | 131 } |
| 135 jsAst.Name callName = stub.callName; | 132 jsAst.Name callName = stub.callName; |
| 136 jsAst.Literal callSelectorString = | 133 jsAst.Literal callSelectorString = |
| 137 (callName == null) ? new jsAst.LiteralNull() : js.quoteName(callName); | 134 (callName == null) ? new jsAst.LiteralNull() : js.quoteName(callName); |
| 138 tearOffInfo.add(callSelectorString); | 135 tearOffInfo.add(callSelectorString); |
| 139 } | 136 } |
| 140 | 137 |
| 141 expressions | 138 expressions |
| 142 ..addAll(tearOffInfo) | 139 ..addAll(tearOffInfo) |
| 143 ..add((tearOffName == null || member.isAccessor) | 140 ..add((tearOffName == null || member.isGetter || member.isSetter) |
| 144 ? js("null") | 141 ? js("null") |
| 145 : js.quoteName(tearOffName)) | 142 : js.quoteName(tearOffName)) |
| 146 ..add(js.number(requiredParameterCount)) | 143 ..add(js.number(requiredParameterCount)) |
| 147 ..add(js.number(optionalParameterCount)) | 144 ..add(js.number(optionalParameterCount)) |
| 148 ..add(memberTypeExpression == null ? js("null") : memberTypeExpression) | 145 ..add(memberTypeExpression == null ? js("null") : memberTypeExpression) |
| 149 ..addAll(task.metadataCollector.reifyDefaultArguments(member)); | 146 ..addAll(task.metadataCollector.reifyDefaultArguments(member)); |
| 150 | 147 |
| 151 if (canBeReflected || canBeApplied) { | 148 if (canBeReflected || canBeApplied) { |
| 152 parameters.forEachParameter((Element parameter) { | 149 // TODO(johnniwinther): Support entities. |
| 150 MethodElement method = member; |
| 151 method.functionSignature.forEachParameter((Element parameter) { |
| 153 expressions.add(task.metadataCollector.reifyName(parameter.name)); | 152 expressions.add(task.metadataCollector.reifyName(parameter.name)); |
| 154 if (backend.mirrorsData.mustRetainMetadata) { | 153 if (backend.mirrorsData.mustRetainMetadata) { |
| 155 Iterable<jsAst.Expression> metadataIndices = | 154 Iterable<jsAst.Expression> metadataIndices = |
| 156 parameter.metadata.map((MetadataAnnotation annotation) { | 155 parameter.metadata.map((MetadataAnnotation annotation) { |
| 157 ConstantValue constant = | 156 ConstantValue constant = |
| 158 backend.constants.getConstantValueForMetadata(annotation); | 157 backend.constants.getConstantValueForMetadata(annotation); |
| 159 backend.constants.addCompileTimeConstantForEmission(constant); | 158 backend.constants.addCompileTimeConstantForEmission(constant); |
| 160 return task.metadataCollector.reifyMetadata(annotation); | 159 return task.metadataCollector.reifyMetadata(annotation); |
| 161 }); | 160 }); |
| 162 expressions.add(new jsAst.ArrayInitializer(metadataIndices.toList())); | 161 expressions.add(new jsAst.ArrayInitializer(metadataIndices.toList())); |
| 163 } | 162 } |
| 164 }); | 163 }); |
| 165 } | 164 } |
| 165 Name memberName = new Name(member.name, member.library); |
| 166 if (canBeReflected) { | 166 if (canBeReflected) { |
| 167 jsAst.LiteralString reflectionName; | 167 jsAst.LiteralString reflectionName; |
| 168 if (member.isConstructor) { | 168 if (member.isConstructor) { |
| 169 // TODO(herhut): This registers name as a mangled name. Do we need this | 169 // TODO(herhut): This registers name as a mangled name. Do we need this |
| 170 // given that we use a different name below? | 170 // given that we use a different name below? |
| 171 emitter.getReflectionName(member, name); | 171 emitter.getReflectionName(member, name); |
| 172 reflectionName = new jsAst.LiteralString( | 172 reflectionName = new jsAst.LiteralString( |
| 173 '"new ${Elements.reconstructConstructorName(member)}"'); | 173 '"new ${Elements.reconstructConstructorName(member)}"'); |
| 174 } else { | 174 } else { |
| 175 reflectionName = js.string(namer.privateName(member.memberName)); | 175 reflectionName = js.string(namer.privateName(memberName)); |
| 176 } | 176 } |
| 177 expressions | 177 expressions |
| 178 ..add(reflectionName) | 178 ..add(reflectionName) |
| 179 ..addAll(task.metadataCollector.computeMetadata(member)); | 179 ..addAll(task.metadataCollector.computeMetadata(member)); |
| 180 } else if (isClosure && canBeApplied) { | 180 } else if (isClosure && canBeApplied) { |
| 181 expressions.add(js.string(namer.privateName(member.memberName))); | 181 expressions.add(js.string(namer.privateName(memberName))); |
| 182 } | 182 } |
| 183 | 183 |
| 184 jsAst.ArrayInitializer arrayInit = | 184 jsAst.ArrayInitializer arrayInit = |
| 185 new jsAst.ArrayInitializer(expressions.toList()); | 185 new jsAst.ArrayInitializer(expressions.toList()); |
| 186 compiler.dumpInfoTask | 186 compiler.dumpInfoTask |
| 187 .registerElementAst(member, builder.addProperty(name, arrayInit)); | 187 .registerElementAst(member, builder.addProperty(name, arrayInit)); |
| 188 } | 188 } |
| 189 | 189 |
| 190 void addMemberField(Field field, ClassBuilder builder) { | 190 void addMemberField(Field field, ClassBuilder builder) { |
| 191 // For now, do nothing. | 191 // For now, do nothing. |
| 192 } | 192 } |
| 193 } | 193 } |
| OLD | NEW |