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

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

Issue 1859343004: dartfmt pkg/compiler (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 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 part of dart2js.js_emitter.full_emitter; 5 part of dart2js.js_emitter.full_emitter;
6 6
7 class ClassEmitter extends CodeEmitterHelper { 7 class ClassEmitter extends CodeEmitterHelper {
8
9 ClassStubGenerator get _stubGenerator => 8 ClassStubGenerator get _stubGenerator =>
10 new ClassStubGenerator(compiler, namer, backend); 9 new ClassStubGenerator(compiler, namer, backend);
11 10
12 /** 11 /**
13 * Documentation wanted -- johnniwinther 12 * Documentation wanted -- johnniwinther
14 */ 13 */
15 void emitClass(Class cls, ClassBuilder enclosingBuilder, Fragment fragment) { 14 void emitClass(Class cls, ClassBuilder enclosingBuilder, Fragment fragment) {
16 ClassElement classElement = cls.element; 15 ClassElement classElement = cls.element;
17 16
18 assert(invariant(classElement, classElement.isDeclaration)); 17 assert(invariant(classElement, classElement.isDeclaration));
19 18
20 emitter.needsClassSupport = true; 19 emitter.needsClassSupport = true;
21 20
22 ClassElement superclass = classElement.superclass; 21 ClassElement superclass = classElement.superclass;
23 jsAst.Name superName; 22 jsAst.Name superName;
24 if (superclass != null) { 23 if (superclass != null) {
25 superName = namer.className(superclass); 24 superName = namer.className(superclass);
26 } 25 }
27 26
28 if (cls.isMixinApplication) { 27 if (cls.isMixinApplication) {
29 MixinApplication mixinApplication = cls; 28 MixinApplication mixinApplication = cls;
30 jsAst.Name mixinName = mixinApplication.mixinClass.name; 29 jsAst.Name mixinName = mixinApplication.mixinClass.name;
31 superName = 30 superName = new CompoundName([superName, Namer.literalPlus, mixinName]);
32 new CompoundName([superName, Namer.literalPlus, mixinName]);
33 emitter.needsMixinSupport = true; 31 emitter.needsMixinSupport = true;
34 } 32 }
35 33
36 ClassBuilder builder = new ClassBuilder.forClass(classElement, namer); 34 ClassBuilder builder = new ClassBuilder.forClass(classElement, namer);
37 builder.superName = superName; 35 builder.superName = superName;
38 emitConstructorsForCSP(cls); 36 emitConstructorsForCSP(cls);
39 emitFields(cls, builder); 37 emitFields(cls, builder);
40 emitCheckedClassSetters(cls, builder); 38 emitCheckedClassSetters(cls, builder);
41 emitClassGettersSettersForCSP(cls, builder); 39 emitClassGettersSettersForCSP(cls, builder);
42 emitInstanceMembers(cls, builder); 40 emitInstanceMembers(cls, builder);
43 emitStubs(cls.callStubs, builder); 41 emitStubs(cls.callStubs, builder);
44 emitStubs(cls.typeVariableReaderStubs, builder); 42 emitStubs(cls.typeVariableReaderStubs, builder);
45 emitRuntimeTypeInformation(cls, builder); 43 emitRuntimeTypeInformation(cls, builder);
46 emitNativeInfo(cls, builder); 44 emitNativeInfo(cls, builder);
47 45
48 if (classElement == backend.helpers.closureClass) { 46 if (classElement == backend.helpers.closureClass) {
49 // We add a special getter here to allow for tearing off a closure from 47 // We add a special getter here to allow for tearing off a closure from
50 // itself. 48 // itself.
51 jsAst.Fun function = js('function() { return this; }'); 49 jsAst.Fun function = js('function() { return this; }');
52 jsAst.Name name = namer.getterForMember(Names.call); 50 jsAst.Name name = namer.getterForMember(Names.call);
53 builder.addProperty(name, function); 51 builder.addProperty(name, function);
54 } 52 }
55 53
56 emitClassBuilderWithReflectionData(cls, builder, enclosingBuilder, 54 emitClassBuilderWithReflectionData(
57 fragment); 55 cls, builder, enclosingBuilder, fragment);
58 } 56 }
57
59 /** 58 /**
60 * Emits the precompiled constructor when in CSP mode. 59 * Emits the precompiled constructor when in CSP mode.
61 */ 60 */
62 void emitConstructorsForCSP(Class cls) { 61 void emitConstructorsForCSP(Class cls) {
63 List<jsAst.Name> fieldNames = <jsAst.Name>[]; 62 List<jsAst.Name> fieldNames = <jsAst.Name>[];
64 63
65 if (!compiler.options.useContentSecurityPolicy) return; 64 if (!compiler.options.useContentSecurityPolicy) return;
66 65
67 if (!cls.onlyForRti && !cls.isNative) { 66 if (!cls.onlyForRti && !cls.isNative) {
68 fieldNames = cls.fields.map((Field field) => field.name).toList(); 67 fieldNames = cls.fields.map((Field field) => field.name).toList();
69 } 68 }
70 69
71 ClassElement classElement = cls.element; 70 ClassElement classElement = cls.element;
72 71
73 jsAst.Expression constructorAst = 72 jsAst.Expression constructorAst =
74 _stubGenerator.generateClassConstructor(classElement, fieldNames); 73 _stubGenerator.generateClassConstructor(classElement, fieldNames);
75 74
76 jsAst.Name constructorName = namer.className(classElement); 75 jsAst.Name constructorName = namer.className(classElement);
77 OutputUnit outputUnit = 76 OutputUnit outputUnit =
78 compiler.deferredLoadTask.outputUnitForElement(classElement); 77 compiler.deferredLoadTask.outputUnitForElement(classElement);
79 emitter.assemblePrecompiledConstructor( 78 emitter.assemblePrecompiledConstructor(
80 outputUnit, constructorName, constructorAst, fieldNames); 79 outputUnit, constructorName, constructorAst, fieldNames);
81 } 80 }
82 81
83 /// Returns `true` if fields added. 82 /// Returns `true` if fields added.
84 bool emitFields(FieldContainer container, 83 bool emitFields(FieldContainer container, ClassBuilder builder,
85 ClassBuilder builder, 84 {bool classIsNative: false, bool emitStatics: false}) {
86 { bool classIsNative: false,
87 bool emitStatics: false }) {
88 Iterable<Field> fields; 85 Iterable<Field> fields;
89 if (container is Class) { 86 if (container is Class) {
90 if (emitStatics) { 87 if (emitStatics) {
91 fields = container.staticFieldsForReflection; 88 fields = container.staticFieldsForReflection;
92 } else if (container.onlyForRti) { 89 } else if (container.onlyForRti) {
93 return false; 90 return false;
94 } else { 91 } else {
95 fields = container.fields; 92 fields = container.fields;
96 } 93 }
97 } else { 94 } else {
98 assert(container is Library); 95 assert(container is Library);
99 assert(emitStatics); 96 assert(emitStatics);
100 fields = container.staticFieldsForReflection; 97 fields = container.staticFieldsForReflection;
101 } 98 }
102 99
103 var fieldMetadata = []; 100 var fieldMetadata = [];
104 bool hasMetadata = false; 101 bool hasMetadata = false;
105 bool fieldsAdded = false; 102 bool fieldsAdded = false;
106 103
107 for (Field field in fields) { 104 for (Field field in fields) {
108 FieldElement fieldElement = field.element; 105 FieldElement fieldElement = field.element;
109 jsAst.Name name = field.name; 106 jsAst.Name name = field.name;
110 jsAst.Name accessorName = field.accessorName; 107 jsAst.Name accessorName = field.accessorName;
111 bool needsGetter = field.needsGetter; 108 bool needsGetter = field.needsGetter;
112 bool needsSetter = field.needsUncheckedSetter; 109 bool needsSetter = field.needsUncheckedSetter;
113 110
114 // Ignore needsCheckedSetter - that is handled below. 111 // Ignore needsCheckedSetter - that is handled below.
115 bool needsAccessor = (needsGetter || needsSetter); 112 bool needsAccessor = (needsGetter || needsSetter);
116 // We need to output the fields for non-native classes so we can auto- 113 // We need to output the fields for non-native classes so we can auto-
117 // generate the constructor. For native classes there are no 114 // generate the constructor. For native classes there are no
118 // constructors, so we don't need the fields unless we are generating 115 // constructors, so we don't need the fields unless we are generating
119 // accessors at runtime. 116 // accessors at runtime.
120 bool needsFieldsForConstructor = !emitStatics && !classIsNative; 117 bool needsFieldsForConstructor = !emitStatics && !classIsNative;
121 if (needsFieldsForConstructor || needsAccessor) { 118 if (needsFieldsForConstructor || needsAccessor) {
122 var metadata = 119 var metadata =
123 task.metadataCollector.buildMetadataFunction(fieldElement); 120 task.metadataCollector.buildMetadataFunction(fieldElement);
124 if (metadata != null) { 121 if (metadata != null) {
(...skipping 11 matching lines...) Expand all
136 fieldNameParts.add(name); 133 fieldNameParts.add(name);
137 } else { 134 } else {
138 // Emit (possibly renaming) field name so we can add accessors at 135 // Emit (possibly renaming) field name so we can add accessors at
139 // runtime. 136 // runtime.
140 if (name != accessorName) { 137 if (name != accessorName) {
141 fieldNameParts.add(accessorName); 138 fieldNameParts.add(accessorName);
142 fieldNameParts.add(js.stringPart(':')); 139 fieldNameParts.add(js.stringPart(':'));
143 } 140 }
144 fieldNameParts.add(name); 141 fieldNameParts.add(name);
145 if (field.needsInterceptedGetter) { 142 if (field.needsInterceptedGetter) {
146 emitter.interceptorEmitter.interceptorInvocationNames.add( 143 emitter.interceptorEmitter.interceptorInvocationNames
147 namer.getterForElement(fieldElement)); 144 .add(namer.getterForElement(fieldElement));
148 } 145 }
149 // TODO(16168): The setter creator only looks at the getter-name. 146 // TODO(16168): The setter creator only looks at the getter-name.
150 // Even though the setter could avoid the interceptor convention we 147 // Even though the setter could avoid the interceptor convention we
151 // currently still need to add the additional argument. 148 // currently still need to add the additional argument.
152 if (field.needsInterceptedGetter || field.needsInterceptedSetter) { 149 if (field.needsInterceptedGetter || field.needsInterceptedSetter) {
153 emitter.interceptorEmitter.interceptorInvocationNames.add( 150 emitter.interceptorEmitter.interceptorInvocationNames
154 namer.setterForElement(fieldElement)); 151 .add(namer.setterForElement(fieldElement));
155 } 152 }
156 153
157 int code = field.getterFlags + (field.setterFlags << 2); 154 int code = field.getterFlags + (field.setterFlags << 2);
158 if (code == 0) { 155 if (code == 0) {
159 reporter.internalError(fieldElement, 156 reporter.internalError(
160 'Field code is 0 ($fieldElement).'); 157 fieldElement, 'Field code is 0 ($fieldElement).');
161 } 158 }
162 fieldNameParts.add( 159 fieldNameParts.add(
163 js.stringPart(FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE])); 160 js.stringPart(FIELD_CODE_CHARACTERS[code - FIRST_FIELD_CODE]));
164 } 161 }
165 // Fields can only be reflected if their declaring class is reflectable 162 // Fields can only be reflected if their declaring class is reflectable
166 // (as they are only accessible via [ClassMirror.declarations]). 163 // (as they are only accessible via [ClassMirror.declarations]).
167 // However, set/get operations can be performed on them, so they are 164 // However, set/get operations can be performed on them, so they are
168 // reflectable in some sense, which leads to [isAccessibleByReflection] 165 // reflectable in some sense, which leads to [isAccessibleByReflection]
169 // reporting `true`. 166 // reporting `true`.
170 if (backend.isAccessibleByReflection(fieldElement)) { 167 if (backend.isAccessibleByReflection(fieldElement)) {
(...skipping 20 matching lines...) Expand all
191 188
192 /// Emits checked setters for fields. 189 /// Emits checked setters for fields.
193 void emitCheckedClassSetters(Class cls, ClassBuilder builder) { 190 void emitCheckedClassSetters(Class cls, ClassBuilder builder) {
194 if (cls.onlyForRti) return; 191 if (cls.onlyForRti) return;
195 192
196 for (StubMethod method in cls.checkedSetters) { 193 for (StubMethod method in cls.checkedSetters) {
197 Element member = method.element; 194 Element member = method.element;
198 assert(member != null); 195 assert(member != null);
199 jsAst.Expression code = method.code; 196 jsAst.Expression code = method.code;
200 jsAst.Name setterName = method.name; 197 jsAst.Name setterName = method.name;
201 compiler.dumpInfoTask.registerElementAst(member, 198 compiler.dumpInfoTask
202 builder.addProperty(setterName, code)); 199 .registerElementAst(member, builder.addProperty(setterName, code));
203 generateReflectionDataForFieldGetterOrSetter( 200 generateReflectionDataForFieldGetterOrSetter(member, setterName, builder,
204 member, setterName, builder, isGetter: false); 201 isGetter: false);
205 } 202 }
206 } 203 }
207 204
208 /// Emits getters/setters for fields if compiling in CSP mode. 205 /// Emits getters/setters for fields if compiling in CSP mode.
209 void emitClassGettersSettersForCSP(Class cls, ClassBuilder builder) { 206 void emitClassGettersSettersForCSP(Class cls, ClassBuilder builder) {
210
211 if (!compiler.options.useContentSecurityPolicy || cls.onlyForRti) return; 207 if (!compiler.options.useContentSecurityPolicy || cls.onlyForRti) return;
212 208
213 for (Field field in cls.fields) { 209 for (Field field in cls.fields) {
214 Element member = field.element; 210 Element member = field.element;
215 reporter.withCurrentElement(member, () { 211 reporter.withCurrentElement(member, () {
216 if (field.needsGetter) { 212 if (field.needsGetter) {
217 emitGetterForCSP(member, field.name, field.accessorName, builder); 213 emitGetterForCSP(member, field.name, field.accessorName, builder);
218 } 214 }
219 if (field.needsUncheckedSetter) { 215 if (field.needsUncheckedSetter) {
220 emitSetterForCSP(member, field.name, field.accessorName, builder); 216 emitSetterForCSP(member, field.name, field.accessorName, builder);
221 } 217 }
222 }); 218 });
223 } 219 }
224 } 220 }
225 221
226 void emitStubs(Iterable<StubMethod> stubs, ClassBuilder builder) { 222 void emitStubs(Iterable<StubMethod> stubs, ClassBuilder builder) {
227 for (Method method in stubs) { 223 for (Method method in stubs) {
228 jsAst.Property property = builder.addProperty(method.name, method.code); 224 jsAst.Property property = builder.addProperty(method.name, method.code);
229 compiler.dumpInfoTask.registerElementAst(method.element, property); 225 compiler.dumpInfoTask.registerElementAst(method.element, property);
230 } 226 }
231 } 227 }
232 228
233 /** 229 /**
234 * Documentation wanted -- johnniwinther 230 * Documentation wanted -- johnniwinther
235 * 231 *
236 * Invariant: [classElement] must be a declaration element. 232 * Invariant: [classElement] must be a declaration element.
237 */ 233 */
238 void emitInstanceMembers(Class cls, 234 void emitInstanceMembers(Class cls, ClassBuilder builder) {
239 ClassBuilder builder) {
240 ClassElement classElement = cls.element; 235 ClassElement classElement = cls.element;
241 assert(invariant(classElement, classElement.isDeclaration)); 236 assert(invariant(classElement, classElement.isDeclaration));
242 237
243 if (cls.onlyForRti || cls.isMixinApplication) return; 238 if (cls.onlyForRti || cls.isMixinApplication) return;
244 239
245 // TODO(herhut): This is a no-op. Should it be removed? 240 // TODO(herhut): This is a no-op. Should it be removed?
246 for (Field field in cls.fields) { 241 for (Field field in cls.fields) {
247 emitter.containerBuilder.addMemberField(field, builder); 242 emitter.containerBuilder.addMemberField(field, builder);
248 } 243 }
249 244
(...skipping 24 matching lines...) Expand all
274 } 269 }
275 } 270 }
276 271
277 void emitNativeInfo(Class cls, ClassBuilder builder) { 272 void emitNativeInfo(Class cls, ClassBuilder builder) {
278 jsAst.Expression nativeInfo = NativeGenerator.encodeNativeInfo(cls); 273 jsAst.Expression nativeInfo = NativeGenerator.encodeNativeInfo(cls);
279 if (nativeInfo != null) { 274 if (nativeInfo != null) {
280 builder.addPropertyByName(namer.nativeSpecProperty, nativeInfo); 275 builder.addPropertyByName(namer.nativeSpecProperty, nativeInfo);
281 } 276 }
282 } 277 }
283 278
284 void emitClassBuilderWithReflectionData(Class cls, 279 void emitClassBuilderWithReflectionData(Class cls, ClassBuilder classBuilder,
285 ClassBuilder classBuilder, 280 ClassBuilder enclosingBuilder, Fragment fragment) {
286 ClassBuilder enclosingBuilder,
287 Fragment fragment) {
288 ClassElement classElement = cls.element; 281 ClassElement classElement = cls.element;
289 jsAst.Name className = cls.name; 282 jsAst.Name className = cls.name;
290 283
291 var metadata = task.metadataCollector.buildMetadataFunction(classElement); 284 var metadata = task.metadataCollector.buildMetadataFunction(classElement);
292 if (metadata != null) { 285 if (metadata != null) {
293 classBuilder.addPropertyByName("@", metadata); 286 classBuilder.addPropertyByName("@", metadata);
294 } 287 }
295 288
296 if (backend.isAccessibleByReflection(classElement)) { 289 if (backend.isAccessibleByReflection(classElement)) {
297 List<DartType> typeVars = classElement.typeVariables; 290 List<DartType> typeVars = classElement.typeVariables;
298 Iterable typeVariableProperties = emitter.typeVariableHandler 291 Iterable typeVariableProperties =
299 .typeVariablesOf(classElement); 292 emitter.typeVariableHandler.typeVariablesOf(classElement);
300 293
301 ClassElement superclass = classElement.superclass; 294 ClassElement superclass = classElement.superclass;
302 bool hasSuper = superclass != null; 295 bool hasSuper = superclass != null;
303 if ((!typeVariableProperties.isEmpty && !hasSuper) || 296 if ((!typeVariableProperties.isEmpty && !hasSuper) ||
304 (hasSuper && !equalElements(superclass.typeVariables, typeVars))) { 297 (hasSuper && !equalElements(superclass.typeVariables, typeVars))) {
305 classBuilder.addPropertyByName('<>', 298 classBuilder.addPropertyByName(
306 new jsAst.ArrayInitializer(typeVariableProperties.toList())); 299 '<>', new jsAst.ArrayInitializer(typeVariableProperties.toList()));
307 } 300 }
308 } 301 }
309 302
310 List<jsAst.Property> statics = new List<jsAst.Property>(); 303 List<jsAst.Property> statics = new List<jsAst.Property>();
311 ClassBuilder staticsBuilder = 304 ClassBuilder staticsBuilder =
312 new ClassBuilder.forStatics(classElement, namer); 305 new ClassBuilder.forStatics(classElement, namer);
313 if (emitFields(cls, staticsBuilder, emitStatics: true)) { 306 if (emitFields(cls, staticsBuilder, emitStatics: true)) {
314 jsAst.ObjectInitializer initializer = 307 jsAst.ObjectInitializer initializer =
315 staticsBuilder.toObjectInitializer(); 308 staticsBuilder.toObjectInitializer();
316 compiler.dumpInfoTask.registerElementAst(classElement, 309 compiler.dumpInfoTask.registerElementAst(classElement, initializer);
317 initializer);
318 jsAst.Node property = initializer.properties.single; 310 jsAst.Node property = initializer.properties.single;
319 compiler.dumpInfoTask.registerElementAst(classElement, property); 311 compiler.dumpInfoTask.registerElementAst(classElement, property);
320 statics.add(property); 312 statics.add(property);
321 } 313 }
322 314
323 // TODO(herhut): Do not grab statics out of the properties. 315 // TODO(herhut): Do not grab statics out of the properties.
324 ClassBuilder classProperties = 316 ClassBuilder classProperties =
325 emitter.elementDescriptors[fragment].remove(classElement); 317 emitter.elementDescriptors[fragment].remove(classElement);
326 if (classProperties != null) { 318 if (classProperties != null) {
327 statics.addAll(classProperties.properties); 319 statics.addAll(classProperties.properties);
328 } 320 }
329 321
330 if (!statics.isEmpty) { 322 if (!statics.isEmpty) {
331 classBuilder.addProperty( 323 classBuilder.addProperty(
332 namer.staticsPropertyName, // 'static' or its minified name. 324 namer.staticsPropertyName, // 'static' or its minified name.
333 new jsAst.ObjectInitializer(statics, isOneLiner: false)); 325 new jsAst.ObjectInitializer(statics, isOneLiner: false));
334 } 326 }
335 327
336 // TODO(ahe): This method (generateClass) should return a jsAst.Expression. 328 // TODO(ahe): This method (generateClass) should return a jsAst.Expression.
337 jsAst.ObjectInitializer propertyValue = 329 jsAst.ObjectInitializer propertyValue = classBuilder.toObjectInitializer();
338 classBuilder.toObjectInitializer(); 330 compiler.dumpInfoTask
339 compiler.dumpInfoTask.registerElementAst(classBuilder.element, propertyValue ); 331 .registerElementAst(classBuilder.element, propertyValue);
340 enclosingBuilder.addProperty(className, propertyValue); 332 enclosingBuilder.addProperty(className, propertyValue);
341 333
342 String reflectionName = emitter.getReflectionName(classElement, className); 334 String reflectionName = emitter.getReflectionName(classElement, className);
343 if (reflectionName != null) { 335 if (reflectionName != null) {
344 if (!backend.isAccessibleByReflection(classElement) || cls.onlyForRti) { 336 if (!backend.isAccessibleByReflection(classElement) || cls.onlyForRti) {
345 // TODO(herhut): Fix use of reflection name here. 337 // TODO(herhut): Fix use of reflection name here.
346 enclosingBuilder.addPropertyByName("+$reflectionName", js.number(0)); 338 enclosingBuilder.addPropertyByName("+$reflectionName", js.number(0));
347 } else { 339 } else {
348 List<jsAst.Expression> types = <jsAst.Expression>[]; 340 List<jsAst.Expression> types = <jsAst.Expression>[];
349 if (classElement.supertype != null) { 341 if (classElement.supertype != null) {
350 types.add(task.metadataCollector.reifyType(classElement.supertype)); 342 types.add(task.metadataCollector.reifyType(classElement.supertype));
351 } 343 }
352 for (DartType interface in classElement.interfaces) { 344 for (DartType interface in classElement.interfaces) {
353 types.add(task.metadataCollector.reifyType(interface)); 345 types.add(task.metadataCollector.reifyType(interface));
354 } 346 }
355 // TODO(herhut): Fix use of reflection name here. 347 // TODO(herhut): Fix use of reflection name here.
356 enclosingBuilder.addPropertyByName("+$reflectionName", 348 enclosingBuilder.addPropertyByName(
357 new jsAst.ArrayInitializer(types)); 349 "+$reflectionName", new jsAst.ArrayInitializer(types));
358 } 350 }
359 } 351 }
360 } 352 }
361 353
362 void recordMangledField(Element member, 354 void recordMangledField(
363 jsAst.Name accessorName, 355 Element member, jsAst.Name accessorName, String memberName) {
364 String memberName) {
365 if (!backend.shouldRetainGetter(member)) return; 356 if (!backend.shouldRetainGetter(member)) return;
366 String previousName; 357 String previousName;
367 if (member.isInstanceMember) { 358 if (member.isInstanceMember) {
368 previousName = emitter.mangledFieldNames.putIfAbsent( 359 previousName = emitter.mangledFieldNames
369 namer.deriveGetterName(accessorName), 360 .putIfAbsent(namer.deriveGetterName(accessorName), () => memberName);
370 () => memberName);
371 } else { 361 } else {
372 previousName = emitter.mangledGlobalFieldNames.putIfAbsent( 362 previousName = emitter.mangledGlobalFieldNames
373 accessorName, 363 .putIfAbsent(accessorName, () => memberName);
374 () => memberName);
375 } 364 }
376 assert(invariant(member, previousName == memberName, 365 assert(invariant(member, previousName == memberName,
377 message: '$previousName != ${memberName}')); 366 message: '$previousName != ${memberName}'));
378 } 367 }
379 368
380 void emitGetterForCSP(Element member, jsAst.Name fieldName, 369 void emitGetterForCSP(Element member, jsAst.Name fieldName,
381 jsAst.Name accessorName, 370 jsAst.Name accessorName, ClassBuilder builder) {
382 ClassBuilder builder) {
383 jsAst.Expression function = 371 jsAst.Expression function =
384 _stubGenerator.generateGetter(member, fieldName); 372 _stubGenerator.generateGetter(member, fieldName);
385 373
386 jsAst.Name getterName = namer.deriveGetterName(accessorName); 374 jsAst.Name getterName = namer.deriveGetterName(accessorName);
387 ClassElement cls = member.enclosingClass; 375 ClassElement cls = member.enclosingClass;
388 jsAst.Name className = namer.className(cls); 376 jsAst.Name className = namer.className(cls);
389 OutputUnit outputUnit = 377 OutputUnit outputUnit =
390 compiler.deferredLoadTask.outputUnitForElement(member); 378 compiler.deferredLoadTask.outputUnitForElement(member);
391 emitter.cspPrecompiledFunctionFor(outputUnit).add( 379 emitter
392 js('#.prototype.# = #', [className, getterName, function])); 380 .cspPrecompiledFunctionFor(outputUnit)
381 .add(js('#.prototype.# = #', [className, getterName, function]));
393 if (backend.isAccessibleByReflection(member)) { 382 if (backend.isAccessibleByReflection(member)) {
394 emitter.cspPrecompiledFunctionFor(outputUnit).add( 383 emitter.cspPrecompiledFunctionFor(outputUnit).add(js(
395 js('#.prototype.#.${namer.reflectableField} = 1', 384 '#.prototype.#.${namer.reflectableField} = 1',
396 [className, getterName])); 385 [className, getterName]));
397 } 386 }
398 } 387 }
399 388
400 void emitSetterForCSP(Element member, jsAst.Name fieldName, 389 void emitSetterForCSP(Element member, jsAst.Name fieldName,
401 jsAst.Name accessorName, 390 jsAst.Name accessorName, ClassBuilder builder) {
402 ClassBuilder builder) {
403 jsAst.Expression function = 391 jsAst.Expression function =
404 _stubGenerator.generateSetter(member, fieldName); 392 _stubGenerator.generateSetter(member, fieldName);
405 393
406 jsAst.Name setterName = namer.deriveSetterName(accessorName); 394 jsAst.Name setterName = namer.deriveSetterName(accessorName);
407 ClassElement cls = member.enclosingClass; 395 ClassElement cls = member.enclosingClass;
408 jsAst.Name className = namer.className(cls); 396 jsAst.Name className = namer.className(cls);
409 OutputUnit outputUnit = 397 OutputUnit outputUnit =
410 compiler.deferredLoadTask.outputUnitForElement(member); 398 compiler.deferredLoadTask.outputUnitForElement(member);
411 emitter.cspPrecompiledFunctionFor(outputUnit).add( 399 emitter
412 js('#.prototype.# = #', [className, setterName, function])); 400 .cspPrecompiledFunctionFor(outputUnit)
401 .add(js('#.prototype.# = #', [className, setterName, function]));
413 if (backend.isAccessibleByReflection(member)) { 402 if (backend.isAccessibleByReflection(member)) {
414 emitter.cspPrecompiledFunctionFor(outputUnit).add( 403 emitter.cspPrecompiledFunctionFor(outputUnit).add(js(
415 js('#.prototype.#.${namer.reflectableField} = 1', 404 '#.prototype.#.${namer.reflectableField} = 1',
416 [className, setterName])); 405 [className, setterName]));
417 } 406 }
418 } 407 }
419 408
420 void generateReflectionDataForFieldGetterOrSetter(Element member, 409 void generateReflectionDataForFieldGetterOrSetter(
421 jsAst.Name name, 410 Element member, jsAst.Name name, ClassBuilder builder,
422 ClassBuilder builder, 411 {bool isGetter}) {
423 {bool isGetter}) {
424 Selector selector = isGetter 412 Selector selector = isGetter
425 ? new Selector.getter( 413 ? new Selector.getter(new Name(member.name, member.library))
426 new Name(member.name, member.library))
427 : new Selector.setter( 414 : new Selector.setter(
428 new Name(member.name, member.library, isSetter: true)); 415 new Name(member.name, member.library, isSetter: true));
429 String reflectionName = emitter.getReflectionName(selector, name); 416 String reflectionName = emitter.getReflectionName(selector, name);
430 if (reflectionName != null) { 417 if (reflectionName != null) {
431 var reflectable = 418 var reflectable =
432 js(backend.isAccessibleByReflection(member) ? '1' : '0'); 419 js(backend.isAccessibleByReflection(member) ? '1' : '0');
433 builder.addPropertyByName('+$reflectionName', reflectable); 420 builder.addPropertyByName('+$reflectionName', reflectable);
434 } 421 }
435 } 422 }
436 } 423 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698