| 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 part of dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
| 6 | 6 |
| 7 /// This class should morph into something that makes it easy to build | 7 /// This class should morph into something that makes it easy to build |
| 8 /// JavaScript representations of libraries, class-sides, and instance-sides. | 8 /// JavaScript representations of libraries, class-sides, and instance-sides. |
| 9 /// Initially, it is just a placeholder for code that is moved from | 9 /// Initially, it is just a placeholder for code that is moved from |
| 10 /// [CodeEmitterTask]. | 10 /// [CodeEmitterTask]. |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 void addMemberMethod(FunctionElement member, ClassBuilder builder) { | 319 void addMemberMethod(FunctionElement member, ClassBuilder builder) { |
| 320 if (member.isAbstract) return; | 320 if (member.isAbstract) return; |
| 321 jsAst.Expression code = backend.generatedCode[member]; | 321 jsAst.Expression code = backend.generatedCode[member]; |
| 322 if (code == null) return; | 322 if (code == null) return; |
| 323 String name = namer.getNameOfMember(member); | 323 String name = namer.getNameOfMember(member); |
| 324 task.interceptorEmitter.recordMangledNameOfMemberMethod(member, name); | 324 task.interceptorEmitter.recordMangledNameOfMemberMethod(member, name); |
| 325 FunctionSignature parameters = member.computeSignature(compiler); | 325 FunctionSignature parameters = member.computeSignature(compiler); |
| 326 bool needsStubs = !parameters.optionalParameters.isEmpty; | 326 bool needsStubs = !parameters.optionalParameters.isEmpty; |
| 327 bool canTearOff = false; | 327 bool canTearOff = false; |
| 328 bool isClosure = false; | 328 bool isClosure = false; |
| 329 bool canBeApplied = compiler.enabledFunctionApply; |
| 329 String tearOffName; | 330 String tearOffName; |
| 330 if (!member.isFunction() || member.isConstructor() || member.isAccessor()) { | 331 if (!member.isFunction() || member.isConstructor() || member.isAccessor()) { |
| 331 canTearOff = false; | 332 canTearOff = false; |
| 333 canBeApplied = false; |
| 332 } else if (member.isInstanceMember()) { | 334 } else if (member.isInstanceMember()) { |
| 333 if (member.getEnclosingClass().isClosure()) { | 335 if (member.getEnclosingClass().isClosure()) { |
| 334 canTearOff = false; | 336 canTearOff = false; |
| 335 isClosure = true; | 337 isClosure = true; |
| 336 } else { | 338 } else { |
| 337 // Careful with operators. | 339 // Careful with operators. |
| 338 canTearOff = compiler.codegenWorld.hasInvokedGetter(member, compiler); | 340 canTearOff = compiler.codegenWorld.hasInvokedGetter(member, compiler); |
| 339 tearOffName = namer.getterName(member); | 341 tearOffName = namer.getterName(member); |
| 340 } | 342 } |
| 341 } else { | 343 } else { |
| 342 canTearOff = | 344 canTearOff = |
| 343 compiler.codegenWorld.staticFunctionsNeedingGetter.contains(member); | 345 compiler.codegenWorld.staticFunctionsNeedingGetter.contains(member); |
| 344 tearOffName = namer.getStaticClosureName(member); | 346 tearOffName = namer.getStaticClosureName(member); |
| 345 } | 347 } |
| 346 | 348 |
| 347 bool canBeReflected = backend.isAccessibleByReflection(member); | 349 bool canBeReflected = backend.isAccessibleByReflection(member); |
| 348 bool needStructuredInfo = | 350 bool needStructuredInfo = |
| 349 canTearOff || canBeReflected || compiler.enabledFunctionApply; | 351 canTearOff || canBeReflected || canBeApplied; |
| 350 if (!needStructuredInfo) { | 352 if (!needStructuredInfo) { |
| 351 builder.addProperty(name, code); | 353 builder.addProperty(name, code); |
| 352 if (needsStubs) { | 354 if (needsStubs) { |
| 353 addParameterStubs( | 355 addParameterStubs( |
| 354 member, | 356 member, |
| 355 (Selector selector, jsAst.Fun function) { | 357 (Selector selector, jsAst.Fun function) { |
| 356 builder.addProperty(namer.invocationName(selector), function); | 358 builder.addProperty(namer.invocationName(selector), function); |
| 357 }); | 359 }); |
| 358 } | 360 } |
| 359 return; | 361 return; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 if (canTearOff && callSelectors != null && | 444 if (canTearOff && callSelectors != null && |
| 443 callSelectors.contains(callSelector)) { | 445 callSelectors.contains(callSelector)) { |
| 444 callSelectorString = '"${namer.invocationName(callSelector)}"'; | 446 callSelectorString = '"${namer.invocationName(callSelector)}"'; |
| 445 } | 447 } |
| 446 tearOffInfo.add( | 448 tearOffInfo.add( |
| 447 new jsAst.LiteralString('$callSelectorString /* tearOffInfo */')); | 449 new jsAst.LiteralString('$callSelectorString /* tearOffInfo */')); |
| 448 }, canTearOff); | 450 }, canTearOff); |
| 449 } | 451 } |
| 450 | 452 |
| 451 jsAst.Expression memberTypeExpression; | 453 jsAst.Expression memberTypeExpression; |
| 452 if ((canTearOff || canBeReflected) && | 454 if (canTearOff || canBeReflected) { |
| 453 !member.isGenerativeConstructorBody()) { | 455 DartType memberType; |
| 454 DartType memberType = member.computeType(compiler); | 456 if (member.isGenerativeConstructorBody()) { |
| 457 var body = member; |
| 458 memberType = body.constructor.computeType(compiler); |
| 459 } else { |
| 460 memberType = member.computeType(compiler); |
| 461 } |
| 455 if (memberType.containsTypeVariables) { | 462 if (memberType.containsTypeVariables) { |
| 456 jsAst.Expression thisAccess = js(r'this.$receiver'); | 463 jsAst.Expression thisAccess = js(r'this.$receiver'); |
| 457 memberTypeExpression = | 464 memberTypeExpression = |
| 458 backend.rti.getSignatureEncoding(memberType, thisAccess); | 465 backend.rti.getSignatureEncoding(memberType, thisAccess); |
| 459 } else { | 466 } else { |
| 460 memberTypeExpression = | 467 memberTypeExpression = |
| 461 js.toExpression(task.metadataEmitter.reifyType(memberType)); | 468 js.toExpression(task.metadataEmitter.reifyType(memberType)); |
| 462 } | 469 } |
| 463 } else { | 470 } else { |
| 464 memberTypeExpression = js('null'); | 471 memberTypeExpression = js('null'); |
| 465 } | 472 } |
| 466 | 473 |
| 467 expressions | 474 expressions |
| 468 ..addAll(tearOffInfo) | 475 ..addAll(tearOffInfo) |
| 469 ..add((tearOffName == null || member.isAccessor()) | 476 ..add((tearOffName == null || member.isAccessor()) |
| 470 ? js("null") : js.string(tearOffName)) | 477 ? js("null") : js.string(tearOffName)) |
| 471 ..add(requiredParameterCount) | 478 ..add(requiredParameterCount) |
| 472 ..add(optionalParameterCount) | 479 ..add(optionalParameterCount) |
| 473 ..add(memberTypeExpression) | 480 ..add(memberTypeExpression) |
| 474 ..addAll(task.metadataEmitter.reifyDefaultArguments(member)); | 481 ..addAll(task.metadataEmitter.reifyDefaultArguments(member)); |
| 475 | 482 |
| 476 if (canBeReflected || compiler.enabledFunctionApply) { | 483 if (canBeReflected || canBeApplied) { |
| 477 parameters.orderedForEachParameter((Element parameter) { | 484 parameters.orderedForEachParameter((Element parameter) { |
| 478 expressions.add(task.metadataEmitter.reifyName(parameter.name)); | 485 expressions.add(task.metadataEmitter.reifyName(parameter.name)); |
| 479 }); | 486 }); |
| 480 } | 487 } |
| 481 if (canBeReflected) { | 488 if (canBeReflected) { |
| 482 jsAst.LiteralString reflectionName; | 489 jsAst.LiteralString reflectionName; |
| 483 if (member.isConstructor()) { | 490 if (member.isConstructor()) { |
| 484 String reflectionNameString = task.getReflectionName(member, name); | 491 String reflectionNameString = task.getReflectionName(member, name); |
| 485 reflectionName = | 492 reflectionName = |
| 486 new jsAst.LiteralString( | 493 new jsAst.LiteralString( |
| 487 '"new ${Elements.reconstructConstructorName(member)}"' | 494 '"new ${Elements.reconstructConstructorName(member)}"' |
| 488 ' /* $reflectionNameString */'); | 495 ' /* $reflectionNameString */'); |
| 489 } else { | 496 } else { |
| 490 reflectionName = js.string(member.name); | 497 reflectionName = js.string(member.name); |
| 491 } | 498 } |
| 492 expressions | 499 expressions |
| 493 ..add(reflectionName) | 500 ..add(reflectionName) |
| 494 ..addAll(task.metadataEmitter.computeMetadata(member)); | 501 ..addAll(task.metadataEmitter.computeMetadata(member)); |
| 495 } else if (isClosure && compiler.enabledFunctionApply) { | 502 } else if (isClosure && canBeApplied) { |
| 496 expressions.add(js.string(member.name)); | 503 expressions.add(js.string(member.name)); |
| 497 } | 504 } |
| 498 | 505 |
| 499 builder.addProperty(name, js.toExpression(expressions)); | 506 builder.addProperty(name, js.toExpression(expressions)); |
| 500 } | 507 } |
| 501 | 508 |
| 502 void addMemberField(VariableElement member, ClassBuilder builder) { | 509 void addMemberField(VariableElement member, ClassBuilder builder) { |
| 503 // For now, do nothing. | 510 // For now, do nothing. |
| 504 } | 511 } |
| 505 } | 512 } |
| OLD | NEW |