| 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 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 if (!selector.appliesUnnamed(member, compiler.world)) continue; | 233 if (!selector.appliesUnnamed(member, compiler.world)) continue; |
| 234 if (untypedSelectors.add(selector)) { | 234 if (untypedSelectors.add(selector)) { |
| 235 // TODO(ahe): Is the last argument to [addParameterStub] needed? | 235 // TODO(ahe): Is the last argument to [addParameterStub] needed? |
| 236 addParameterStub(member, selector, defineStub, new Set<String>()); | 236 addParameterStub(member, selector, defineStub, new Set<String>()); |
| 237 } | 237 } |
| 238 } | 238 } |
| 239 } | 239 } |
| 240 } | 240 } |
| 241 } | 241 } |
| 242 | 242 |
| 243 void addMember(Element member, ClassBuilder builder) { | 243 void addMemberMethod(DartMethod method, ClassBuilder builder) { |
| 244 assert(invariant(member, member.isDeclaration)); | 244 final FunctionElement member = method.element; |
| 245 | 245 String name = method.name; |
| 246 if (member.isField) { | 246 final FunctionSignature parameters = member.functionSignature; |
| 247 addMemberField(member, builder); | 247 jsAst.Expression code = method.code; |
| 248 } else if (member.isFunction || | 248 final bool needsStubs = method.needsStubs; |
| 249 member.isGenerativeConstructorBody || | 249 final bool canTearOff = method.needsTearOff; |
| 250 member.isGenerativeConstructor || | 250 final String tearOffName = method.tearOffName; |
| 251 member.isAccessor) { | 251 final bool canBeReflected = method.canBeReflected; |
| 252 addMemberMethod(member, builder); | 252 final bool canBeApplied = method.canBeApplied; |
| 253 } else { | 253 final bool isClosure = method is InstanceMethod && method.isClosure; |
| 254 compiler.internalError(member, | 254 final bool hasSuperAlias = method is InstanceMethod && method.hasSuperAlias; |
| 255 'Unexpected kind: "${member.kind}".'); | |
| 256 } | |
| 257 } | |
| 258 | |
| 259 void addMemberMethod(FunctionElement member, ClassBuilder builder) { | |
| 260 MemberInfo info = analyzeMemberMethod(member); | |
| 261 if (info != null) { | |
| 262 addMemberMethodFromInfo(info, builder); | |
| 263 } | |
| 264 } | |
| 265 | |
| 266 MemberInfo analyzeMemberMethod(FunctionElement member) { | |
| 267 if (member.isAbstract) return null; | |
| 268 jsAst.Expression code = backend.generatedCode[member]; | |
| 269 if (code == null) return null; | |
| 270 String name = namer.getNameOfMember(member); | |
| 271 | |
| 272 FunctionSignature parameters = member.functionSignature; | |
| 273 bool needsStubs = !parameters.optionalParameters.isEmpty; | |
| 274 bool canTearOff = false; | |
| 275 bool isClosure = false; | |
| 276 bool isNotApplyTarget = !member.isFunction || | |
| 277 member.isConstructor || | |
| 278 member.isAccessor; | |
| 279 String tearOffName; | |
| 280 | |
| 281 | |
| 282 final bool canBeReflected = backend.isAccessibleByReflection(member) || | |
| 283 // During incremental compilation, we have to assume that reflection | |
| 284 // *might* get enabled. | |
| 285 compiler.hasIncrementalSupport; | |
| 286 | |
| 287 if (isNotApplyTarget) { | |
| 288 canTearOff = false; | |
| 289 } else if (member.isInstanceMember) { | |
| 290 if (member.enclosingClass.isClosure) { | |
| 291 canTearOff = false; | |
| 292 isClosure = true; | |
| 293 } else { | |
| 294 // Careful with operators. | |
| 295 canTearOff = | |
| 296 compiler.codegenWorld.hasInvokedGetter(member, compiler.world) || | |
| 297 (canBeReflected && !member.isOperator); | |
| 298 assert(!needsSuperGetter(member) || canTearOff); | |
| 299 tearOffName = namer.getterName(member); | |
| 300 } | |
| 301 } else { | |
| 302 canTearOff = | |
| 303 compiler.codegenWorld.staticFunctionsNeedingGetter.contains(member) || | |
| 304 canBeReflected; | |
| 305 tearOffName = namer.getStaticClosureName(member); | |
| 306 } | |
| 307 final bool canBeApplied = compiler.enabledFunctionApply && | |
| 308 compiler.world.getMightBePassedToApply(member); | |
| 309 | |
| 310 final bool hasSuperAlias = backend.isAliasedSuperMember(member); | |
| 311 | 255 |
| 312 final bool needStructuredInfo = | 256 final bool needStructuredInfo = |
| 313 canTearOff || canBeReflected || canBeApplied || hasSuperAlias; | 257 canTearOff || canBeReflected || canBeApplied || hasSuperAlias; |
| 314 | 258 |
| 315 | |
| 316 if (canTearOff) { | |
| 317 assert(invariant(member, !member.isGenerativeConstructor)); | |
| 318 assert(invariant(member, !member.isGenerativeConstructorBody)); | |
| 319 assert(invariant(member, !member.isConstructor)); | |
| 320 } | |
| 321 | |
| 322 return new MemberInfo( | |
| 323 member, | |
| 324 name, | |
| 325 parameters, | |
| 326 code, | |
| 327 needsStubs: needsStubs, | |
| 328 canTearOff: canTearOff, | |
| 329 isClosure: isClosure, | |
| 330 tearOffName: tearOffName, | |
| 331 canBeReflected: canBeReflected, | |
| 332 canBeApplied: canBeApplied, | |
| 333 hasSuperAlias: hasSuperAlias, | |
| 334 needStructuredInfo: needStructuredInfo | |
| 335 ); | |
| 336 } | |
| 337 | |
| 338 void addMemberMethodFromInfo(MemberInfo info, ClassBuilder builder) { | |
| 339 final FunctionElement member = info.member; | |
| 340 String name = info.name; | |
| 341 final FunctionSignature parameters = info.parameters; | |
| 342 jsAst.Expression code = info.code; | |
| 343 final bool needsStubs = info.needsStubs; | |
| 344 final bool canTearOff = info.canTearOff; | |
| 345 final bool isClosure = info.isClosure; | |
| 346 final String tearOffName = info.tearOffName; | |
| 347 final bool canBeReflected = info.canBeReflected; | |
| 348 final bool canBeApplied = info.canBeApplied; | |
| 349 final bool needStructuredInfo = info.needStructuredInfo; | |
| 350 final bool hasSuperAlias = info.hasSuperAlias; | |
| 351 | |
| 352 emitter.interceptorEmitter.recordMangledNameOfMemberMethod(member, name); | 259 emitter.interceptorEmitter.recordMangledNameOfMemberMethod(member, name); |
| 353 | 260 |
| 354 if (!needStructuredInfo) { | 261 if (!needStructuredInfo) { |
| 355 compiler.dumpInfoTask.registerElementAst(member, | 262 compiler.dumpInfoTask.registerElementAst(member, |
| 356 builder.addProperty(name, code)); | 263 builder.addProperty(name, code)); |
| 357 if (needsStubs) { | 264 if (needsStubs) { |
| 358 addParameterStubs( | 265 addParameterStubs( |
| 359 member, | 266 member, |
| 360 (Selector selector, jsAst.Fun function) { | 267 (Selector selector, jsAst.Fun function) { |
| 361 compiler.dumpInfoTask.registerElementAst(member, | 268 compiler.dumpInfoTask.registerElementAst(member, |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 expressions.add(js.string(namer.privateName(member.library, | 431 expressions.add(js.string(namer.privateName(member.library, |
| 525 member.name))); | 432 member.name))); |
| 526 } | 433 } |
| 527 | 434 |
| 528 jsAst.ArrayInitializer arrayInit = | 435 jsAst.ArrayInitializer arrayInit = |
| 529 new jsAst.ArrayInitializer(expressions.toList()); | 436 new jsAst.ArrayInitializer(expressions.toList()); |
| 530 compiler.dumpInfoTask.registerElementAst(member, | 437 compiler.dumpInfoTask.registerElementAst(member, |
| 531 builder.addProperty(name, arrayInit)); | 438 builder.addProperty(name, arrayInit)); |
| 532 } | 439 } |
| 533 | 440 |
| 534 void addMemberField(VariableElement member, ClassBuilder builder) { | 441 void addMemberField(Field field, ClassBuilder builder) { |
| 535 // For now, do nothing. | 442 // For now, do nothing. |
| 536 } | 443 } |
| 537 } | 444 } |
| 538 | |
| 539 class MemberInfo { | |
| 540 final FunctionElement member; | |
| 541 | |
| 542 final String name; | |
| 543 | |
| 544 final FunctionSignature parameters; | |
| 545 | |
| 546 final jsAst.Expression code; | |
| 547 | |
| 548 final bool needsStubs; | |
| 549 | |
| 550 final bool canTearOff; | |
| 551 | |
| 552 final bool isClosure; | |
| 553 | |
| 554 final String tearOffName; | |
| 555 | |
| 556 final bool canBeReflected; | |
| 557 | |
| 558 final bool canBeApplied; | |
| 559 | |
| 560 final bool needStructuredInfo; | |
| 561 | |
| 562 final bool hasSuperAlias; | |
| 563 | |
| 564 MemberInfo( | |
| 565 this.member, | |
| 566 this.name, | |
| 567 this.parameters, | |
| 568 this.code, | |
| 569 {this.needsStubs, | |
| 570 this.canTearOff, | |
| 571 this.isClosure, | |
| 572 this.tearOffName, | |
| 573 this.canBeReflected, | |
| 574 this.canBeApplied, | |
| 575 this.hasSuperAlias, | |
| 576 this.needStructuredInfo}) { | |
| 577 assert(member != null); | |
| 578 assert(name != null); | |
| 579 assert(parameters != null); | |
| 580 assert(code != null); | |
| 581 assert(needsStubs != null); | |
| 582 assert(canTearOff != null); | |
| 583 assert(isClosure != null); | |
| 584 assert(tearOffName != null || !canTearOff); | |
| 585 assert(canBeReflected != null); | |
| 586 assert(canBeApplied != null); | |
| 587 assert(hasSuperAlias != null); | |
| 588 assert(needStructuredInfo != null); | |
| 589 } | |
| 590 } | |
| OLD | NEW |