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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/universe/universe.dart

Issue 14049010: Take noSuchMethod into account when computing the potential targets of a call. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 8 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 library universe; 5 library universe;
6 6
7 import '../closure.dart'; 7 import '../closure.dart';
8 import '../elements/elements.dart'; 8 import '../elements/elements.dart';
9 import '../dart2jslib.dart'; 9 import '../dart2jslib.dart';
10 import '../dart_types.dart'; 10 import '../dart_types.dart';
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 LibraryElement library) 178 LibraryElement library)
179 : this(SelectorKind.CALL, 179 : this(SelectorKind.CALL,
180 constructorName, 180 constructorName,
181 library, 181 library,
182 0, 182 0,
183 const []); 183 const []);
184 184
185 Selector.callDefaultConstructor(LibraryElement library) 185 Selector.callDefaultConstructor(LibraryElement library)
186 : this(SelectorKind.CALL, const SourceString(""), library, 0, const []); 186 : this(SelectorKind.CALL, const SourceString(""), library, 0, const []);
187 187
188 // TODO(kasperl): This belongs somewhere else.
189 Selector.noSuchMethod()
190 : this(SelectorKind.CALL, Compiler.NO_SUCH_METHOD, null,
191 Compiler.NO_SUCH_METHOD_ARG_COUNT);
192
193 bool isGetter() => identical(kind, SelectorKind.GETTER); 188 bool isGetter() => identical(kind, SelectorKind.GETTER);
194 bool isSetter() => identical(kind, SelectorKind.SETTER); 189 bool isSetter() => identical(kind, SelectorKind.SETTER);
195 bool isCall() => identical(kind, SelectorKind.CALL); 190 bool isCall() => identical(kind, SelectorKind.CALL);
196 bool isClosureCall() { 191 bool isClosureCall() {
197 SourceString callName = Compiler.CALL_OPERATOR_NAME; 192 SourceString callName = Compiler.CALL_OPERATOR_NAME;
198 return isCall() && name == callName; 193 return isCall() && name == callName;
199 } 194 }
200 195
201 bool isIndex() => identical(kind, SelectorKind.INDEX) && argumentCount == 1; 196 bool isIndex() => identical(kind, SelectorKind.INDEX) && argumentCount == 1;
202 bool isIndexSet() => identical(kind, SelectorKind.INDEX) && argumentCount == 2 ; 197 bool isIndexSet() => identical(kind, SelectorKind.INDEX) && argumentCount == 2 ;
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 : this(new TypeMask.exact(base), selector); 429 : this(new TypeMask.exact(base), selector);
435 430
436 TypedSelector.subclass(DartType base, Selector selector) 431 TypedSelector.subclass(DartType base, Selector selector)
437 : this(new TypeMask.subclass(base), selector); 432 : this(new TypeMask.subclass(base), selector);
438 433
439 TypedSelector.subtype(DartType base, Selector selector) 434 TypedSelector.subtype(DartType base, Selector selector)
440 : this(new TypeMask.subtype(base), selector); 435 : this(new TypeMask.subtype(base), selector);
441 436
442 bool get hasExactMask => mask.isExact; 437 bool get hasExactMask => mask.isExact;
443 438
444 /**
445 * Check if [element] will be the one used at runtime when being
446 * invoked on an instance of [cls].
447 */
448 bool hasElementIn(ClassElement cls, Element element) {
449 // Use the [:implementation] of [cls] in case [element]
450 // is in the patch class. Also use [:implementation:] of [element]
451 // because our function set only stores declarations.
452 Element result = cls.implementation.lookupSelector(this);
453 return result == null
454 ? false
455 : result.implementation == element.implementation;
456 }
457
458 bool appliesUnnamed(Element element, Compiler compiler) { 439 bool appliesUnnamed(Element element, Compiler compiler) {
459 assert(sameNameHack(element, compiler)); 440 assert(sameNameHack(element, compiler));
460 // [TypedSelector] are only used after resolution. 441 // [TypedSelector] are only used after resolution.
461 assert(compiler.phase > Compiler.PHASE_RESOLVING); 442 assert(compiler.phase > Compiler.PHASE_RESOLVING);
462 if (!element.isMember()) return false; 443 if (!element.isMember()) return false;
463 444
464 // A closure can be called through any typed selector: 445 // A closure can be called through any typed selector:
465 // class A { 446 // class A {
466 // get foo => () => 42; 447 // get foo => () => 42;
467 // bar() => foo(); // The call to 'foo' is a typed selector. 448 // bar() => foo(); // The call to 'foo' is a typed selector.
468 // } 449 // }
469 ClassElement other = element.getEnclosingClass(); 450 if (element.getEnclosingClass().isClosure()) {
470 if (identical(other.superclass, compiler.closureClass)) {
471 return appliesUntyped(element, compiler); 451 return appliesUntyped(element, compiler);
472 } 452 }
473 453
474 if (mask.isEmpty) { 454 if (!mask.canHit(element, this, compiler)) return false;
475 if (!mask.isNullable) return false; 455 return appliesUntyped(element, compiler);
476 return hasElementIn(compiler.backend.nullImplementation, element)
477 && appliesUntyped(element, compiler);
478 }
479
480 // TODO(kasperl): Can't we just avoid creating typed selectors
481 // based of function types?
482 Element self = mask.base.element;
483 if (self.isTypedef()) {
484 // A typedef is a function type that doesn't have any
485 // user-defined members.
486 return false;
487 }
488
489 if (compiler.backend.isNullImplementation(other)) {
490 return mask.isNullable && appliesUntyped(element, compiler);
491 } else if (mask.isExact) {
492 return hasElementIn(self, element) && appliesUntyped(element, compiler);
493 } else if (mask.isSubclass) {
494 return (hasElementIn(self, element)
495 || other.isSubclassOf(self)
496 || compiler.world.hasAnySubclassThatMixes(self, other))
497 && appliesUntyped(element, compiler);
498 } else {
499 assert(mask.isSubtype);
500 if (other.implementsInterface(self)
501 || other.isSubclassOf(self)
502 || compiler.world.hasAnySubclassThatMixes(self, other)
503 || compiler.world.hasAnySubclassThatImplements(other, mask.base)) {
504 return appliesUntyped(element, compiler);
505 }
506
507 // If [self] is a subclass of [other], it inherits the
508 // implementation of [element].
509 ClassElement cls = self;
510 if (cls.isSubclassOf(other)) {
511 // Resolve an invocation of [element.name] on [self]. If it
512 // is found, this selector is a candidate.
513 return hasElementIn(cls, element) && appliesUntyped(element, compiler);
514 }
515 }
516 return false;
517 } 456 }
518 } 457 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698