| OLD | NEW |
| 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 '../elements/elements.dart'; | 7 import '../elements/elements.dart'; |
| 8 import '../dart2jslib.dart'; | 8 import '../dart2jslib.dart'; |
| 9 import '../dart_types.dart'; | 9 import '../dart_types.dart'; |
| 10 import '../types/types.dart'; | 10 import '../types/types.dart'; |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 180 Selector result = new Selector.internal( | 180 Selector result = new Selector.internal( |
| 181 kind, name, library, argumentCount, | 181 kind, name, library, argumentCount, |
| 182 namedArguments, orderedNamedArguments, | 182 namedArguments, orderedNamedArguments, |
| 183 hashCode); | 183 hashCode); |
| 184 list.add(result); | 184 list.add(result); |
| 185 return result; | 185 return result; |
| 186 } | 186 } |
| 187 | 187 |
| 188 factory Selector.fromElement(Element element, Compiler compiler) { | 188 factory Selector.fromElement(Element element, Compiler compiler) { |
| 189 String name = element.name; | 189 String name = element.name; |
| 190 if (element.isFunction()) { | 190 if (element.isFunction) { |
| 191 if (name == '[]') { | 191 if (name == '[]') { |
| 192 return new Selector.index(); | 192 return new Selector.index(); |
| 193 } else if (name == '[]=') { | 193 } else if (name == '[]=') { |
| 194 return new Selector.indexSet(); | 194 return new Selector.indexSet(); |
| 195 } | 195 } |
| 196 FunctionSignature signature = | 196 FunctionSignature signature = |
| 197 element.asFunctionElement().computeSignature(compiler); | 197 element.asFunctionElement().computeSignature(compiler); |
| 198 int arity = signature.parameterCount; | 198 int arity = signature.parameterCount; |
| 199 List<String> namedArguments = null; | 199 List<String> namedArguments = null; |
| 200 if (signature.optionalParametersAreNamed) { | 200 if (signature.optionalParametersAreNamed) { |
| 201 namedArguments = | 201 namedArguments = |
| 202 signature.orderedOptionalParameters.map((e) => e.name).toList(); | 202 signature.orderedOptionalParameters.map((e) => e.name).toList(); |
| 203 } | 203 } |
| 204 if (Elements.operatorNameToIdentifier(name) != name) { | 204 if (Elements.operatorNameToIdentifier(name) != name) { |
| 205 // Operators cannot have named arguments, however, that doesn't prevent | 205 // Operators cannot have named arguments, however, that doesn't prevent |
| 206 // a user from declaring such an operator. | 206 // a user from declaring such an operator. |
| 207 return new Selector( | 207 return new Selector( |
| 208 SelectorKind.OPERATOR, name, null, arity, namedArguments); | 208 SelectorKind.OPERATOR, name, null, arity, namedArguments); |
| 209 } else { | 209 } else { |
| 210 return new Selector.call( | 210 return new Selector.call( |
| 211 name, element.getLibrary(), arity, namedArguments); | 211 name, element.library, arity, namedArguments); |
| 212 } | 212 } |
| 213 } else if (element.isSetter()) { | 213 } else if (element.isSetter) { |
| 214 return new Selector.setter(name, element.getLibrary()); | 214 return new Selector.setter(name, element.library); |
| 215 } else if (element.isGetter()) { | 215 } else if (element.isGetter) { |
| 216 return new Selector.getter(name, element.getLibrary()); | 216 return new Selector.getter(name, element.library); |
| 217 } else if (element.isField()) { | 217 } else if (element.isField) { |
| 218 return new Selector.getter(name, element.getLibrary()); | 218 return new Selector.getter(name, element.library); |
| 219 } else { | 219 } else { |
| 220 throw new SpannableAssertionFailure( | 220 throw new SpannableAssertionFailure( |
| 221 element, "Can't get selector from $element"); | 221 element, "Can't get selector from $element"); |
| 222 } | 222 } |
| 223 } | 223 } |
| 224 | 224 |
| 225 factory Selector.getter(String name, LibraryElement library) | 225 factory Selector.getter(String name, LibraryElement library) |
| 226 => new Selector(SelectorKind.GETTER, name, library, 0); | 226 => new Selector(SelectorKind.GETTER, name, library, 0); |
| 227 | 227 |
| 228 factory Selector.getterFrom(Selector selector) | 228 factory Selector.getterFrom(Selector selector) |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 | 267 |
| 268 factory Selector.callConstructor(String name, LibraryElement library, | 268 factory Selector.callConstructor(String name, LibraryElement library, |
| 269 [int arity = 0, | 269 [int arity = 0, |
| 270 List<String> namedArguments]) | 270 List<String> namedArguments]) |
| 271 => new Selector(SelectorKind.CALL, name, library, | 271 => new Selector(SelectorKind.CALL, name, library, |
| 272 arity, namedArguments); | 272 arity, namedArguments); |
| 273 | 273 |
| 274 factory Selector.callDefaultConstructor(LibraryElement library) | 274 factory Selector.callDefaultConstructor(LibraryElement library) |
| 275 => new Selector(SelectorKind.CALL, "", library, 0); | 275 => new Selector(SelectorKind.CALL, "", library, 0); |
| 276 | 276 |
| 277 bool isGetter() => identical(kind, SelectorKind.GETTER); | 277 bool get isGetter => identical(kind, SelectorKind.GETTER); |
| 278 bool isSetter() => identical(kind, SelectorKind.SETTER); | 278 bool get isSetter => identical(kind, SelectorKind.SETTER); |
| 279 bool isCall() => identical(kind, SelectorKind.CALL); | 279 bool get isCall => identical(kind, SelectorKind.CALL); |
| 280 bool isClosureCall() { | 280 bool get isClosureCall { |
| 281 String callName = Compiler.CALL_OPERATOR_NAME; | 281 String callName = Compiler.CALL_OPERATOR_NAME; |
| 282 return isCall() && name == callName; | 282 return isCall && name == callName; |
| 283 } | 283 } |
| 284 | 284 |
| 285 bool isIndex() => identical(kind, SelectorKind.INDEX) && argumentCount == 1; | 285 bool get isIndex => identical(kind, SelectorKind.INDEX) && argumentCount == 1; |
| 286 bool isIndexSet() => identical(kind, SelectorKind.INDEX) && argumentCount == 2
; | 286 bool get isIndexSet => identical(kind, SelectorKind.INDEX) && argumentCount ==
2; |
| 287 | 287 |
| 288 bool isOperator() => identical(kind, SelectorKind.OPERATOR); | 288 bool get isOperator => identical(kind, SelectorKind.OPERATOR); |
| 289 bool isUnaryOperator() => isOperator() && argumentCount == 0; | 289 bool get isUnaryOperator => isOperator && argumentCount == 0; |
| 290 | 290 |
| 291 /** Check whether this is a call to 'assert'. */ | 291 /** Check whether this is a call to 'assert'. */ |
| 292 bool isAssert() => isCall() && identical(name, "assert"); | 292 bool get isAssert => isCall && identical(name, "assert"); |
| 293 | 293 |
| 294 int get namedArgumentCount => namedArguments.length; | 294 int get namedArgumentCount => namedArguments.length; |
| 295 int get positionalArgumentCount => argumentCount - namedArgumentCount; | 295 int get positionalArgumentCount => argumentCount - namedArgumentCount; |
| 296 | 296 |
| 297 bool get hasExactMask => false; | 297 bool get hasExactMask => false; |
| 298 TypeMask get mask => null; | 298 TypeMask get mask => null; |
| 299 Selector get asUntyped => this; | 299 Selector get asUntyped => this; |
| 300 | 300 |
| 301 /** | 301 /** |
| 302 * The member name for invocation mirrors created from this selector. | 302 * The member name for invocation mirrors created from this selector. |
| 303 */ | 303 */ |
| 304 String get invocationMirrorMemberName => | 304 String get invocationMirrorMemberName => |
| 305 isSetter() ? '$name=' : name; | 305 isSetter ? '$name=' : name; |
| 306 | 306 |
| 307 int get invocationMirrorKind { | 307 int get invocationMirrorKind { |
| 308 const int METHOD = 0; | 308 const int METHOD = 0; |
| 309 const int GETTER = 1; | 309 const int GETTER = 1; |
| 310 const int SETTER = 2; | 310 const int SETTER = 2; |
| 311 int kind = METHOD; | 311 int kind = METHOD; |
| 312 if (isGetter()) { | 312 if (isGetter) { |
| 313 kind = GETTER; | 313 kind = GETTER; |
| 314 } else if (isSetter()) { | 314 } else if (isSetter) { |
| 315 kind = SETTER; | 315 kind = SETTER; |
| 316 } | 316 } |
| 317 return kind; | 317 return kind; |
| 318 } | 318 } |
| 319 | 319 |
| 320 bool appliesUnnamed(Element element, Compiler compiler) { | 320 bool appliesUnnamed(Element element, Compiler compiler) { |
| 321 assert(sameNameHack(element, compiler)); | 321 assert(sameNameHack(element, compiler)); |
| 322 return appliesUntyped(element, compiler); | 322 return appliesUntyped(element, compiler); |
| 323 } | 323 } |
| 324 | 324 |
| 325 bool appliesUntyped(Element element, Compiler compiler) { | 325 bool appliesUntyped(Element element, Compiler compiler) { |
| 326 assert(sameNameHack(element, compiler)); | 326 assert(sameNameHack(element, compiler)); |
| 327 if (Elements.isUnresolved(element)) return false; | 327 if (Elements.isUnresolved(element)) return false; |
| 328 if (isPrivateName(name) && library != element.getLibrary()) return false; | 328 if (isPrivateName(name) && library != element.library) return false; |
| 329 if (element.isForeign(compiler)) return true; | 329 if (element.isForeign(compiler)) return true; |
| 330 if (element.isSetter()) return isSetter(); | 330 if (element.isSetter) return isSetter; |
| 331 if (element.isGetter()) return isGetter() || isCall(); | 331 if (element.isGetter) return isGetter || isCall; |
| 332 if (element.isField()) { | 332 if (element.isField) { |
| 333 return isSetter() | 333 return isSetter |
| 334 ? !element.modifiers.isFinalOrConst() | 334 ? !element.modifiers.isFinalOrConst |
| 335 : isGetter() || isCall(); | 335 : isGetter || isCall; |
| 336 } | 336 } |
| 337 if (isGetter()) return true; | 337 if (isGetter) return true; |
| 338 if (isSetter()) return false; | 338 if (isSetter) return false; |
| 339 return signatureApplies(element, compiler); | 339 return signatureApplies(element, compiler); |
| 340 } | 340 } |
| 341 | 341 |
| 342 bool signatureApplies(FunctionElement function, Compiler compiler) { | 342 bool signatureApplies(FunctionElement function, Compiler compiler) { |
| 343 FunctionSignature parameters = function.computeSignature(compiler); | 343 FunctionSignature parameters = function.computeSignature(compiler); |
| 344 if (argumentCount > parameters.parameterCount) return false; | 344 if (argumentCount > parameters.parameterCount) return false; |
| 345 int requiredParameterCount = parameters.requiredParameterCount; | 345 int requiredParameterCount = parameters.requiredParameterCount; |
| 346 int optionalParameterCount = parameters.optionalParameterCount; | 346 int optionalParameterCount = parameters.optionalParameterCount; |
| 347 if (positionalArgumentCount < requiredParameterCount) return false; | 347 if (positionalArgumentCount < requiredParameterCount) return false; |
| 348 | 348 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 368 // check in the resolver also. | 368 // check in the resolver also. |
| 369 nameSet.remove(name); | 369 nameSet.remove(name); |
| 370 } | 370 } |
| 371 return true; | 371 return true; |
| 372 } | 372 } |
| 373 } | 373 } |
| 374 | 374 |
| 375 bool sameNameHack(Element element, Compiler compiler) { | 375 bool sameNameHack(Element element, Compiler compiler) { |
| 376 // TODO(ngeoffray): Remove workaround checks. | 376 // TODO(ngeoffray): Remove workaround checks. |
| 377 return element == compiler.assertMethod | 377 return element == compiler.assertMethod |
| 378 || element.isConstructor() | 378 || element.isConstructor |
| 379 || name == element.name; | 379 || name == element.name; |
| 380 } | 380 } |
| 381 | 381 |
| 382 bool applies(Element element, Compiler compiler) { | 382 bool applies(Element element, Compiler compiler) { |
| 383 if (!sameNameHack(element, compiler)) return false; | 383 if (!sameNameHack(element, compiler)) return false; |
| 384 return appliesUnnamed(element, compiler); | 384 return appliesUnnamed(element, compiler); |
| 385 } | 385 } |
| 386 | 386 |
| 387 /** | 387 /** |
| 388 * Fills [list] with the arguments in a defined order. | 388 * Fills [list] with the arguments in a defined order. |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 Link<Node> nodes = computeCallNodesFromParameters(); | 499 Link<Node> nodes = computeCallNodesFromParameters(); |
| 500 | 500 |
| 501 // Synthesize a selector for the call. | 501 // Synthesize a selector for the call. |
| 502 // TODO(ngeoffray): Should the resolver do it instead? | 502 // TODO(ngeoffray): Should the resolver do it instead? |
| 503 List<String> namedParameters; | 503 List<String> namedParameters; |
| 504 if (signature.optionalParametersAreNamed) { | 504 if (signature.optionalParametersAreNamed) { |
| 505 namedParameters = | 505 namedParameters = |
| 506 signature.optionalParameters.toList().map((e) => e.name).toList(); | 506 signature.optionalParameters.toList().map((e) => e.name).toList(); |
| 507 } | 507 } |
| 508 Selector selector = new Selector.call(callee.name, | 508 Selector selector = new Selector.call(callee.name, |
| 509 caller.getLibrary(), | 509 caller.library, |
| 510 signature.parameterCount, | 510 signature.parameterCount, |
| 511 namedParameters); | 511 namedParameters); |
| 512 | 512 |
| 513 return selector.addArgumentsToList(nodes, | 513 return selector.addArgumentsToList(nodes, |
| 514 list, | 514 list, |
| 515 callee, | 515 callee, |
| 516 internalCompileArgument, | 516 internalCompileArgument, |
| 517 compileConstant, | 517 compileConstant, |
| 518 compiler); | 518 compiler); |
| 519 } | 519 } |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 653 factory TypedSelector.subclass(ClassElement base, Selector selector) | 653 factory TypedSelector.subclass(ClassElement base, Selector selector) |
| 654 => new TypedSelector(new TypeMask.subclass(base), selector); | 654 => new TypedSelector(new TypeMask.subclass(base), selector); |
| 655 | 655 |
| 656 factory TypedSelector.subtype(ClassElement base, Selector selector) | 656 factory TypedSelector.subtype(ClassElement base, Selector selector) |
| 657 => new TypedSelector(new TypeMask.subtype(base), selector); | 657 => new TypedSelector(new TypeMask.subtype(base), selector); |
| 658 | 658 |
| 659 bool appliesUnnamed(Element element, Compiler compiler) { | 659 bool appliesUnnamed(Element element, Compiler compiler) { |
| 660 assert(sameNameHack(element, compiler)); | 660 assert(sameNameHack(element, compiler)); |
| 661 // [TypedSelector] are only used after resolution. | 661 // [TypedSelector] are only used after resolution. |
| 662 assert(compiler.phase > Compiler.PHASE_RESOLVING); | 662 assert(compiler.phase > Compiler.PHASE_RESOLVING); |
| 663 if (!element.isMember()) return false; | 663 if (!element.isMember) return false; |
| 664 | 664 |
| 665 // A closure can be called through any typed selector: | 665 // A closure can be called through any typed selector: |
| 666 // class A { | 666 // class A { |
| 667 // get foo => () => 42; | 667 // get foo => () => 42; |
| 668 // bar() => foo(); // The call to 'foo' is a typed selector. | 668 // bar() => foo(); // The call to 'foo' is a typed selector. |
| 669 // } | 669 // } |
| 670 if (element.getEnclosingClass().isClosure()) { | 670 if (element.enclosingClass.isClosure) { |
| 671 return appliesUntyped(element, compiler); | 671 return appliesUntyped(element, compiler); |
| 672 } | 672 } |
| 673 | 673 |
| 674 if (!mask.canHit(element, this, compiler)) return false; | 674 if (!mask.canHit(element, this, compiler)) return false; |
| 675 return appliesUntyped(element, compiler); | 675 return appliesUntyped(element, compiler); |
| 676 } | 676 } |
| 677 | 677 |
| 678 Selector extendIfReachesAll(Compiler compiler) { | 678 Selector extendIfReachesAll(Compiler compiler) { |
| 679 bool canReachAll = compiler.enabledInvokeOn | 679 bool canReachAll = compiler.enabledInvokeOn |
| 680 && mask.needsNoSuchMethodHandling(this, compiler); | 680 && mask.needsNoSuchMethodHandling(this, compiler); |
| 681 return canReachAll | 681 return canReachAll |
| 682 ? new TypedSelector(compiler.typesTask.dynamicType, this) | 682 ? new TypedSelector(compiler.typesTask.dynamicType, this) |
| 683 : this; | 683 : this; |
| 684 } | 684 } |
| 685 } | 685 } |
| OLD | NEW |