Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(591)

Side by Side Diff: pkg/compiler/lib/src/js_emitter/full_emitter/class_emitter.dart

Issue 2791263005: Split MirrorsData methods and MirrorsDataImpl data by element kind. (Closed)
Patch Set: Updated cf. comments. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 '../../elements/resolution_types.dart' show ResolutionDartType; 9 import '../../elements/resolution_types.dart' show ResolutionDartType;
10 import '../../deferred_load.dart' show OutputUnit; 10 import '../../deferred_load.dart' show OutputUnit;
11 import '../../elements/elements.dart' 11 import '../../elements/elements.dart'
12 show ClassElement, Element, FieldElement, MemberElement, Name; 12 show ClassElement, FieldElement, MemberElement, Name;
13 import '../../js/js.dart' as jsAst; 13 import '../../js/js.dart' as jsAst;
14 import '../../js/js.dart' show js; 14 import '../../js/js.dart' show js;
15 import '../../js_backend/js_backend.dart' show CompoundName, Namer; 15 import '../../js_backend/js_backend.dart' show CompoundName, Namer;
16 import '../../universe/selector.dart' show Selector; 16 import '../../universe/selector.dart' show Selector;
17 import '../../util/util.dart' show equalElements; 17 import '../../util/util.dart' show equalElements;
18 import '../../world.dart' show ClosedWorld; 18 import '../../world.dart' show ClosedWorld;
19 import '../js_emitter.dart' hide Emitter, EmitterFactory; 19 import '../js_emitter.dart' hide Emitter, EmitterFactory;
20 import '../model.dart'; 20 import '../model.dart';
21 import 'emitter.dart'; 21 import 'emitter.dart';
22 22
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 133
134 // Ignore needsCheckedSetter - that is handled below. 134 // Ignore needsCheckedSetter - that is handled below.
135 bool needsAccessor = (needsGetter || needsSetter); 135 bool needsAccessor = (needsGetter || needsSetter);
136 // We need to output the fields for non-native classes so we can auto- 136 // We need to output the fields for non-native classes so we can auto-
137 // generate the constructor. For native classes there are no 137 // generate the constructor. For native classes there are no
138 // constructors, so we don't need the fields unless we are generating 138 // constructors, so we don't need the fields unless we are generating
139 // accessors at runtime. 139 // accessors at runtime.
140 bool needsFieldsForConstructor = !emitStatics && !classIsNative; 140 bool needsFieldsForConstructor = !emitStatics && !classIsNative;
141 if (needsFieldsForConstructor || needsAccessor) { 141 if (needsFieldsForConstructor || needsAccessor) {
142 var metadata = 142 var metadata =
143 task.metadataCollector.buildMetadataFunction(fieldElement); 143 task.metadataCollector.buildFieldMetadataFunction(fieldElement);
144 if (metadata != null) { 144 if (metadata != null) {
145 hasMetadata = true; 145 hasMetadata = true;
146 } else { 146 } else {
147 metadata = new jsAst.LiteralNull(); 147 metadata = new jsAst.LiteralNull();
148 } 148 }
149 fieldMetadata.add(metadata); 149 fieldMetadata.add(metadata);
150 recordMangledField(fieldElement, accessorName, 150 recordMangledField(fieldElement, accessorName,
151 namer.privateName(fieldElement.memberName)); 151 namer.privateName(fieldElement.memberName));
152 List<jsAst.Literal> fieldNameParts = <jsAst.Literal>[]; 152 List<jsAst.Literal> fieldNameParts = <jsAst.Literal>[];
153 if (!needsAccessor) { 153 if (!needsAccessor) {
(...skipping 26 matching lines...) Expand all
180 fieldElement, 'Field code is 0 ($fieldElement).'); 180 fieldElement, 'Field code is 0 ($fieldElement).');
181 } 181 }
182 fieldNameParts.add( 182 fieldNameParts.add(
183 js.stringPart(FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE])); 183 js.stringPart(FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE]));
184 } 184 }
185 // Fields can only be reflected if their declaring class is reflectable 185 // Fields can only be reflected if their declaring class is reflectable
186 // (as they are only accessible via [ClassMirror.declarations]). 186 // (as they are only accessible via [ClassMirror.declarations]).
187 // However, set/get operations can be performed on them, so they are 187 // However, set/get operations can be performed on them, so they are
188 // reflectable in some sense, which leads to [isAccessibleByReflection] 188 // reflectable in some sense, which leads to [isAccessibleByReflection]
189 // reporting `true`. 189 // reporting `true`.
190 if (backend.mirrorsData.isAccessibleByReflection(fieldElement)) { 190 if (backend.mirrorsData.isMemberAccessibleByReflection(fieldElement)) {
191 fieldNameParts.add(new jsAst.LiteralString('-')); 191 fieldNameParts.add(new jsAst.LiteralString('-'));
192 if (fieldElement.isTopLevel || 192 if (fieldElement.isTopLevel ||
193 backend.mirrorsData 193 backend.mirrorsData
194 .isAccessibleByReflection(fieldElement.enclosingClass)) { 194 .isClassAccessibleByReflection(fieldElement.enclosingClass)) {
195 ResolutionDartType type = fieldElement.type; 195 ResolutionDartType type = fieldElement.type;
196 fieldNameParts.add(task.metadataCollector.reifyType(type)); 196 fieldNameParts.add(task.metadataCollector.reifyType(type));
197 } 197 }
198 } 198 }
199 jsAst.Literal fieldNameAst = js.concatenateStrings(fieldNameParts); 199 jsAst.Literal fieldNameAst = js.concatenateStrings(fieldNameParts);
200 builder.addField(fieldNameAst); 200 builder.addField(fieldNameAst);
201 // Add 1 because adding a field to the class also requires a comma 201 // Add 1 because adding a field to the class also requires a comma
202 compiler.dumpInfoTask.registerElementAst(fieldElement, fieldNameAst); 202 compiler.dumpInfoTask.registerElementAst(fieldElement, fieldNameAst);
203 fieldsAdded = true; 203 fieldsAdded = true;
204 } 204 }
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 if (nativeInfo != null) { 297 if (nativeInfo != null) {
298 builder.addPropertyByName(namer.nativeSpecProperty, nativeInfo); 298 builder.addPropertyByName(namer.nativeSpecProperty, nativeInfo);
299 } 299 }
300 } 300 }
301 301
302 void emitClassBuilderWithReflectionData(Class cls, ClassBuilder classBuilder, 302 void emitClassBuilderWithReflectionData(Class cls, ClassBuilder classBuilder,
303 ClassBuilder enclosingBuilder, Fragment fragment) { 303 ClassBuilder enclosingBuilder, Fragment fragment) {
304 ClassElement classElement = cls.element; 304 ClassElement classElement = cls.element;
305 jsAst.Name className = cls.name; 305 jsAst.Name className = cls.name;
306 306
307 var metadata = task.metadataCollector.buildMetadataFunction(classElement); 307 var metadata =
308 task.metadataCollector.buildClassMetadataFunction(classElement);
308 if (metadata != null) { 309 if (metadata != null) {
309 classBuilder.addPropertyByName("@", metadata); 310 classBuilder.addPropertyByName("@", metadata);
310 } 311 }
311 312
312 if (backend.mirrorsData.isAccessibleByReflection(classElement)) { 313 if (backend.mirrorsData.isClassAccessibleByReflection(classElement)) {
313 List<ResolutionDartType> typeVars = classElement.typeVariables; 314 List<ResolutionDartType> typeVars = classElement.typeVariables;
314 Iterable typeVariableProperties = 315 Iterable typeVariableProperties =
315 emitter.typeVariableCodegenAnalysis.typeVariablesOf(classElement); 316 emitter.typeVariableCodegenAnalysis.typeVariablesOf(classElement);
316 317
317 ClassElement superclass = classElement.superclass; 318 ClassElement superclass = classElement.superclass;
318 bool hasSuper = superclass != null; 319 bool hasSuper = superclass != null;
319 if ((!typeVariableProperties.isEmpty && !hasSuper) || 320 if ((!typeVariableProperties.isEmpty && !hasSuper) ||
320 (hasSuper && !equalElements(superclass.typeVariables, typeVars))) { 321 (hasSuper && !equalElements(superclass.typeVariables, typeVars))) {
321 classBuilder.addPropertyByName( 322 classBuilder.addPropertyByName(
322 '<>', new jsAst.ArrayInitializer(typeVariableProperties.toList())); 323 '<>', new jsAst.ArrayInitializer(typeVariableProperties.toList()));
(...skipping 26 matching lines...) Expand all
349 } 350 }
350 351
351 // TODO(ahe): This method (generateClass) should return a jsAst.Expression. 352 // TODO(ahe): This method (generateClass) should return a jsAst.Expression.
352 jsAst.ObjectInitializer propertyValue = classBuilder.toObjectInitializer(); 353 jsAst.ObjectInitializer propertyValue = classBuilder.toObjectInitializer();
353 compiler.dumpInfoTask 354 compiler.dumpInfoTask
354 .registerElementAst(classBuilder.element, propertyValue); 355 .registerElementAst(classBuilder.element, propertyValue);
355 enclosingBuilder.addProperty(className, propertyValue); 356 enclosingBuilder.addProperty(className, propertyValue);
356 357
357 String reflectionName = emitter.getReflectionName(classElement, className); 358 String reflectionName = emitter.getReflectionName(classElement, className);
358 if (reflectionName != null) { 359 if (reflectionName != null) {
359 if (!backend.mirrorsData.isAccessibleByReflection(classElement) || 360 if (!backend.mirrorsData.isClassAccessibleByReflection(classElement) ||
360 cls.onlyForRti) { 361 cls.onlyForRti) {
361 // TODO(herhut): Fix use of reflection name here. 362 // TODO(herhut): Fix use of reflection name here.
362 enclosingBuilder.addPropertyByName("+$reflectionName", js.number(0)); 363 enclosingBuilder.addPropertyByName("+$reflectionName", js.number(0));
363 } else { 364 } else {
364 List<jsAst.Expression> types = <jsAst.Expression>[]; 365 List<jsAst.Expression> types = <jsAst.Expression>[];
365 if (classElement.supertype != null) { 366 if (classElement.supertype != null) {
366 types.add(task.metadataCollector.reifyType(classElement.supertype)); 367 types.add(task.metadataCollector.reifyType(classElement.supertype));
367 } 368 }
368 for (ResolutionDartType interface in classElement.interfaces) { 369 for (ResolutionDartType interface in classElement.interfaces) {
369 types.add(task.metadataCollector.reifyType(interface)); 370 types.add(task.metadataCollector.reifyType(interface));
370 } 371 }
371 // TODO(herhut): Fix use of reflection name here. 372 // TODO(herhut): Fix use of reflection name here.
372 enclosingBuilder.addPropertyByName( 373 enclosingBuilder.addPropertyByName(
373 "+$reflectionName", new jsAst.ArrayInitializer(types)); 374 "+$reflectionName", new jsAst.ArrayInitializer(types));
374 } 375 }
375 } 376 }
376 } 377 }
377 378
378 void recordMangledField( 379 void recordMangledField(
379 Element member, jsAst.Name accessorName, String memberName) { 380 FieldElement member, jsAst.Name accessorName, String memberName) {
380 if (!backend.mirrorsData.shouldRetainGetter(member)) return; 381 if (!backend.mirrorsData.shouldRetainGetter(member)) return;
381 String previousName; 382 String previousName;
382 if (member.isInstanceMember) { 383 if (member.isInstanceMember) {
383 previousName = emitter.mangledFieldNames 384 previousName = emitter.mangledFieldNames
384 .putIfAbsent(namer.deriveGetterName(accessorName), () => memberName); 385 .putIfAbsent(namer.deriveGetterName(accessorName), () => memberName);
385 } else { 386 } else {
386 previousName = emitter.mangledGlobalFieldNames 387 previousName = emitter.mangledGlobalFieldNames
387 .putIfAbsent(accessorName, () => memberName); 388 .putIfAbsent(accessorName, () => memberName);
388 } 389 }
389 assert(invariant(member, previousName == memberName, 390 assert(invariant(member, previousName == memberName,
390 message: '$previousName != ${memberName}')); 391 message: '$previousName != ${memberName}'));
391 } 392 }
392 393
393 void emitGetterForCSP(FieldElement member, jsAst.Name fieldName, 394 void emitGetterForCSP(FieldElement member, jsAst.Name fieldName,
394 jsAst.Name accessorName, ClassBuilder builder) { 395 jsAst.Name accessorName, ClassBuilder builder) {
395 jsAst.Expression function = 396 jsAst.Expression function =
396 _stubGenerator.generateGetter(member, fieldName); 397 _stubGenerator.generateGetter(member, fieldName);
397 398
398 jsAst.Name getterName = namer.deriveGetterName(accessorName); 399 jsAst.Name getterName = namer.deriveGetterName(accessorName);
399 ClassElement cls = member.enclosingClass; 400 ClassElement cls = member.enclosingClass;
400 jsAst.Name className = namer.className(cls); 401 jsAst.Name className = namer.className(cls);
401 OutputUnit outputUnit = 402 OutputUnit outputUnit =
402 compiler.deferredLoadTask.outputUnitForElement(member); 403 compiler.deferredLoadTask.outputUnitForElement(member);
403 emitter 404 emitter
404 .cspPrecompiledFunctionFor(outputUnit) 405 .cspPrecompiledFunctionFor(outputUnit)
405 .add(js('#.prototype.# = #', [className, getterName, function])); 406 .add(js('#.prototype.# = #', [className, getterName, function]));
406 if (backend.mirrorsData.isAccessibleByReflection(member)) { 407 if (backend.mirrorsData.isMemberAccessibleByReflection(member)) {
407 emitter.cspPrecompiledFunctionFor(outputUnit).add(js( 408 emitter.cspPrecompiledFunctionFor(outputUnit).add(js(
408 '#.prototype.#.${namer.reflectableField} = 1', 409 '#.prototype.#.${namer.reflectableField} = 1',
409 [className, getterName])); 410 [className, getterName]));
410 } 411 }
411 } 412 }
412 413
413 void emitSetterForCSP(FieldElement member, jsAst.Name fieldName, 414 void emitSetterForCSP(FieldElement member, jsAst.Name fieldName,
414 jsAst.Name accessorName, ClassBuilder builder) { 415 jsAst.Name accessorName, ClassBuilder builder) {
415 jsAst.Expression function = 416 jsAst.Expression function =
416 _stubGenerator.generateSetter(member, fieldName); 417 _stubGenerator.generateSetter(member, fieldName);
417 418
418 jsAst.Name setterName = namer.deriveSetterName(accessorName); 419 jsAst.Name setterName = namer.deriveSetterName(accessorName);
419 ClassElement cls = member.enclosingClass; 420 ClassElement cls = member.enclosingClass;
420 jsAst.Name className = namer.className(cls); 421 jsAst.Name className = namer.className(cls);
421 OutputUnit outputUnit = 422 OutputUnit outputUnit =
422 compiler.deferredLoadTask.outputUnitForElement(member); 423 compiler.deferredLoadTask.outputUnitForElement(member);
423 emitter 424 emitter
424 .cspPrecompiledFunctionFor(outputUnit) 425 .cspPrecompiledFunctionFor(outputUnit)
425 .add(js('#.prototype.# = #', [className, setterName, function])); 426 .add(js('#.prototype.# = #', [className, setterName, function]));
426 if (backend.mirrorsData.isAccessibleByReflection(member)) { 427 if (backend.mirrorsData.isMemberAccessibleByReflection(member)) {
427 emitter.cspPrecompiledFunctionFor(outputUnit).add(js( 428 emitter.cspPrecompiledFunctionFor(outputUnit).add(js(
428 '#.prototype.#.${namer.reflectableField} = 1', 429 '#.prototype.#.${namer.reflectableField} = 1',
429 [className, setterName])); 430 [className, setterName]));
430 } 431 }
431 } 432 }
432 433
433 void generateReflectionDataForFieldGetterOrSetter( 434 void generateReflectionDataForFieldGetterOrSetter(
434 Element member, jsAst.Name name, ClassBuilder builder, 435 MemberElement member, jsAst.Name name, ClassBuilder builder,
435 {bool isGetter}) { 436 {bool isGetter}) {
436 Selector selector = isGetter 437 Selector selector = isGetter
437 ? new Selector.getter(new Name(member.name, member.library)) 438 ? new Selector.getter(new Name(member.name, member.library))
438 : new Selector.setter( 439 : new Selector.setter(
439 new Name(member.name, member.library, isSetter: true)); 440 new Name(member.name, member.library, isSetter: true));
440 String reflectionName = emitter.getReflectionName(selector, name); 441 String reflectionName = emitter.getReflectionName(selector, name);
441 if (reflectionName != null) { 442 if (reflectionName != null) {
442 var reflectable = 443 var reflectable = js(
443 js(backend.mirrorsData.isAccessibleByReflection(member) ? '1' : '0'); 444 backend.mirrorsData.isMemberAccessibleByReflection(member)
445 ? '1'
446 : '0');
444 builder.addPropertyByName('+$reflectionName', reflectable); 447 builder.addPropertyByName('+$reflectionName', reflectable);
445 } 448 }
446 } 449 }
447 } 450 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_backend/type_variable_handler.dart ('k') | pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698