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

Side by Side Diff: dart/frog/leg/emitter.dart

Issue 9689045: Library privacy. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 /** 5 /**
6 * A function element that represents a closure call. The signature is copied 6 * A function element that represents a closure call. The signature is copied
7 * from the given element. 7 * from the given element.
8 */ 8 */
9 class ClosureInvocationElement extends FunctionElement { 9 class ClosureInvocationElement extends FunctionElement {
10 ClosureInvocationElement(SourceString name, 10 ClosureInvocationElement(SourceString name,
11 FunctionElement other) 11 FunctionElement other)
12 : super.from(name, other, null); 12 : super.from(name, other, other.enclosingElement);
13 13
14 isInstanceMember() => true; 14 isInstanceMember() => true;
15 } 15 }
16 16
17 /** 17 /**
18 * Generates the code for all used classes in the program. Static fields (even 18 * Generates the code for all used classes in the program. Static fields (even
19 * in classes) are ignored, since they can be treated as non-class elements. 19 * in classes) are ignored, since they can be treated as non-class elements.
20 * 20 *
21 * The code for the containing (used) methods must exist in the [:universe:]. 21 * The code for the containing (used) methods must exist in the [:universe:].
22 */ 22 */
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 FunctionParameters parameters = member.computeParameters(compiler); 70 FunctionParameters parameters = member.computeParameters(compiler);
71 int positionalArgumentCount = selector.positionalArgumentCount; 71 int positionalArgumentCount = selector.positionalArgumentCount;
72 if (positionalArgumentCount == parameters.parameterCount) { 72 if (positionalArgumentCount == parameters.parameterCount) {
73 assert(selector.namedArgumentCount == 0); 73 assert(selector.namedArgumentCount == 0);
74 return; 74 return;
75 } 75 }
76 ConstantHandler handler = compiler.constantHandler; 76 ConstantHandler handler = compiler.constantHandler;
77 List<SourceString> names = selector.getOrderedNamedArguments(); 77 List<SourceString> names = selector.getOrderedNamedArguments();
78 78
79 String invocationName = 79 String invocationName =
80 namer.instanceMethodInvocationName(member.name, selector); 80 namer.instanceMethodInvocationName(member.getLibrary(), member.name,
81 selector);
81 buffer.add('${attachTo(invocationName)} = function('); 82 buffer.add('${attachTo(invocationName)} = function(');
82 83
83 // The parameters that this stub takes. 84 // The parameters that this stub takes.
84 List<String> parametersBuffer = new List<String>(selector.argumentCount); 85 List<String> parametersBuffer = new List<String>(selector.argumentCount);
85 // The arguments that will be passed to the real method. 86 // The arguments that will be passed to the real method.
86 List<String> argumentsBuffer = new List<String>(parameters.parameterCount); 87 List<String> argumentsBuffer = new List<String>(parameters.parameterCount);
87 88
88 // We fill the lists depending on the selector. For example, 89 // We fill the lists depending on the selector. For example,
89 // take method foo: 90 // take method foo:
90 // foo(a, b, [c, d]); 91 // foo(a, b, [c, d]);
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 FunctionElement function = member; 201 FunctionElement function = member;
201 FunctionParameters parameters = function.computeParameters(compiler); 202 FunctionParameters parameters = function.computeParameters(compiler);
202 if (!parameters.optionalParameters.isEmpty()) { 203 if (!parameters.optionalParameters.isEmpty()) {
203 addParameterStubs(member, attachTo, buffer, isNative: isNative); 204 addParameterStubs(member, attachTo, buffer, isNative: isNative);
204 } 205 }
205 } else if (member.kind === ElementKind.FIELD) { 206 } else if (member.kind === ElementKind.FIELD) {
206 // TODO(ngeoffray): Have another class generate the code for the 207 // TODO(ngeoffray): Have another class generate the code for the
207 // fields. 208 // fields.
208 if ((member.modifiers === null || !member.modifiers.isFinal()) && 209 if ((member.modifiers === null || !member.modifiers.isFinal()) &&
209 compiler.universe.invokedSetters.contains(member.name)) { 210 compiler.universe.invokedSetters.contains(member.name)) {
210 String setterName = namer.setterName(member.name); 211 String setterName = namer.setterName(member.getLibrary(), member.name);
211 String name = 212 String name =
212 isNative ? member.name.slowToString() : namer.getName(member); 213 isNative ? member.name.slowToString() : namer.getName(member);
213 buffer.add('${attachTo(setterName)} = function(v){\n'); 214 buffer.add('${attachTo(setterName)} = function(v){\n');
214 buffer.add(' this.$name = v;\n};\n'); 215 buffer.add(' this.$name = v;\n};\n');
215 } 216 }
216 if (compiler.universe.invokedGetters.contains(member.name)) { 217 if (compiler.universe.invokedGetters.contains(member.name)) {
217 String getterName = namer.getterName(member.name); 218 String getterName = namer.getterName(member.getLibrary(), member.name);
218 String name = 219 String name =
219 isNative ? member.name.slowToString() : namer.getName(member); 220 isNative ? member.name.slowToString() : namer.getName(member);
220 buffer.add('${attachTo(getterName)} = function(){\n'); 221 buffer.add('${attachTo(getterName)} = function(){\n');
221 buffer.add(' return this.$name;\n};\n'); 222 buffer.add(' return this.$name;\n};\n');
222 } 223 }
223 } else { 224 } else {
224 compiler.internalError('unexpected kind: "${member.kind}"', 225 compiler.internalError('unexpected kind: "${member.kind}"',
225 element: member); 226 element: member);
226 } 227 }
227 emitExtraAccessors(member, attachTo, buffer); 228 emitExtraAccessors(member, attachTo, buffer);
228 } 229 }
229 230
230 bool generateFieldInits(ClassElement classElement, 231 bool generateFieldInits(ClassElement classElement,
231 StringBuffer argumentsBuffer, 232 StringBuffer argumentsBuffer,
232 StringBuffer bodyBuffer) { 233 StringBuffer bodyBuffer) {
233 bool isFirst = true; 234 bool isFirst = true;
234 do { 235 do {
235 // TODO(floitsch): make sure there are no name clashes. 236 // TODO(floitsch): make sure there are no name clashes.
236 String className = namer.getName(classElement); 237 String className = namer.getName(classElement);
237 238
238 void generateFieldInit(Element member) { 239 void generateFieldInit(Element member) {
239 if (member.isInstanceMember() && member.kind == ElementKind.FIELD) { 240 if (member.isInstanceMember() && member.kind == ElementKind.FIELD) {
240 if (!isFirst) argumentsBuffer.add(', '); 241 if (!isFirst) argumentsBuffer.add(', ');
241 isFirst = false; 242 isFirst = false;
242 String memberName = namer.instanceFieldName(member.name); 243 String memberName = namer.instanceFieldName(member.getLibrary(),
244 member.name);
243 argumentsBuffer.add('${className}_$memberName'); 245 argumentsBuffer.add('${className}_$memberName');
244 bodyBuffer.add(' this.$memberName = ${className}_$memberName;\n'); 246 bodyBuffer.add(' this.$memberName = ${className}_$memberName;\n');
245 } 247 }
246 } 248 }
247 249
248 for (Element element in classElement.members) { 250 for (Element element in classElement.members) {
249 generateFieldInit(element); 251 generateFieldInit(element);
250 } 252 }
251 for (Element element in classElement.backendMembers) { 253 for (Element element in classElement.backendMembers) {
252 generateFieldInit(element); 254 generateFieldInit(element);
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 for (FunctionElement element in functionsNeedingGetter) { 373 for (FunctionElement element in functionsNeedingGetter) {
372 // The static function does not have the correct name. Since 374 // The static function does not have the correct name. Since
373 // [addParameterStubs] use the name to create its stubs we simply 375 // [addParameterStubs] use the name to create its stubs we simply
374 // create a fake element with the correct name. 376 // create a fake element with the correct name.
375 // Note: the callElement will not have any enclosingElement. 377 // Note: the callElement will not have any enclosingElement.
376 FunctionElement callElement = 378 FunctionElement callElement =
377 new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, element); 379 new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, element);
378 String staticName = namer.isolatePropertyAccess(element); 380 String staticName = namer.isolatePropertyAccess(element);
379 int parameterCount = element.parameterCount(compiler); 381 int parameterCount = element.parameterCount(compiler);
380 String invocationName = 382 String invocationName =
381 namer.instanceMethodName(callElement.name, parameterCount); 383 namer.instanceMethodName(element.getLibrary(), callElement.name,
384 parameterCount);
382 buffer.add("$staticName.$invocationName = $staticName;\n"); 385 buffer.add("$staticName.$invocationName = $staticName;\n");
383 addParameterStubs(callElement, (name) => '$staticName.$name', buffer); 386 addParameterStubs(callElement, (name) => '$staticName.$name', buffer);
384 } 387 }
385 } 388 }
386 389
387 void emitDynamicFunctionGetter(StringBuffer buffer, 390 void emitDynamicFunctionGetter(StringBuffer buffer,
388 String attachTo(String invocationName), 391 String attachTo(String invocationName),
389 FunctionElement member) { 392 FunctionElement member) {
390 // For every method that has the same name as a property-get we create a 393 // For every method that has the same name as a property-get we create a
391 // getter that returns a bound closure. Say we have a class 'A' with method 394 // getter that returns a bound closure. Say we have a class 'A' with method
(...skipping 30 matching lines...) Expand all
422 425
423 // Now add the methods on the closure class. The instance method does not 426 // Now add the methods on the closure class. The instance method does not
424 // have the correct name. Since [addParameterStubs] use the name to create 427 // have the correct name. Since [addParameterStubs] use the name to create
425 // its stubs we simply create a fake element with the correct name. 428 // its stubs we simply create a fake element with the correct name.
426 // Note: the callElement will not have any enclosingElement. 429 // Note: the callElement will not have any enclosingElement.
427 FunctionElement callElement = 430 FunctionElement callElement =
428 new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, member); 431 new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, member);
429 432
430 int parameterCount = member.parameterCount(compiler); 433 int parameterCount = member.parameterCount(compiler);
431 String invocationName = 434 String invocationName =
432 namer.instanceMethodName(callElement.name, parameterCount); 435 namer.instanceMethodName(member.getLibrary(),
433 String targetName = namer.instanceMethodName(member.name, parameterCount); 436 callElement.name, parameterCount);
437 String targetName = namer.instanceMethodName(member.getLibrary(),
438 member.name, parameterCount);
434 List<String> arguments = new List<String>(parameterCount); 439 List<String> arguments = new List<String>(parameterCount);
435 for (int i = 0; i < parameterCount; i++) { 440 for (int i = 0; i < parameterCount; i++) {
436 arguments[i] = "arg$i"; 441 arguments[i] = "arg$i";
437 } 442 }
438 String joinedArgs = Strings.join(arguments, ", "); 443 String joinedArgs = Strings.join(arguments, ", ");
439 buffer.add("$prototype.$invocationName = function($joinedArgs) {\n"); 444 buffer.add("$prototype.$invocationName = function($joinedArgs) {\n");
440 buffer.add(" return this.self.$targetName($joinedArgs);\n"); 445 buffer.add(" return this.self.$targetName($joinedArgs);\n");
441 buffer.add("};\n"); 446 buffer.add("};\n");
442 addParameterStubs(callElement, (name) => '$prototype.$name', buffer); 447 addParameterStubs(callElement, (name) => '$prototype.$name', buffer);
443 448
444 // And finally the getter. 449 // And finally the getter.
445 String getterName = namer.getterName(member.name); 450 String getterName = namer.getterName(member.getLibrary(), member.name);
446 String closureClass = namer.isolateAccess(closureClassElement); 451 String closureClass = namer.isolateAccess(closureClassElement);
447 buffer.add("${attachTo(getterName)} = function() {\n"); 452 buffer.add("${attachTo(getterName)} = function() {\n");
448 buffer.add(" return new $closureClass(this);\n"); 453 buffer.add(" return new $closureClass(this);\n");
449 buffer.add("};\n"); 454 buffer.add("};\n");
450 } 455 }
451 456
452 void emitCallStubForGetter(StringBuffer buffer, 457 void emitCallStubForGetter(StringBuffer buffer,
453 String attachTo(String name), 458 String attachTo(String name),
454 Element member, 459 Element member,
455 Set<Selector> selectors) { 460 Set<Selector> selectors) {
456 String getter; 461 String getter;
457 if (member.kind == ElementKind.GETTER) { 462 if (member.kind == ElementKind.GETTER) {
458 getter = "this.${namer.getterName(member.name)}()"; 463 getter = "this.${namer.getterName(member.getLibrary(), member.name)}()";
459 } else { 464 } else {
460 getter = "this.${namer.instanceFieldName(member.name)}"; 465 getter =
466 "this.${namer.instanceFieldName(member.getLibrary(), member.name)}";
461 } 467 }
462 for (Selector selector in selectors) { 468 for (Selector selector in selectors) {
463 String invocationName = 469 String invocationName =
464 namer.instanceMethodInvocationName(member.name, selector); 470 namer.instanceMethodInvocationName(member.getLibrary(), member.name,
471 selector);
465 SourceString callName = Namer.CLOSURE_INVOCATION_NAME; 472 SourceString callName = Namer.CLOSURE_INVOCATION_NAME;
466 String closureCallName = 473 String closureCallName =
467 namer.instanceMethodInvocationName(callName, selector); 474 namer.instanceMethodInvocationName(member.getLibrary(), callName,
475 selector);
468 List<String> arguments = <String>[]; 476 List<String> arguments = <String>[];
469 for (int i = 0; i < selector.argumentCount; i++) { 477 for (int i = 0; i < selector.argumentCount; i++) {
470 arguments.add("arg$i"); 478 arguments.add("arg$i");
471 } 479 }
472 String joined = Strings.join(arguments, ", "); 480 String joined = Strings.join(arguments, ", ");
473 buffer.add("${attachTo(invocationName)} = function($joined) {\n"); 481 buffer.add("${attachTo(invocationName)} = function($joined) {\n");
474 buffer.add(" return $getter.$closureCallName($joined);\n"); 482 buffer.add(" return $getter.$closureCallName($joined);\n");
475 buffer.add("};\n"); 483 buffer.add("};\n");
476 } 484 }
477 } 485 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 559
552 void emitNoSuchMethodCalls(StringBuffer buffer) { 560 void emitNoSuchMethodCalls(StringBuffer buffer) {
553 // Do not generate no such method calls if there is no class. 561 // Do not generate no such method calls if there is no class.
554 if (compiler.universe.instantiatedClasses.isEmpty()) return; 562 if (compiler.universe.instantiatedClasses.isEmpty()) return;
555 563
556 ClassElement objectClass = 564 ClassElement objectClass =
557 compiler.coreLibrary.find(const SourceString('Object')); 565 compiler.coreLibrary.find(const SourceString('Object'));
558 String className = namer.isolatePropertyAccess(objectClass); 566 String className = namer.isolatePropertyAccess(objectClass);
559 String prototype = '$className.prototype'; 567 String prototype = '$className.prototype';
560 String noSuchMethodName = 568 String noSuchMethodName =
561 namer.instanceMethodName(Compiler.NO_SUCH_METHOD, 2); 569 namer.instanceMethodName(null, Compiler.NO_SUCH_METHOD, 2);
570 Collection<LibraryElement> libraries =
571 compiler.universe.libraries.getValues();
562 572
563 void generateMethod(String methodName, String jsName, Selector selector) { 573 void generateMethod(String methodName, String jsName, Selector selector) {
564 buffer.add('$prototype.$jsName = function'); 574 buffer.add('$prototype.$jsName = function');
565 StringBuffer args = new StringBuffer(); 575 StringBuffer args = new StringBuffer();
566 for (int i = 0; i < selector.argumentCount; i++) { 576 for (int i = 0; i < selector.argumentCount; i++) {
567 if (i != 0) args.add(', '); 577 if (i != 0) args.add(', ');
568 args.add('arg$i'); 578 args.add('arg$i');
569 } 579 }
570 // We need to check if the object has a noSuchMethod. If not, it 580 // We need to check if the object has a noSuchMethod. If not, it
571 // means the object is a native object, and we can just call our 581 // means the object is a native object, and we can just call our
572 // generic noSuchMethod. Note that when calling this method, the 582 // generic noSuchMethod. Note that when calling this method, the
573 // 'this' object is not a Dart object. 583 // 'this' object is not a Dart object.
574 buffer.add(' ($args) {\n'); 584 buffer.add(' ($args) {\n');
575 buffer.add(' return this.$noSuchMethodName\n'); 585 buffer.add(' return this.$noSuchMethodName\n');
576 buffer.add(" ? this.$noSuchMethodName('$methodName', [$args])\n"); 586 buffer.add(" ? this.$noSuchMethodName('$methodName', [$args])\n");
577 buffer.add(" : $objectClassName.prototype.$noSuchMethodName.call("); 587 buffer.add(" : $objectClassName.prototype.$noSuchMethodName.call(");
578 buffer.add("this, '$methodName', [$args])\n"); 588 buffer.add("this, '$methodName', [$args])\n");
579 buffer.add('}\n'); 589 buffer.add('}\n');
580 } 590 }
581 591
582 compiler.universe.invokedNames.forEach((SourceString methodName, 592 compiler.universe.invokedNames.forEach((SourceString methodName,
583 Set<Selector> selectors) { 593 Set<Selector> selectors) {
584 if (objectClass.lookupLocalMember(methodName) === null 594 if (objectClass.lookupLocalMember(methodName) === null
585 && methodName != Namer.OPERATOR_EQUALS) { 595 && methodName != Namer.OPERATOR_EQUALS) {
586 for (Selector selector in selectors) { 596 for (Selector selector in selectors) {
587 String jsName = 597 if (methodName.isPrivate()) {
588 namer.instanceMethodInvocationName(methodName, selector); 598 for (LibraryElement lib in libraries) {
589 generateMethod(methodName.slowToString(), jsName, selector); 599 String jsName =
600 namer.instanceMethodInvocationName(lib, methodName, selector);
601 generateMethod(methodName.slowToString(), jsName, selector);
602 }
603 } else {
604 String jsName =
605 namer.instanceMethodInvocationName(null, methodName, selector);
606 generateMethod(methodName.slowToString(), jsName, selector);
607 }
590 } 608 }
591 } 609 }
592 }); 610 });
593 611
594 compiler.universe.invokedGetters.forEach((SourceString getterName) { 612 compiler.universe.invokedGetters.forEach((SourceString getterName) {
595 String jsName = namer.getterName(getterName); 613 if (getterName.isPrivate()) {
596 generateMethod('get ${getterName.slowToString()}', jsName, 614 for (LibraryElement lib in libraries) {
597 Selector.GETTER); 615 String jsName = namer.getterName(lib, getterName);
616 generateMethod('get ${getterName.slowToString()}', jsName,
617 Selector.GETTER);
618 }
619 } else {
620 String jsName = namer.getterName(null, getterName);
621 generateMethod('get ${getterName.slowToString()}', jsName,
622 Selector.GETTER);
623 }
598 }); 624 });
599 625
600 compiler.universe.invokedSetters.forEach((SourceString setterName) { 626 compiler.universe.invokedSetters.forEach((SourceString setterName) {
601 String jsName = namer.setterName(setterName); 627 if (setterName.isPrivate()) {
602 generateMethod('set ${setterName.slowToString()}', jsName, 628 for (LibraryElement lib in libraries) {
603 Selector.SETTER); 629 String jsName = namer.setterName(lib, setterName);
630 generateMethod('set ${setterName.slowToString()}', jsName,
631 Selector.SETTER);
632 }
633 } else {
634 String jsName = namer.setterName(null, setterName);
635 generateMethod('set ${setterName.slowToString()}', jsName,
636 Selector.SETTER);
637 }
604 }); 638 });
605 } 639 }
606 640
607 String buildIsolateSetup(Element appMain, Element isolateMain) { 641 String buildIsolateSetup(Element appMain, Element isolateMain) {
608 String mainAccess = "${namer.isolateAccess(appMain)}"; 642 String mainAccess = "${namer.isolateAccess(appMain)}";
609 String currentIsolate = "${namer.CURRENT_ISOLATE}"; 643 String currentIsolate = "${namer.CURRENT_ISOLATE}";
610 String mainEnsureGetter = ''; 644 String mainEnsureGetter = '';
611 // Since we pass the closurized version of the main method to 645 // Since we pass the closurized version of the main method to
612 // the isolate method, we must make sure that it exists. 646 // the isolate method, we must make sure that it exists.
613 if (!compiler.universe.staticFunctionsNeedingGetter.contains(appMain)) { 647 if (!compiler.universe.staticFunctionsNeedingGetter.contains(appMain)) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
654 compiler.isolateLibrary.find(Compiler.START_ROOT_ISOLATE); 688 compiler.isolateLibrary.find(Compiler.START_ROOT_ISOLATE);
655 buffer.add(buildIsolateSetup(main, isolateMain)); 689 buffer.add(buildIsolateSetup(main, isolateMain));
656 } else { 690 } else {
657 buffer.add('${namer.isolateAccess(main)}();\n'); 691 buffer.add('${namer.isolateAccess(main)}();\n');
658 } 692 }
659 compiler.assembledCode = buffer.toString(); 693 compiler.assembledCode = buffer.toString();
660 }); 694 });
661 return compiler.assembledCode; 695 return compiler.assembledCode;
662 } 696 }
663 } 697 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698