OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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.program_builder; | 5 library dart2js.js_emitter.program_builder; |
6 | 6 |
7 import 'js_emitter.dart' show computeMixinClass; | 7 import 'js_emitter.dart' show computeMixinClass; |
8 import 'model.dart'; | 8 import 'model.dart'; |
9 | 9 |
10 import '../common.dart'; | 10 import '../common.dart'; |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 .toList(growable: false); | 209 .toList(growable: false); |
210 } | 210 } |
211 | 211 |
212 StaticField _buildStaticField(Element element) { | 212 StaticField _buildStaticField(Element element) { |
213 JavaScriptConstantCompiler handler = backend.constants; | 213 JavaScriptConstantCompiler handler = backend.constants; |
214 ConstantValue initialValue = handler.getInitialValueFor(element).value; | 214 ConstantValue initialValue = handler.getInitialValueFor(element).value; |
215 // TODO(zarah): The holder should not be registered during building of | 215 // TODO(zarah): The holder should not be registered during building of |
216 // a static field. | 216 // a static field. |
217 _registry.registerHolder(namer.globalObjectForConstant(initialValue)); | 217 _registry.registerHolder(namer.globalObjectForConstant(initialValue)); |
218 js.Expression code = _task.emitter.constantReference(initialValue); | 218 js.Expression code = _task.emitter.constantReference(initialValue); |
219 String name = namer.getNameOfGlobalField(element); | 219 String name = namer.globalPropertyName(element); |
220 bool isFinal = false; | 220 bool isFinal = false; |
221 bool isLazy = false; | 221 bool isLazy = false; |
222 | 222 |
223 // TODO(floitsch): we shouldn't update the registry in the middle of | 223 // TODO(floitsch): we shouldn't update the registry in the middle of |
224 // building a static field. (Note that the $ holder is already registered | 224 // building a static field. (Note that the $ holder is already registered |
225 // earlier). | 225 // earlier). |
226 return new StaticField(element, | 226 return new StaticField(element, |
227 name, _registry.registerHolder(r'$'), code, | 227 name, _registry.registerHolder(r'$'), code, |
228 isFinal, isLazy); | 228 isFinal, isLazy); |
229 } | 229 } |
(...skipping 15 matching lines...) Expand all Loading... |
245 .toList(growable: false); | 245 .toList(growable: false); |
246 } | 246 } |
247 | 247 |
248 StaticField _buildLazyField(Element element) { | 248 StaticField _buildLazyField(Element element) { |
249 js.Expression code = backend.generatedCode[element]; | 249 js.Expression code = backend.generatedCode[element]; |
250 // The code is null if we ended up not needing the lazily | 250 // The code is null if we ended up not needing the lazily |
251 // initialized field after all because of constant folding | 251 // initialized field after all because of constant folding |
252 // before code generation. | 252 // before code generation. |
253 if (code == null) return null; | 253 if (code == null) return null; |
254 | 254 |
255 String name = namer.getNameOfGlobalField(element); | 255 String name = namer.globalPropertyName(element); |
256 bool isFinal = element.isFinal; | 256 bool isFinal = element.isFinal; |
257 bool isLazy = true; | 257 bool isLazy = true; |
258 // TODO(floitsch): we shouldn't update the registry in the middle of | 258 // TODO(floitsch): we shouldn't update the registry in the middle of |
259 // building a static field. (Note that the $ holder is already registered | 259 // building a static field. (Note that the $ holder is already registered |
260 // earlier). | 260 // earlier). |
261 return new StaticField(element, | 261 return new StaticField(element, |
262 name, _registry.registerHolder(r'$'), code, | 262 name, _registry.registerHolder(r'$'), code, |
263 isFinal, isLazy); | 263 isFinal, isLazy); |
264 } | 264 } |
265 | 265 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 staticFieldsForReflection); | 301 staticFieldsForReflection); |
302 } | 302 } |
303 | 303 |
304 /// HACK for Incremental Compilation. | 304 /// HACK for Incremental Compilation. |
305 /// | 305 /// |
306 /// Returns a class that contains the fields of a class. | 306 /// Returns a class that contains the fields of a class. |
307 Class buildFieldsHackForIncrementalCompilation(ClassElement element) { | 307 Class buildFieldsHackForIncrementalCompilation(ClassElement element) { |
308 assert(_compiler.hasIncrementalSupport); | 308 assert(_compiler.hasIncrementalSupport); |
309 | 309 |
310 List<Field> instanceFields = _buildFields(element, false); | 310 List<Field> instanceFields = _buildFields(element, false); |
311 String name = namer.getNameOfClass(element); | 311 String name = namer.className(element); |
312 | 312 |
313 return new Class( | 313 return new Class( |
314 element, name, null, [], instanceFields, [], [], [], [], [], null, | 314 element, name, null, [], instanceFields, [], [], [], [], [], null, |
315 isDirectlyInstantiated: true, | 315 isDirectlyInstantiated: true, |
316 onlyForRti: false, | 316 onlyForRti: false, |
317 isNative: element.isNative); | 317 isNative: element.isNative); |
318 } | 318 } |
319 | 319 |
320 Class _buildClass(ClassElement element) { | 320 Class _buildClass(ClassElement element) { |
321 bool onlyForRti = _task.typeTestRegistry.rtiNeededClasses.contains(element); | 321 bool onlyForRti = _task.typeTestRegistry.rtiNeededClasses.contains(element); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 selectors.forEach((String name, Selector selector) { | 362 selectors.forEach((String name, Selector selector) { |
363 noSuchMethodStubs | 363 noSuchMethodStubs |
364 .add(classStubGenerator.generateStubForNoSuchMethod(name, | 364 .add(classStubGenerator.generateStubForNoSuchMethod(name, |
365 selector)); | 365 selector)); |
366 }); | 366 }); |
367 } | 367 } |
368 | 368 |
369 if (element == backend.closureClass) { | 369 if (element == backend.closureClass) { |
370 // We add a special getter here to allow for tearing off a closure from | 370 // We add a special getter here to allow for tearing off a closure from |
371 // itself. | 371 // itself. |
372 String name = namer.getterNameFromAccessorName( | 372 String name = namer.getterForPublicMember(Compiler.CALL_OPERATOR_NAME); |
373 namer.getMappedInstanceName(Compiler.CALL_OPERATOR_NAME)); | |
374 js.Fun function = js.js('function() { return this; }'); | 373 js.Fun function = js.js('function() { return this; }'); |
375 callStubs.add(_buildStubMethod(name, function)); | 374 callStubs.add(_buildStubMethod(name, function)); |
376 } | 375 } |
377 | 376 |
378 ClassElement implementation = element.implementation; | 377 ClassElement implementation = element.implementation; |
379 | 378 |
380 // MixinApplications run through the members of their mixin. Here, we are | 379 // MixinApplications run through the members of their mixin. Here, we are |
381 // only interested in direct members. | 380 // only interested in direct members. |
382 if (!onlyForRti && !element.isMixinApplication) { | 381 if (!onlyForRti && !element.isMixinApplication) { |
383 implementation.forEachMember(visitMember, includeBackendMembers: true); | 382 implementation.forEachMember(visitMember, includeBackendMembers: true); |
384 } | 383 } |
385 | 384 |
386 List<Field> instanceFields = | 385 List<Field> instanceFields = |
387 onlyForRti ? const <Field>[] : _buildFields(element, false); | 386 onlyForRti ? const <Field>[] : _buildFields(element, false); |
388 List<Field> staticFieldsForReflection = | 387 List<Field> staticFieldsForReflection = |
389 onlyForRti ? const <Field>[] : _buildFields(element, true); | 388 onlyForRti ? const <Field>[] : _buildFields(element, true); |
390 | 389 |
391 TypeTestProperties typeTests = | 390 TypeTestProperties typeTests = |
392 runtimeTypeGenerator.generateIsTests( | 391 runtimeTypeGenerator.generateIsTests( |
393 element, | 392 element, |
394 storeFunctionTypeInMetadata: _storeFunctionTypesInMetadata); | 393 storeFunctionTypeInMetadata: _storeFunctionTypesInMetadata); |
395 | 394 |
396 List<StubMethod> isChecks = <StubMethod>[]; | 395 List<StubMethod> isChecks = <StubMethod>[]; |
397 typeTests.properties.forEach((String name, js.Node code) { | 396 typeTests.properties.forEach((String name, js.Node code) { |
398 isChecks.add(_buildStubMethod(name, code)); | 397 isChecks.add(_buildStubMethod(name, code)); |
399 }); | 398 }); |
400 | 399 |
401 String name = namer.getNameOfClass(element); | 400 String name = namer.className(element); |
402 String holderName = namer.globalObjectFor(element); | 401 String holderName = namer.globalObjectFor(element); |
403 // TODO(floitsch): we shouldn't update the registry in the middle of | 402 // TODO(floitsch): we shouldn't update the registry in the middle of |
404 // building a class. | 403 // building a class. |
405 Holder holder = _registry.registerHolder(holderName); | 404 Holder holder = _registry.registerHolder(holderName); |
406 bool isInstantiated = | 405 bool isInstantiated = |
407 _compiler.codegenWorld.directlyInstantiatedClasses.contains(element); | 406 _compiler.codegenWorld.directlyInstantiatedClasses.contains(element); |
408 | 407 |
409 Class result; | 408 Class result; |
410 if (element.isMixinApplication && !onlyForRti) { | 409 if (element.isMixinApplication && !onlyForRti) { |
411 assert(!element.isNative); | 410 assert(!element.isNative); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 signature.forEachOptionalParameter((ParameterElement parameter) { | 477 signature.forEachOptionalParameter((ParameterElement parameter) { |
479 ConstantExpression def = | 478 ConstantExpression def = |
480 backend.constants.getConstantForVariable(parameter); | 479 backend.constants.getConstantForVariable(parameter); |
481 optionalParameterDefaultValues.add(def.value); | 480 optionalParameterDefaultValues.add(def.value); |
482 }); | 481 }); |
483 } | 482 } |
484 return optionalParameterDefaultValues; | 483 return optionalParameterDefaultValues; |
485 } | 484 } |
486 | 485 |
487 DartMethod _buildMethod(FunctionElement element) { | 486 DartMethod _buildMethod(FunctionElement element) { |
488 String name = namer.getNameOfInstanceMember(element); | 487 String name = namer.methodPropertyName(element); |
489 js.Expression code = backend.generatedCode[element]; | 488 js.Expression code = backend.generatedCode[element]; |
490 | 489 |
491 // TODO(kasperl): Figure out under which conditions code is null. | 490 // TODO(kasperl): Figure out under which conditions code is null. |
492 if (code == null) return null; | 491 if (code == null) return null; |
493 | 492 |
494 bool canTearOff = false; | 493 bool canTearOff = false; |
495 String tearOffName; | 494 String tearOffName; |
496 bool isClosure = false; | 495 bool isClosure = false; |
497 bool isNotApplyTarget = !element.isFunction || element.isAccessor; | 496 bool isNotApplyTarget = !element.isFunction || element.isAccessor; |
498 | 497 |
499 bool canBeReflected = _methodCanBeReflected(element); | 498 bool canBeReflected = _methodCanBeReflected(element); |
500 bool needsStubs = _methodNeedsStubs(element); | 499 bool needsStubs = _methodNeedsStubs(element); |
501 bool canBeApplied = _methodCanBeApplied(element); | 500 bool canBeApplied = _methodCanBeApplied(element); |
502 | 501 |
503 String aliasName = backend.isAliasedSuperMember(element) | 502 String aliasName = backend.isAliasedSuperMember(element) |
504 ? namer.getNameOfAliasedSuperMember(element) | 503 ? namer.aliasedSuperMemberPropertyName(element) |
505 : null; | 504 : null; |
506 | 505 |
507 if (isNotApplyTarget) { | 506 if (isNotApplyTarget) { |
508 canTearOff = false; | 507 canTearOff = false; |
509 } else { | 508 } else { |
510 if (element.enclosingClass.isClosure) { | 509 if (element.enclosingClass.isClosure) { |
511 canTearOff = false; | 510 canTearOff = false; |
512 isClosure = true; | 511 isClosure = true; |
513 } else { | 512 } else { |
514 // Careful with operators. | 513 // Careful with operators. |
515 canTearOff = universe.hasInvokedGetter(element, _compiler.world) || | 514 canTearOff = universe.hasInvokedGetter(element, _compiler.world) || |
516 (canBeReflected && !element.isOperator); | 515 (canBeReflected && !element.isOperator); |
517 assert(canTearOff || | 516 assert(canTearOff || |
518 !universe.methodsNeedingSuperGetter.contains(element)); | 517 !universe.methodsNeedingSuperGetter.contains(element)); |
519 tearOffName = namer.getterName(element); | 518 tearOffName = namer.getterForElement(element); |
520 } | 519 } |
521 } | 520 } |
522 | 521 |
523 if (canTearOff) { | 522 if (canTearOff) { |
524 assert(invariant(element, !element.isGenerativeConstructor)); | 523 assert(invariant(element, !element.isGenerativeConstructor)); |
525 assert(invariant(element, !element.isGenerativeConstructorBody)); | 524 assert(invariant(element, !element.isGenerativeConstructorBody)); |
526 assert(invariant(element, !element.isConstructor)); | 525 assert(invariant(element, !element.isConstructor)); |
527 } | 526 } |
528 | 527 |
529 String callName = null; | 528 String callName = null; |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
685 Holder holder = _registry.registerHolder(holderName); | 684 Holder holder = _registry.registerHolder(holderName); |
686 | 685 |
687 List<String> names = backend.oneShotInterceptors.keys.toList()..sort(); | 686 List<String> names = backend.oneShotInterceptors.keys.toList()..sort(); |
688 return names.map((String name) { | 687 return names.map((String name) { |
689 js.Expression code = stubGenerator.generateOneShotInterceptor(name); | 688 js.Expression code = stubGenerator.generateOneShotInterceptor(name); |
690 return new StaticStubMethod(name, holder, code); | 689 return new StaticStubMethod(name, holder, code); |
691 }); | 690 }); |
692 } | 691 } |
693 | 692 |
694 StaticDartMethod _buildStaticMethod(FunctionElement element) { | 693 StaticDartMethod _buildStaticMethod(FunctionElement element) { |
695 String name = namer.getNameOfMember(element); | 694 String name = namer.methodPropertyName(element); |
696 String holder = namer.globalObjectFor(element); | 695 String holder = namer.globalObjectFor(element); |
697 js.Expression code = backend.generatedCode[element]; | 696 js.Expression code = backend.generatedCode[element]; |
698 | 697 |
699 bool isApplyTarget = !element.isConstructor && !element.isAccessor; | 698 bool isApplyTarget = !element.isConstructor && !element.isAccessor; |
700 bool canBeApplied = _methodCanBeApplied(element); | 699 bool canBeApplied = _methodCanBeApplied(element); |
701 bool canBeReflected = _methodCanBeReflected(element); | 700 bool canBeReflected = _methodCanBeReflected(element); |
702 | 701 |
703 bool needsTearOff = isApplyTarget && | 702 bool needsTearOff = isApplyTarget && |
704 (canBeReflected || | 703 (canBeReflected || |
705 universe.staticFunctionsNeedingGetter.contains(element)); | 704 universe.staticFunctionsNeedingGetter.contains(element)); |
706 | 705 |
707 String tearOffName = | 706 String tearOffName = |
708 needsTearOff ? namer.getStaticClosureName(element) : null; | 707 needsTearOff ? namer.staticClosureName(element) : null; |
709 | 708 |
710 | 709 |
711 String callName = null; | 710 String callName = null; |
712 if (needsTearOff) { | 711 if (needsTearOff) { |
713 Selector callSelector = | 712 Selector callSelector = |
714 new Selector.fromElement(element).toCallSelector(); | 713 new Selector.fromElement(element).toCallSelector(); |
715 callName = namer.invocationName(callSelector); | 714 callName = namer.invocationName(callSelector); |
716 } | 715 } |
717 js.Expression functionType; | 716 js.Expression functionType; |
718 DartType type = element.type; | 717 DartType type = element.type; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
753 _registry.registerConstant(outputUnit, constantValue); | 752 _registry.registerConstant(outputUnit, constantValue); |
754 assert(!_constants.containsKey(constantValue)); | 753 assert(!_constants.containsKey(constantValue)); |
755 String name = namer.constantName(constantValue); | 754 String name = namer.constantName(constantValue); |
756 String constantObject = namer.globalObjectForConstant(constantValue); | 755 String constantObject = namer.globalObjectForConstant(constantValue); |
757 Holder holder = _registry.registerHolder(constantObject); | 756 Holder holder = _registry.registerHolder(constantObject); |
758 Constant constant = new Constant(name, holder, constantValue); | 757 Constant constant = new Constant(name, holder, constantValue); |
759 _constants[constantValue] = constant; | 758 _constants[constantValue] = constant; |
760 } | 759 } |
761 } | 760 } |
762 } | 761 } |
OLD | NEW |