| 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 |