| 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.class_emitter; | 5 library dart2js.js_emitter.full_emitter.class_emitter; |
| 6 | 6 |
| 7 import '../../common.dart'; | 7 import '../../common.dart'; |
| 8 import '../../common/names.dart' show Names; | 8 import '../../common/names.dart' show Names; |
| 9 import '../../common_elements.dart'; | 9 import '../../common_elements.dart'; |
| 10 import '../../elements/resolution_types.dart' show ResolutionDartType; | 10 import '../../elements/resolution_types.dart' show ResolutionDartType; |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 assert(container is Library); | 123 assert(container is Library); |
| 124 assert(emitStatics); | 124 assert(emitStatics); |
| 125 fields = container.staticFieldsForReflection; | 125 fields = container.staticFieldsForReflection; |
| 126 } | 126 } |
| 127 | 127 |
| 128 var fieldMetadata = []; | 128 var fieldMetadata = []; |
| 129 bool hasMetadata = false; | 129 bool hasMetadata = false; |
| 130 bool fieldsAdded = false; | 130 bool fieldsAdded = false; |
| 131 | 131 |
| 132 for (Field field in fields) { | 132 for (Field field in fields) { |
| 133 FieldElement fieldElement = field.element; | 133 FieldEntity fieldElement = field.element; |
| 134 jsAst.Name name = field.name; | 134 jsAst.Name name = field.name; |
| 135 jsAst.Name accessorName = field.accessorName; | 135 jsAst.Name accessorName = field.accessorName; |
| 136 bool needsGetter = field.needsGetter; | 136 bool needsGetter = field.needsGetter; |
| 137 bool needsSetter = field.needsUncheckedSetter; | 137 bool needsSetter = field.needsUncheckedSetter; |
| 138 | 138 |
| 139 // Ignore needsCheckedSetter - that is handled below. | 139 // Ignore needsCheckedSetter - that is handled below. |
| 140 bool needsAccessor = (needsGetter || needsSetter); | 140 bool needsAccessor = (needsGetter || needsSetter); |
| 141 // We need to output the fields for non-native classes so we can auto- | 141 // We need to output the fields for non-native classes so we can auto- |
| 142 // generate the constructor. For native classes there are no | 142 // generate the constructor. For native classes there are no |
| 143 // constructors, so we don't need the fields unless we are generating | 143 // constructors, so we don't need the fields unless we are generating |
| (...skipping 25 matching lines...) Expand all Loading... |
| 169 fieldNameParts.add(name); | 169 fieldNameParts.add(name); |
| 170 if (field.needsInterceptedGetter) { | 170 if (field.needsInterceptedGetter) { |
| 171 emitter.interceptorEmitter.interceptorInvocationNames | 171 emitter.interceptorEmitter.interceptorInvocationNames |
| 172 .add(namer.getterForElement(fieldElement)); | 172 .add(namer.getterForElement(fieldElement)); |
| 173 } | 173 } |
| 174 // TODO(16168): The setter creator only looks at the getter-name. | 174 // TODO(16168): The setter creator only looks at the getter-name. |
| 175 // Even though the setter could avoid the interceptor convention we | 175 // Even though the setter could avoid the interceptor convention we |
| 176 // currently still need to add the additional argument. | 176 // currently still need to add the additional argument. |
| 177 if (field.needsInterceptedGetter || field.needsInterceptedSetter) { | 177 if (field.needsInterceptedGetter || field.needsInterceptedSetter) { |
| 178 emitter.interceptorEmitter.interceptorInvocationNames | 178 emitter.interceptorEmitter.interceptorInvocationNames |
| 179 .add(namer.setterForElement(fieldElement)); | 179 .add(namer.setterForMember(fieldElement)); |
| 180 } | 180 } |
| 181 | 181 |
| 182 int code = field.getterFlags + (field.setterFlags << 2); | 182 int code = field.getterFlags + (field.setterFlags << 2); |
| 183 if (code == 0) { | 183 if (code == 0) { |
| 184 reporter.internalError( | 184 reporter.internalError( |
| 185 fieldElement, 'Field code is 0 ($fieldElement).'); | 185 fieldElement, 'Field code is 0 ($fieldElement).'); |
| 186 } | 186 } |
| 187 fieldNameParts.add( | 187 fieldNameParts.add( |
| 188 js.stringPart(FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE])); | 188 js.stringPart(FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE])); |
| 189 } | 189 } |
| 190 // Fields can only be reflected if their declaring class is reflectable | 190 // Fields can only be reflected if their declaring class is reflectable |
| 191 // (as they are only accessible via [ClassMirror.declarations]). | 191 // (as they are only accessible via [ClassMirror.declarations]). |
| 192 // However, set/get operations can be performed on them, so they are | 192 // However, set/get operations can be performed on them, so they are |
| 193 // reflectable in some sense, which leads to [isAccessibleByReflection] | 193 // reflectable in some sense, which leads to [isAccessibleByReflection] |
| 194 // reporting `true`. | 194 // reporting `true`. |
| 195 if (backend.mirrorsData.isMemberAccessibleByReflection(fieldElement)) { | 195 if (backend.mirrorsData.isMemberAccessibleByReflection(fieldElement)) { |
| 196 fieldNameParts.add(new jsAst.LiteralString('-')); | 196 fieldNameParts.add(new jsAst.LiteralString('-')); |
| 197 if (fieldElement.isTopLevel || | 197 if (fieldElement.isTopLevel || |
| 198 backend.mirrorsData | 198 backend.mirrorsData |
| 199 .isClassAccessibleByReflection(fieldElement.enclosingClass)) { | 199 .isClassAccessibleByReflection(fieldElement.enclosingClass)) { |
| 200 ResolutionDartType type = fieldElement.type; | 200 // TODO(johnniwinther): Support field entities. |
| 201 FieldElement element = fieldElement; |
| 202 ResolutionDartType type = element.type; |
| 201 fieldNameParts.add(task.metadataCollector.reifyType(type)); | 203 fieldNameParts.add(task.metadataCollector.reifyType(type)); |
| 202 } | 204 } |
| 203 } | 205 } |
| 204 jsAst.Literal fieldNameAst = js.concatenateStrings(fieldNameParts); | 206 jsAst.Literal fieldNameAst = js.concatenateStrings(fieldNameParts); |
| 205 builder.addField(fieldNameAst); | 207 builder.addField(fieldNameAst); |
| 206 // Add 1 because adding a field to the class also requires a comma | 208 // Add 1 because adding a field to the class also requires a comma |
| 207 compiler.dumpInfoTask.registerElementAst(fieldElement, fieldNameAst); | 209 compiler.dumpInfoTask.registerElementAst(fieldElement, fieldNameAst); |
| 208 fieldsAdded = true; | 210 fieldsAdded = true; |
| 209 } | 211 } |
| 210 } | 212 } |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 | 362 |
| 361 // TODO(ahe): This method (generateClass) should return a jsAst.Expression. | 363 // TODO(ahe): This method (generateClass) should return a jsAst.Expression. |
| 362 jsAst.ObjectInitializer propertyValue = classBuilder.toObjectInitializer(); | 364 jsAst.ObjectInitializer propertyValue = classBuilder.toObjectInitializer(); |
| 363 compiler.dumpInfoTask | 365 compiler.dumpInfoTask |
| 364 .registerElementAst(classBuilder.element, propertyValue); | 366 .registerElementAst(classBuilder.element, propertyValue); |
| 365 enclosingBuilder.addProperty(className, propertyValue); | 367 enclosingBuilder.addProperty(className, propertyValue); |
| 366 | 368 |
| 367 String reflectionName = | 369 String reflectionName = |
| 368 emitter.getReflectionClassName(classEntity, className); | 370 emitter.getReflectionClassName(classEntity, className); |
| 369 if (reflectionName != null) { | 371 if (reflectionName != null) { |
| 370 // TODO(johnniwinther): Handle class entities. | 372 if (!backend.mirrorsData.isClassAccessibleByReflection(classEntity) || |
| 371 ClassElement classElement = classEntity; | |
| 372 if (!backend.mirrorsData.isClassAccessibleByReflection(classElement) || | |
| 373 cls.onlyForRti) { | 373 cls.onlyForRti) { |
| 374 // TODO(herhut): Fix use of reflection name here. | 374 // TODO(herhut): Fix use of reflection name here. |
| 375 enclosingBuilder.addPropertyByName("+$reflectionName", js.number(0)); | 375 enclosingBuilder.addPropertyByName("+$reflectionName", js.number(0)); |
| 376 } else { | 376 } else { |
| 377 // TODO(johnniwinther): Handle class entities. |
| 378 ClassElement classElement = classEntity; |
| 377 List<jsAst.Expression> types = <jsAst.Expression>[]; | 379 List<jsAst.Expression> types = <jsAst.Expression>[]; |
| 378 if (classElement.supertype != null) { | 380 if (classElement.supertype != null) { |
| 379 types.add(task.metadataCollector.reifyType(classElement.supertype)); | 381 types.add(task.metadataCollector.reifyType(classElement.supertype)); |
| 380 } | 382 } |
| 381 for (ResolutionDartType interface in classElement.interfaces) { | 383 for (ResolutionDartType interface in classElement.interfaces) { |
| 382 types.add(task.metadataCollector.reifyType(interface)); | 384 types.add(task.metadataCollector.reifyType(interface)); |
| 383 } | 385 } |
| 384 // TODO(herhut): Fix use of reflection name here. | 386 // TODO(herhut): Fix use of reflection name here. |
| 385 enclosingBuilder.addPropertyByName( | 387 enclosingBuilder.addPropertyByName( |
| 386 "+$reflectionName", new jsAst.ArrayInitializer(types)); | 388 "+$reflectionName", new jsAst.ArrayInitializer(types)); |
| 387 } | 389 } |
| 388 } | 390 } |
| 389 } | 391 } |
| 390 | 392 |
| 391 void recordMangledField( | 393 void recordMangledField( |
| 392 FieldElement member, jsAst.Name accessorName, String memberName) { | 394 FieldEntity member, jsAst.Name accessorName, String memberName) { |
| 393 if (!backend.mirrorsData.shouldRetainGetter(member)) return; | 395 if (!backend.mirrorsData.shouldRetainGetter(member)) return; |
| 394 String previousName; | 396 String previousName; |
| 395 if (member.isInstanceMember) { | 397 if (member.isInstanceMember) { |
| 396 previousName = emitter.mangledFieldNames | 398 previousName = emitter.mangledFieldNames |
| 397 .putIfAbsent(namer.deriveGetterName(accessorName), () => memberName); | 399 .putIfAbsent(namer.deriveGetterName(accessorName), () => memberName); |
| 398 } else { | 400 } else { |
| 399 previousName = emitter.mangledGlobalFieldNames | 401 previousName = emitter.mangledGlobalFieldNames |
| 400 .putIfAbsent(accessorName, () => memberName); | 402 .putIfAbsent(accessorName, () => memberName); |
| 401 } | 403 } |
| 402 assert(previousName == memberName, | 404 assert(previousName == memberName, |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 452 String reflectionName = emitter.getReflectionSelectorName(selector, name); | 454 String reflectionName = emitter.getReflectionSelectorName(selector, name); |
| 453 if (reflectionName != null) { | 455 if (reflectionName != null) { |
| 454 var reflectable = js( | 456 var reflectable = js( |
| 455 backend.mirrorsData.isMemberAccessibleByReflection(member) | 457 backend.mirrorsData.isMemberAccessibleByReflection(member) |
| 456 ? '1' | 458 ? '1' |
| 457 : '0'); | 459 : '0'); |
| 458 builder.addPropertyByName('+$reflectionName', reflectable); | 460 builder.addPropertyByName('+$reflectionName', reflectable); |
| 459 } | 461 } |
| 460 } | 462 } |
| 461 } | 463 } |
| OLD | NEW |