| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 /** A formal parameter to a [Method]. */ | 5 /** A formal parameter to a [Method]. */ |
| 6 class Parameter { | 6 class Parameter { |
| 7 FormalNode definition; | 7 FormalNode definition; |
| 8 Member method; | 8 Member method; |
| 9 | 9 |
| 10 String name; | 10 String name; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 | 26 |
| 27 if (definition.value != null) { | 27 if (definition.value != null) { |
| 28 // To match VM, detect cases where value was not actually specified in | 28 // To match VM, detect cases where value was not actually specified in |
| 29 // code and don't signal errors. | 29 // code and don't signal errors. |
| 30 // TODO(jimhug): Clean up after issue #352 is resolved. | 30 // TODO(jimhug): Clean up after issue #352 is resolved. |
| 31 if (!hasDefaultValue) return; | 31 if (!hasDefaultValue) return; |
| 32 | 32 |
| 33 if (method.name == ':call') { | 33 if (method.name == ':call') { |
| 34 // TODO(jimhug): Need simpler way to detect "true" function types vs. | 34 // TODO(jimhug): Need simpler way to detect "true" function types vs. |
| 35 // regular methods being used as function types for closures. | 35 // regular methods being used as function types for closures. |
| 36 if (method.definition.body == null) { | 36 // TODO(sigmund): Disallow non-null default values for native calls? |
| 37 if (method.definition.body == null && !method.isNative) { |
| 37 world.error('default value not allowed on function type', | 38 world.error('default value not allowed on function type', |
| 38 definition.span); | 39 definition.span); |
| 39 } | 40 } |
| 40 } else if (method.isAbstract) { | 41 } else if (method.isAbstract) { |
| 41 world.error('default value not allowed on abstract methods', | 42 world.error('default value not allowed on abstract methods', |
| 42 definition.span); | 43 definition.span); |
| 43 } | 44 } |
| 44 } else if (isInitializer && !method.isConstructor) { | 45 } else if (isInitializer && !method.isConstructor) { |
| 45 world.error('initializer parameters only allowed on constructors', | 46 world.error('initializer parameters only allowed on constructors', |
| 46 definition.span); | 47 definition.span); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 bool get isFinal() => false; | 109 bool get isFinal() => false; |
| 109 | 110 |
| 110 // TODO(jmesserly): these only makes sense on methods, but because of | 111 // TODO(jmesserly): these only makes sense on methods, but because of |
| 111 // ConcreteMember we need to support them on Member. | 112 // ConcreteMember we need to support them on Member. |
| 112 bool get isConst() => false; | 113 bool get isConst() => false; |
| 113 bool get isFactory() => false; | 114 bool get isFactory() => false; |
| 114 | 115 |
| 115 bool get isOperator() => name.startsWith(':'); | 116 bool get isOperator() => name.startsWith(':'); |
| 116 bool get isCallMethod() => name == ':call'; | 117 bool get isCallMethod() => name == ':call'; |
| 117 | 118 |
| 118 bool get prefersPropertySyntax() => true; | 119 bool get requiresPropertySyntax() => false; |
| 119 bool get requiresFieldSyntax() => false; | 120 bool get requiresFieldSyntax() => false; |
| 120 | 121 |
| 121 bool get isNative() => false; | 122 bool get isNative() => false; |
| 122 String get constructorName() { | 123 String get constructorName() { |
| 123 world.internalError('can not be a constructor', span); | 124 world.internalError('can not be a constructor', span); |
| 124 } | 125 } |
| 125 | 126 |
| 126 // Don't display an error here; we'll get a better error later. | 127 // Don't display an error here; we'll get a better error later. |
| 127 void provideFieldSyntax() {} | 128 void provideFieldSyntax() {} |
| 128 void providePropertySyntax() {} | 129 void providePropertySyntax() {} |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 // other.returnType.ensureAssignableFrom(returnType, null, true); | 290 // other.returnType.ensureAssignableFrom(returnType, null, true); |
| 290 return true; | 291 return true; |
| 291 // TODO(jimhug): Merge in overridesProperty logic here. | 292 // TODO(jimhug): Merge in overridesProperty logic here. |
| 292 } else { | 293 } else { |
| 293 world.error('field can not override anything but property', | 294 world.error('field can not override anything but property', |
| 294 span, other.span); | 295 span, other.span); |
| 295 return false; | 296 return false; |
| 296 } | 297 } |
| 297 } | 298 } |
| 298 | 299 |
| 299 bool get prefersPropertySyntax() => false; | |
| 300 bool get requiresFieldSyntax() => isNative; | |
| 301 | |
| 302 void provideFieldSyntax() {} // Nothing to do. | 300 void provideFieldSyntax() {} // Nothing to do. |
| 303 void providePropertySyntax() { _providePropertySyntax = true; } | 301 void providePropertySyntax() { _providePropertySyntax = true; } |
| 304 | 302 |
| 305 FieldMember(String name, Type declaringType, this.definition, this.value) | 303 FieldMember(String name, Type declaringType, this.definition, this.value) |
| 306 : super(name, declaringType), isNative = false; | 304 : super(name, declaringType), isNative = false; |
| 307 | 305 |
| 308 SourceSpan get span() => definition == null ? null : definition.span; | 306 SourceSpan get span() => definition == null ? null : definition.span; |
| 309 | 307 |
| 310 Type get returnType() => type; | 308 Type get returnType() => type; |
| 311 | 309 |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 Member _overriddenField; | 453 Member _overriddenField; |
| 456 | 454 |
| 457 bool _provideFieldSyntax = false; | 455 bool _provideFieldSyntax = false; |
| 458 | 456 |
| 459 // TODO(jimhug): What is the right span for this beast? | 457 // TODO(jimhug): What is the right span for this beast? |
| 460 SourceSpan get span() => getter != null ? getter.span : null; | 458 SourceSpan get span() => getter != null ? getter.span : null; |
| 461 | 459 |
| 462 bool get canGet() => getter != null; | 460 bool get canGet() => getter != null; |
| 463 bool get canSet() => setter != null; | 461 bool get canSet() => setter != null; |
| 464 | 462 |
| 465 bool get prefersPropertySyntax() => true; | 463 // If the property is just a declaration in an interface, continue to allow |
| 466 bool get requiresFieldSyntax() => false; | 464 // field syntax in the generated code. |
| 465 bool get requiresPropertySyntax() => declaringType.isClass; |
| 467 | 466 |
| 468 void provideFieldSyntax() { _provideFieldSyntax = true; } | 467 void provideFieldSyntax() { _provideFieldSyntax = true; } |
| 469 void providePropertySyntax() {}// Nothing to do. | 468 void providePropertySyntax() { |
| 469 // when overriding native fields, we still provide a field syntax to ensure |
| 470 // that native functions will find the appropriate property implementation. |
| 471 // TODO(sigmund): should check for this transitively... |
| 472 if (_overriddenField != null && _overriddenField.isNative) { |
| 473 provideFieldSyntax(); |
| 474 } |
| 475 } |
| 470 | 476 |
| 471 // TODO(jimhug): Union of getter and setters sucks! | 477 // TODO(jimhug): Union of getter and setters sucks! |
| 472 bool get isStatic() => getter == null ? setter.isStatic : getter.isStatic; | 478 bool get isStatic() => getter == null ? setter.isStatic : getter.isStatic; |
| 473 | 479 |
| 474 bool get isProperty() => true; | 480 bool get isProperty() => true; |
| 475 | 481 |
| 476 Type get returnType() { | 482 Type get returnType() { |
| 477 return getter == null ? setter.returnType : getter.returnType; | 483 return getter == null ? setter.returnType : getter.returnType; |
| 478 } | 484 } |
| 479 | 485 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 | 607 |
| 602 bool get canGet() => baseMember.canGet; | 608 bool get canGet() => baseMember.canGet; |
| 603 bool get canSet() => baseMember.canSet; | 609 bool get canSet() => baseMember.canSet; |
| 604 bool canInvoke(MethodGenerator context, Arguments args) => | 610 bool canInvoke(MethodGenerator context, Arguments args) => |
| 605 baseMember.canInvoke(context, args); | 611 baseMember.canInvoke(context, args); |
| 606 | 612 |
| 607 bool get isField() => baseMember.isField; | 613 bool get isField() => baseMember.isField; |
| 608 bool get isMethod() => baseMember.isMethod; | 614 bool get isMethod() => baseMember.isMethod; |
| 609 bool get isProperty() => baseMember.isProperty; | 615 bool get isProperty() => baseMember.isProperty; |
| 610 | 616 |
| 611 bool get prefersPropertySyntax() => baseMember.prefersPropertySyntax; | 617 bool get requiresPropertySyntax() => baseMember.requiresPropertySyntax; |
| 612 bool get requiresFieldSyntax() => baseMember.requiresFieldSyntax; | 618 bool get requiresFieldSyntax() => baseMember.requiresFieldSyntax; |
| 613 | 619 |
| 614 void provideFieldSyntax() => baseMember.provideFieldSyntax(); | 620 void provideFieldSyntax() => baseMember.provideFieldSyntax(); |
| 615 void providePropertySyntax() => baseMember.providePropertySyntax(); | 621 void providePropertySyntax() => baseMember.providePropertySyntax(); |
| 616 | 622 |
| 617 bool get isConstructor() => name == declaringType.name; | 623 bool get isConstructor() => name == declaringType.name; |
| 618 | 624 |
| 619 String get constructorName() => baseMember.constructorName; | 625 String get constructorName() => baseMember.constructorName; |
| 620 | 626 |
| 621 Definition get definition() => baseMember.definition; | 627 Definition get definition() => baseMember.definition; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 703 Member initDelegate; | 709 Member initDelegate; |
| 704 | 710 |
| 705 MethodMember(String name, Type declaringType, this.definition) | 711 MethodMember(String name, Type declaringType, this.definition) |
| 706 : super(name, declaringType); | 712 : super(name, declaringType); |
| 707 | 713 |
| 708 bool get isConstructor() => name == declaringType.name; | 714 bool get isConstructor() => name == declaringType.name; |
| 709 bool get isMethod() => !isConstructor; | 715 bool get isMethod() => !isConstructor; |
| 710 | 716 |
| 711 bool get isNative() => definition.nativeBody != null; | 717 bool get isNative() => definition.nativeBody != null; |
| 712 | 718 |
| 713 bool get canGet() => false; // TODO(jimhug): get bound method support. | 719 bool get canGet() => true; |
| 714 bool get canSet() => false; | 720 bool get canSet() => false; |
| 715 | 721 |
| 722 bool get requiresPropertySyntax() => true; |
| 723 |
| 716 SourceSpan get span() => definition == null ? null : definition.span; | 724 SourceSpan get span() => definition == null ? null : definition.span; |
| 717 | 725 |
| 718 String get constructorName() { | 726 String get constructorName() { |
| 719 var returnType = definition.returnType; | 727 var returnType = definition.returnType; |
| 720 if (returnType == null) return ''; | 728 if (returnType == null) return ''; |
| 721 if (returnType is GenericTypeReference) { | 729 if (returnType is GenericTypeReference) { |
| 722 return ''; | 730 return ''; |
| 723 } | 731 } |
| 724 | 732 |
| 725 // TODO(jmesserly): make this easier? | 733 // TODO(jmesserly): make this easier? |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 782 int indexOfParameter(String name) { | 790 int indexOfParameter(String name) { |
| 783 for (int i = 0; i < parameters.length; i++) { | 791 for (int i = 0; i < parameters.length; i++) { |
| 784 final p = parameters[i]; | 792 final p = parameters[i]; |
| 785 if (p.isOptional && p.name == name) { | 793 if (p.isOptional && p.name == name) { |
| 786 return i; | 794 return i; |
| 787 } | 795 } |
| 788 } | 796 } |
| 789 return -1; | 797 return -1; |
| 790 } | 798 } |
| 791 | 799 |
| 792 bool get prefersPropertySyntax() => true; | |
| 793 bool get requiresFieldSyntax() => false; | |
| 794 | |
| 795 void provideFieldSyntax() { _provideFieldSyntax = true; } | 800 void provideFieldSyntax() { _provideFieldSyntax = true; } |
| 796 void providePropertySyntax() { _providePropertySyntax = true; } | 801 void providePropertySyntax() { _providePropertySyntax = true; } |
| 797 | 802 |
| 798 Value _set(MethodGenerator context, Node node, Value target, Value value, | 803 Value _set(MethodGenerator context, Node node, Value target, Value value, |
| 799 [bool isDynamic=false]) { | 804 [bool isDynamic=false]) { |
| 800 world.error('cannot set method', node.span); | 805 world.error('cannot set method', node.span); |
| 801 } | 806 } |
| 802 | 807 |
| 803 Value _get(MethodGenerator context, Node node, Value target, | 808 Value _get(MethodGenerator context, Node node, Value target, |
| 804 [bool isDynamic=false]) { | 809 [bool isDynamic=false]) { |
| (...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1478 } | 1483 } |
| 1479 return new Value(world.varType, | 1484 return new Value(world.varType, |
| 1480 '${target.code}.$jsname() /*no applicable $action*/', node.span); | 1485 '${target.code}.$jsname() /*no applicable $action*/', node.span); |
| 1481 } | 1486 } |
| 1482 | 1487 |
| 1483 bool _treatAsField; | 1488 bool _treatAsField; |
| 1484 bool get treatAsField() { | 1489 bool get treatAsField() { |
| 1485 if (_treatAsField == null) { | 1490 if (_treatAsField == null) { |
| 1486 // If this is the global MemberSet from world, always bind dynamically. | 1491 // If this is the global MemberSet from world, always bind dynamically. |
| 1487 // Note: we need this for proper noSuchMethod and REPL behavior. | 1492 // Note: we need this for proper noSuchMethod and REPL behavior. |
| 1488 _treatAsField = !isVar; | 1493 _treatAsField = !isVar && (members.some((m) => m.requiresFieldSyntax) |
| 1489 for (var member in members) { | 1494 || members.every((m) => !m.requiresPropertySyntax)); |
| 1490 if (member.requiresFieldSyntax) { | 1495 |
| 1491 _treatAsField = true; | |
| 1492 break; | |
| 1493 } | |
| 1494 if (member.prefersPropertySyntax) { | |
| 1495 _treatAsField = false; | |
| 1496 } | |
| 1497 } | |
| 1498 for (var member in members) { | 1496 for (var member in members) { |
| 1499 if (_treatAsField) { | 1497 if (_treatAsField) { |
| 1500 member.provideFieldSyntax(); | 1498 member.provideFieldSyntax(); |
| 1501 } else { | 1499 } else { |
| 1502 member.providePropertySyntax(); | 1500 member.providePropertySyntax(); |
| 1503 } | 1501 } |
| 1504 } | 1502 } |
| 1505 } | 1503 } |
| 1506 return _treatAsField; | 1504 return _treatAsField; |
| 1507 } | 1505 } |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1778 } | 1776 } |
| 1779 | 1777 |
| 1780 void forEach(void f(Member member)) { | 1778 void forEach(void f(Member member)) { |
| 1781 factories.forEach((_, Map constructors) { | 1779 factories.forEach((_, Map constructors) { |
| 1782 constructors.forEach((_, Member member) { | 1780 constructors.forEach((_, Member member) { |
| 1783 f(member); | 1781 f(member); |
| 1784 }); | 1782 }); |
| 1785 }); | 1783 }); |
| 1786 } | 1784 } |
| 1787 } | 1785 } |
| OLD | NEW |