| 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; |
| 11 import '../../deferred_load.dart' show OutputUnit; | 11 import '../../deferred_load.dart' show OutputUnit; |
| 12 import '../../elements/elements.dart' | 12 import '../../elements/elements.dart' show ClassElement, FieldElement; |
| 13 show ClassElement, FieldElement, MemberElement; | |
| 14 import '../../elements/entities.dart'; | 13 import '../../elements/entities.dart'; |
| 15 import '../../js/js.dart' as jsAst; | 14 import '../../js/js.dart' as jsAst; |
| 16 import '../../js/js.dart' show js; | 15 import '../../js/js.dart' show js; |
| 17 import '../../js_backend/js_backend.dart' show CompoundName, Namer; | 16 import '../../js_backend/js_backend.dart' show CompoundName, Namer; |
| 18 import '../../universe/selector.dart' show Selector; | 17 import '../../universe/selector.dart' show Selector; |
| 19 import '../../util/util.dart' show equalElements; | 18 import '../../util/util.dart' show equalElements; |
| 20 import '../../world.dart' show ClosedWorld; | 19 import '../../world.dart' show ClosedWorld; |
| 21 import '../js_emitter.dart' hide Emitter, EmitterFactory; | 20 import '../js_emitter.dart' hide Emitter, EmitterFactory; |
| 22 import '../model.dart'; | 21 import '../model.dart'; |
| 23 import 'emitter.dart'; | 22 import 'emitter.dart'; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 */ | 87 */ |
| 89 void emitConstructorsForCSP(Class cls) { | 88 void emitConstructorsForCSP(Class cls) { |
| 90 List<jsAst.Name> fieldNames = <jsAst.Name>[]; | 89 List<jsAst.Name> fieldNames = <jsAst.Name>[]; |
| 91 | 90 |
| 92 if (!compiler.options.useContentSecurityPolicy) return; | 91 if (!compiler.options.useContentSecurityPolicy) return; |
| 93 | 92 |
| 94 if (!cls.onlyForRti && !cls.isNative) { | 93 if (!cls.onlyForRti && !cls.isNative) { |
| 95 fieldNames = cls.fields.map((Field field) => field.name).toList(); | 94 fieldNames = cls.fields.map((Field field) => field.name).toList(); |
| 96 } | 95 } |
| 97 | 96 |
| 98 ClassElement classElement = cls.element; | 97 ClassEntity classElement = cls.element; |
| 99 | 98 |
| 100 jsAst.Expression constructorAst = _stubGenerator.generateClassConstructor( | 99 jsAst.Expression constructorAst = _stubGenerator.generateClassConstructor( |
| 101 classElement, fieldNames, cls.hasRtiField); | 100 classElement, fieldNames, cls.hasRtiField); |
| 102 | 101 |
| 103 jsAst.Name constructorName = namer.className(classElement); | 102 jsAst.Name constructorName = namer.className(classElement); |
| 104 OutputUnit outputUnit = | 103 OutputUnit outputUnit = |
| 105 compiler.deferredLoadTask.outputUnitForElement(classElement); | 104 compiler.deferredLoadTask.outputUnitForElement(classElement); |
| 106 emitter.assemblePrecompiledConstructor( | 105 emitter.assemblePrecompiledConstructor( |
| 107 outputUnit, constructorName, constructorAst, fieldNames); | 106 outputUnit, constructorName, constructorAst, fieldNames); |
| 108 } | 107 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 builder.fieldMetadata = fieldMetadata; | 214 builder.fieldMetadata = fieldMetadata; |
| 216 } | 215 } |
| 217 return fieldsAdded; | 216 return fieldsAdded; |
| 218 } | 217 } |
| 219 | 218 |
| 220 /// Emits checked setters for fields. | 219 /// Emits checked setters for fields. |
| 221 void emitCheckedClassSetters(Class cls, ClassBuilder builder) { | 220 void emitCheckedClassSetters(Class cls, ClassBuilder builder) { |
| 222 if (cls.onlyForRti) return; | 221 if (cls.onlyForRti) return; |
| 223 | 222 |
| 224 for (StubMethod method in cls.checkedSetters) { | 223 for (StubMethod method in cls.checkedSetters) { |
| 225 MemberElement member = method.element; | 224 MemberEntity member = method.element; |
| 226 assert(member != null); | 225 assert(member != null); |
| 227 jsAst.Expression code = method.code; | 226 jsAst.Expression code = method.code; |
| 228 jsAst.Name setterName = method.name; | 227 jsAst.Name setterName = method.name; |
| 229 compiler.dumpInfoTask | 228 compiler.dumpInfoTask |
| 230 .registerElementAst(member, builder.addProperty(setterName, code)); | 229 .registerElementAst(member, builder.addProperty(setterName, code)); |
| 231 generateReflectionDataForFieldGetterOrSetter(member, setterName, builder, | 230 generateReflectionDataForFieldGetterOrSetter(member, setterName, builder, |
| 232 isGetter: false); | 231 isGetter: false); |
| 233 } | 232 } |
| 234 } | 233 } |
| 235 | 234 |
| 236 /// Emits getters/setters for fields if compiling in CSP mode. | 235 /// Emits getters/setters for fields if compiling in CSP mode. |
| 237 void emitClassGettersSettersForCSP(Class cls, ClassBuilder builder) { | 236 void emitClassGettersSettersForCSP(Class cls, ClassBuilder builder) { |
| 238 if (!compiler.options.useContentSecurityPolicy || cls.onlyForRti) return; | 237 if (!compiler.options.useContentSecurityPolicy || cls.onlyForRti) return; |
| 239 | 238 |
| 240 for (Field field in cls.fields) { | 239 for (Field field in cls.fields) { |
| 241 FieldElement member = field.element; | 240 FieldEntity member = field.element; |
| 242 reporter.withCurrentElement(member, () { | 241 reporter.withCurrentElement(member, () { |
| 243 if (field.needsGetter) { | 242 if (field.needsGetter) { |
| 244 emitGetterForCSP(member, field.name, field.accessorName, builder); | 243 emitGetterForCSP(member, field.name, field.accessorName, builder); |
| 245 } | 244 } |
| 246 if (field.needsUncheckedSetter) { | 245 if (field.needsUncheckedSetter) { |
| 247 emitSetterForCSP(member, field.name, field.accessorName, builder); | 246 emitSetterForCSP(member, field.name, field.accessorName, builder); |
| 248 } | 247 } |
| 249 }); | 248 }); |
| 250 } | 249 } |
| 251 } | 250 } |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 previousName = emitter.mangledFieldNames | 397 previousName = emitter.mangledFieldNames |
| 399 .putIfAbsent(namer.deriveGetterName(accessorName), () => memberName); | 398 .putIfAbsent(namer.deriveGetterName(accessorName), () => memberName); |
| 400 } else { | 399 } else { |
| 401 previousName = emitter.mangledGlobalFieldNames | 400 previousName = emitter.mangledGlobalFieldNames |
| 402 .putIfAbsent(accessorName, () => memberName); | 401 .putIfAbsent(accessorName, () => memberName); |
| 403 } | 402 } |
| 404 assert(previousName == memberName, | 403 assert(previousName == memberName, |
| 405 failedAt(member, '$previousName != ${memberName}')); | 404 failedAt(member, '$previousName != ${memberName}')); |
| 406 } | 405 } |
| 407 | 406 |
| 408 void emitGetterForCSP(FieldElement member, jsAst.Name fieldName, | 407 void emitGetterForCSP(FieldEntity member, jsAst.Name fieldName, |
| 409 jsAst.Name accessorName, ClassBuilder builder) { | 408 jsAst.Name accessorName, ClassBuilder builder) { |
| 410 jsAst.Expression function = | 409 jsAst.Expression function = |
| 411 _stubGenerator.generateGetter(member, fieldName); | 410 _stubGenerator.generateGetter(member, fieldName); |
| 412 | 411 |
| 413 jsAst.Name getterName = namer.deriveGetterName(accessorName); | 412 jsAst.Name getterName = namer.deriveGetterName(accessorName); |
| 414 ClassElement cls = member.enclosingClass; | 413 ClassEntity cls = member.enclosingClass; |
| 415 jsAst.Name className = namer.className(cls); | 414 jsAst.Name className = namer.className(cls); |
| 416 OutputUnit outputUnit = | 415 OutputUnit outputUnit = |
| 417 compiler.deferredLoadTask.outputUnitForElement(member); | 416 compiler.deferredLoadTask.outputUnitForElement(member); |
| 418 emitter | 417 emitter |
| 419 .cspPrecompiledFunctionFor(outputUnit) | 418 .cspPrecompiledFunctionFor(outputUnit) |
| 420 .add(js('#.prototype.# = #', [className, getterName, function])); | 419 .add(js('#.prototype.# = #', [className, getterName, function])); |
| 421 if (backend.mirrorsData.isMemberAccessibleByReflection(member)) { | 420 if (backend.mirrorsData.isMemberAccessibleByReflection(member)) { |
| 422 emitter.cspPrecompiledFunctionFor(outputUnit).add(js( | 421 emitter.cspPrecompiledFunctionFor(outputUnit).add(js( |
| 423 '#.prototype.#.${namer.reflectableField} = 1', | 422 '#.prototype.#.${namer.reflectableField} = 1', |
| 424 [className, getterName])); | 423 [className, getterName])); |
| 425 } | 424 } |
| 426 } | 425 } |
| 427 | 426 |
| 428 void emitSetterForCSP(FieldElement member, jsAst.Name fieldName, | 427 void emitSetterForCSP(FieldEntity member, jsAst.Name fieldName, |
| 429 jsAst.Name accessorName, ClassBuilder builder) { | 428 jsAst.Name accessorName, ClassBuilder builder) { |
| 430 jsAst.Expression function = | 429 jsAst.Expression function = |
| 431 _stubGenerator.generateSetter(member, fieldName); | 430 _stubGenerator.generateSetter(member, fieldName); |
| 432 | 431 |
| 433 jsAst.Name setterName = namer.deriveSetterName(accessorName); | 432 jsAst.Name setterName = namer.deriveSetterName(accessorName); |
| 434 ClassElement cls = member.enclosingClass; | 433 ClassEntity cls = member.enclosingClass; |
| 435 jsAst.Name className = namer.className(cls); | 434 jsAst.Name className = namer.className(cls); |
| 436 OutputUnit outputUnit = | 435 OutputUnit outputUnit = |
| 437 compiler.deferredLoadTask.outputUnitForElement(member); | 436 compiler.deferredLoadTask.outputUnitForElement(member); |
| 438 emitter | 437 emitter |
| 439 .cspPrecompiledFunctionFor(outputUnit) | 438 .cspPrecompiledFunctionFor(outputUnit) |
| 440 .add(js('#.prototype.# = #', [className, setterName, function])); | 439 .add(js('#.prototype.# = #', [className, setterName, function])); |
| 441 if (backend.mirrorsData.isMemberAccessibleByReflection(member)) { | 440 if (backend.mirrorsData.isMemberAccessibleByReflection(member)) { |
| 442 emitter.cspPrecompiledFunctionFor(outputUnit).add(js( | 441 emitter.cspPrecompiledFunctionFor(outputUnit).add(js( |
| 443 '#.prototype.#.${namer.reflectableField} = 1', | 442 '#.prototype.#.${namer.reflectableField} = 1', |
| 444 [className, setterName])); | 443 [className, setterName])); |
| 445 } | 444 } |
| 446 } | 445 } |
| 447 | 446 |
| 448 void generateReflectionDataForFieldGetterOrSetter( | 447 void generateReflectionDataForFieldGetterOrSetter( |
| 449 MemberElement member, jsAst.Name name, ClassBuilder builder, | 448 MemberEntity member, jsAst.Name name, ClassBuilder builder, |
| 450 {bool isGetter}) { | 449 {bool isGetter}) { |
| 451 Selector selector = isGetter | 450 Selector selector = isGetter |
| 452 ? new Selector.getter(member.memberName.getter) | 451 ? new Selector.getter(member.memberName.getter) |
| 453 : new Selector.setter(member.memberName.setter); | 452 : new Selector.setter(member.memberName.setter); |
| 454 String reflectionName = emitter.getReflectionSelectorName(selector, name); | 453 String reflectionName = emitter.getReflectionSelectorName(selector, name); |
| 455 if (reflectionName != null) { | 454 if (reflectionName != null) { |
| 456 var reflectable = js( | 455 var reflectable = js( |
| 457 backend.mirrorsData.isMemberAccessibleByReflection(member) | 456 backend.mirrorsData.isMemberAccessibleByReflection(member) |
| 458 ? '1' | 457 ? '1' |
| 459 : '0'); | 458 : '0'); |
| 460 builder.addPropertyByName('+$reflectionName', reflectable); | 459 builder.addPropertyByName('+$reflectionName', reflectable); |
| 461 } | 460 } |
| 462 } | 461 } |
| 463 } | 462 } |
| OLD | NEW |