| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 engine.resolver_test; | 5 library engine.resolver_test; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 import 'package:analyzer/src/generated/java_core.dart'; | 8 import 'package:analyzer/src/generated/java_core.dart'; |
| 9 import 'package:analyzer/src/generated/java_junit.dart'; | 9 import 'package:analyzer/src/generated/java_junit.dart'; |
| 10 import 'package:analyzer/src/generated/java_engine.dart'; | 10 import 'package:analyzer/src/generated/java_engine.dart'; |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 "class C {", | 430 "class C {", |
| 431 " final A a;", | 431 " final A a;", |
| 432 " const C(this.a);", | 432 " const C(this.a);", |
| 433 "}", | 433 "}", |
| 434 "var v = const C(const B());"])); | 434 "var v = const C(const B());"])); |
| 435 resolve(source); | 435 resolve(source); |
| 436 assertNoErrors(source); | 436 assertNoErrors(source); |
| 437 verify([source]); | 437 verify([source]); |
| 438 } | 438 } |
| 439 | 439 |
| 440 void test_fieldFormalParameterAssignableToField_fieldType_unresolved_null() { |
| 441 // Null always passes runtime type checks, even when the type is |
| 442 // unresolved. |
| 443 Source source = addSource(EngineTestCase.createSource([ |
| 444 "class A {", |
| 445 " final Unresolved x;", |
| 446 " const A(String this.x);", |
| 447 "}", |
| 448 "var v = const A(null);"])); |
| 449 resolve(source); |
| 450 assertErrors(source, [ |
| 451 StaticWarningCode.UNDEFINED_CLASS]); |
| 452 verify([source]); |
| 453 } |
| 454 |
| 440 void test_fieldFormalParameterAssignableToField_implements() { | 455 void test_fieldFormalParameterAssignableToField_implements() { |
| 441 // According to checked-mode type checking rules, a value of type B is | 456 // According to checked-mode type checking rules, a value of type B is |
| 442 // assignable to a field of type A, because B implements A (and hence is a | 457 // assignable to a field of type A, because B implements A (and hence is a |
| 443 // subtype of A). | 458 // subtype of A). |
| 444 Source source = addSource(EngineTestCase.createSource([ | 459 Source source = addSource(EngineTestCase.createSource([ |
| 445 "class A {}", | 460 "class A {}", |
| 446 "class B implements A {", | 461 "class B implements A {", |
| 447 " const B();", | 462 " const B();", |
| 448 "}", | 463 "}", |
| 449 "class C {", | 464 "class C {", |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 " const A(String this.x);", | 612 " const A(String this.x);", |
| 598 "}", | 613 "}", |
| 599 "var v = const A('foo');"])); | 614 "var v = const A('foo');"])); |
| 600 resolve(source); | 615 resolve(source); |
| 601 assertErrors(source, [ | 616 assertErrors(source, [ |
| 602 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, | 617 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, |
| 603 StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE]); | 618 StaticWarningCode.FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE]); |
| 604 verify([source]); | 619 verify([source]); |
| 605 } | 620 } |
| 606 | 621 |
| 622 void test_fieldFormalParameterNotAssignableToField_fieldType_unresolved() { |
| 623 Source source = addSource(EngineTestCase.createSource([ |
| 624 "class A {", |
| 625 " final Unresolved x;", |
| 626 " const A(String this.x);", |
| 627 "}", |
| 628 "var v = const A('foo');"])); |
| 629 resolve(source); |
| 630 assertErrors(source, [ |
| 631 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, |
| 632 StaticWarningCode.UNDEFINED_CLASS]); |
| 633 verify([source]); |
| 634 } |
| 635 |
| 607 void test_fieldFormalParameterNotAssignableToField_extends() { | 636 void test_fieldFormalParameterNotAssignableToField_extends() { |
| 608 // According to checked-mode type checking rules, a value of type A is not | 637 // According to checked-mode type checking rules, a value of type A is not |
| 609 // assignable to a field of type B, because B extends A (the subtyping | 638 // assignable to a field of type B, because B extends A (the subtyping |
| 610 // relationship is in the wrong direction). | 639 // relationship is in the wrong direction). |
| 611 Source source = addSource(EngineTestCase.createSource([ | 640 Source source = addSource(EngineTestCase.createSource([ |
| 612 "class A {", | 641 "class A {", |
| 613 " const A();", | 642 " const A();", |
| 614 "}", | 643 "}", |
| 615 "class B extends A {", | 644 "class B extends A {", |
| 616 " const B();", | 645 " const B();", |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 738 " const A(x) : y = x;", | 767 " const A(x) : y = x;", |
| 739 " final int y;", | 768 " final int y;", |
| 740 "}", | 769 "}", |
| 741 "var v = const A('foo');"])); | 770 "var v = const A('foo');"])); |
| 742 resolve(source); | 771 resolve(source); |
| 743 assertErrors(source, [ | 772 assertErrors(source, [ |
| 744 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH]); | 773 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH]); |
| 745 verify([source]); | 774 verify([source]); |
| 746 } | 775 } |
| 747 | 776 |
| 777 void test_fieldTypeMismatch_unresolved() { |
| 778 Source source = addSource(EngineTestCase.createSource([ |
| 779 "class A {", |
| 780 " const A(x) : y = x;", |
| 781 " final Unresolved y;", |
| 782 "}", |
| 783 "var v = const A('foo');"])); |
| 784 resolve(source); |
| 785 assertErrors(source, [ |
| 786 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH, |
| 787 StaticWarningCode.UNDEFINED_CLASS]); |
| 788 verify([source]); |
| 789 } |
| 790 |
| 748 void test_fieldTypeOk_null() { | 791 void test_fieldTypeOk_null() { |
| 749 Source source = addSource(EngineTestCase.createSource([ | 792 Source source = addSource(EngineTestCase.createSource([ |
| 750 "class A {", | 793 "class A {", |
| 751 " const A(x) : y = x;", | 794 " const A(x) : y = x;", |
| 752 " final int y;", | 795 " final int y;", |
| 753 "}", | 796 "}", |
| 754 "var v = const A(null);"])); | 797 "var v = const A(null);"])); |
| 755 resolve(source); | 798 resolve(source); |
| 756 assertNoErrors(source); | 799 assertNoErrors(source); |
| 757 verify([source]); | 800 verify([source]); |
| 758 } | 801 } |
| 759 | 802 |
| 803 void test_fieldTypeOk_unresolved_null() { |
| 804 // Null always passes runtime type checks, even when the type is |
| 805 // unresolved. |
| 806 Source source = addSource(EngineTestCase.createSource([ |
| 807 "class A {", |
| 808 " const A(x) : y = x;", |
| 809 " final Unresolved y;", |
| 810 "}", |
| 811 "var v = const A(null);"])); |
| 812 resolve(source); |
| 813 assertErrors(source, [ |
| 814 StaticWarningCode.UNDEFINED_CLASS]); |
| 815 verify([source]); |
| 816 } |
| 817 |
| 760 void test_listElementTypeNotAssignable() { | 818 void test_listElementTypeNotAssignable() { |
| 761 Source source = addSource(EngineTestCase.createSource(["var v = const <Strin
g> [42];"])); | 819 Source source = addSource(EngineTestCase.createSource(["var v = const <Strin
g> [42];"])); |
| 762 resolve(source); | 820 resolve(source); |
| 763 assertErrors(source, [ | 821 assertErrors(source, [ |
| 764 CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE, | 822 CheckedModeCompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE, |
| 765 StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]); | 823 StaticWarningCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE]); |
| 766 verify([source]); | 824 verify([source]); |
| 767 } | 825 } |
| 768 | 826 |
| 769 void test_mapKeyTypeNotAssignable() { | 827 void test_mapKeyTypeNotAssignable() { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 789 Source source = addSource(EngineTestCase.createSource([ | 847 Source source = addSource(EngineTestCase.createSource([ |
| 790 "class A {", | 848 "class A {", |
| 791 " const A(int x);", | 849 " const A(int x);", |
| 792 "}", | 850 "}", |
| 793 "var v = const A(null);"])); | 851 "var v = const A(null);"])); |
| 794 resolve(source); | 852 resolve(source); |
| 795 assertNoErrors(source); | 853 assertNoErrors(source); |
| 796 verify([source]); | 854 verify([source]); |
| 797 } | 855 } |
| 798 | 856 |
| 857 void test_parameterAssignable_undefined_null() { |
| 858 // Null always passes runtime type checks, even when the type is |
| 859 // unresolved. |
| 860 Source source = addSource(EngineTestCase.createSource([ |
| 861 "class A {", |
| 862 " const A(Unresolved x);", |
| 863 "}", |
| 864 "var v = const A(null);"])); |
| 865 resolve(source); |
| 866 assertErrors(source, [ |
| 867 StaticWarningCode.UNDEFINED_CLASS]); |
| 868 verify([source]); |
| 869 } |
| 870 |
| 799 void test_parameterAssignable_typeSubstitution() { | 871 void test_parameterAssignable_typeSubstitution() { |
| 800 Source source = addSource(EngineTestCase.createSource([ | 872 Source source = addSource(EngineTestCase.createSource([ |
| 801 "class A<T> {", | 873 "class A<T> {", |
| 802 " const A(T x);", | 874 " const A(T x);", |
| 803 "}", | 875 "}", |
| 804 "var v = const A<int>(3);"])); | 876 "var v = const A<int>(3);"])); |
| 805 resolve(source); | 877 resolve(source); |
| 806 assertNoErrors(source); | 878 assertNoErrors(source); |
| 807 verify([source]); | 879 verify([source]); |
| 808 } | 880 } |
| 809 | 881 |
| 810 void test_parameterNotAssignable() { | 882 void test_parameterNotAssignable() { |
| 811 Source source = addSource(EngineTestCase.createSource([ | 883 Source source = addSource(EngineTestCase.createSource([ |
| 812 "class A {", | 884 "class A {", |
| 813 " const A(int x);", | 885 " const A(int x);", |
| 814 "}", | 886 "}", |
| 815 "var v = const A('foo');"])); | 887 "var v = const A('foo');"])); |
| 816 resolve(source); | 888 resolve(source); |
| 817 assertErrors(source, [ | 889 assertErrors(source, [ |
| 818 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, | 890 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, |
| 819 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]); | 891 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]); |
| 820 verify([source]); | 892 verify([source]); |
| 821 } | 893 } |
| 822 | 894 |
| 895 void test_parameterNotAssignable_undefined() { |
| 896 Source source = addSource(EngineTestCase.createSource([ |
| 897 "class A {", |
| 898 " const A(Unresolved x);", |
| 899 "}", |
| 900 "var v = const A('foo');"])); |
| 901 resolve(source); |
| 902 assertErrors(source, [ |
| 903 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, |
| 904 StaticWarningCode.UNDEFINED_CLASS]); |
| 905 verify([source]); |
| 906 } |
| 907 |
| 823 void test_parameterNotAssignable_typeSubstitution() { | 908 void test_parameterNotAssignable_typeSubstitution() { |
| 824 Source source = addSource(EngineTestCase.createSource([ | 909 Source source = addSource(EngineTestCase.createSource([ |
| 825 "class A<T> {", | 910 "class A<T> {", |
| 826 " const A(T x);", | 911 " const A(T x);", |
| 827 "}", | 912 "}", |
| 828 "var v = const A<int>('foo');"])); | 913 "var v = const A<int>('foo');"])); |
| 829 resolve(source); | 914 resolve(source); |
| 830 assertErrors(source, [ | 915 assertErrors(source, [ |
| 831 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, | 916 CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, |
| 832 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]); | 917 StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]); |
| 833 verify([source]); | 918 verify([source]); |
| 834 } | 919 } |
| 835 | 920 |
| 836 void test_topLevelVarAssignable_null() { | 921 void test_topLevelVarAssignable_null() { |
| 837 Source source = addSource(EngineTestCase.createSource([ | 922 Source source = addSource(EngineTestCase.createSource([ |
| 838 "const int x = null;"])); | 923 "const int x = null;"])); |
| 839 resolve(source); | 924 resolve(source); |
| 840 assertNoErrors(source); | 925 assertNoErrors(source); |
| 841 verify([source]); | 926 verify([source]); |
| 842 } | 927 } |
| 843 | 928 |
| 929 void test_topLevelVarAssignable_undefined_null() { |
| 930 // Null always passes runtime type checks, even when the type is |
| 931 // unresolved. |
| 932 Source source = addSource(EngineTestCase.createSource([ |
| 933 "const Unresolved x = null;"])); |
| 934 resolve(source); |
| 935 assertErrors(source, [ |
| 936 StaticWarningCode.UNDEFINED_CLASS]); |
| 937 verify([source]); |
| 938 } |
| 939 |
| 844 void test_topLevelVarNotAssignable() { | 940 void test_topLevelVarNotAssignable() { |
| 845 Source source = addSource(EngineTestCase.createSource([ | 941 Source source = addSource(EngineTestCase.createSource([ |
| 846 "const int x = 'foo';"])); | 942 "const int x = 'foo';"])); |
| 847 resolve(source); | 943 resolve(source); |
| 848 assertErrors(source, [ | 944 assertErrors(source, [ |
| 849 CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, | 945 CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, |
| 850 StaticTypeWarningCode.INVALID_ASSIGNMENT]); | 946 StaticTypeWarningCode.INVALID_ASSIGNMENT]); |
| 851 verify([source]); | 947 verify([source]); |
| 852 } | 948 } |
| 949 |
| 950 void test_topLevelVarNotAssignable_undefined() { |
| 951 Source source = addSource(EngineTestCase.createSource([ |
| 952 "const Unresolved x = 'foo';"])); |
| 953 resolve(source); |
| 954 assertErrors(source, [ |
| 955 CheckedModeCompileTimeErrorCode.VARIABLE_TYPE_MISMATCH, |
| 956 StaticWarningCode.UNDEFINED_CLASS]); |
| 957 verify([source]); |
| 958 } |
| 853 } | 959 } |
| 854 | 960 |
| 855 class DeclarationMatcherTest extends ResolverTestCase { | 961 class DeclarationMatcherTest extends ResolverTestCase { |
| 856 void test_compilationUnitMatches_false_topLevelVariable() { | 962 void test_compilationUnitMatches_false_topLevelVariable() { |
| 857 _assertCompilationUnitMatches(false, EngineTestCase.createSource([ | 963 _assertCompilationUnitMatches(false, EngineTestCase.createSource([ |
| 858 "class C {", | 964 "class C {", |
| 859 " int m(int p) {", | 965 " int m(int p) {", |
| 860 " return p + p;", | 966 " return p + p;", |
| 861 " }", | 967 " }", |
| 862 "}"]), EngineTestCase.createSource([ | 968 "}"]), EngineTestCase.createSource([ |
| (...skipping 7575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8438 @override | 8544 @override |
| 8439 Object visitLabel(Label node) => null; | 8545 Object visitLabel(Label node) => null; |
| 8440 | 8546 |
| 8441 @override | 8547 @override |
| 8442 Object visitLibraryIdentifier(LibraryIdentifier node) => null; | 8548 Object visitLibraryIdentifier(LibraryIdentifier node) => null; |
| 8443 | 8549 |
| 8444 @override | 8550 @override |
| 8445 Object visitPrefixedIdentifier(PrefixedIdentifier node) { | 8551 Object visitPrefixedIdentifier(PrefixedIdentifier node) { |
| 8446 // In cases where we have a prefixed identifier where the prefix is dynamic,
we don't want to | 8552 // In cases where we have a prefixed identifier where the prefix is dynamic,
we don't want to |
| 8447 // assert that the node will have a type. | 8553 // assert that the node will have a type. |
| 8448 if (node.staticType == null && identical(node.prefix.staticType, DynamicType
Impl.instance)) { | 8554 if (node.staticType == null && node.prefix.staticType.isDynamic) { |
| 8449 return null; | 8555 return null; |
| 8450 } | 8556 } |
| 8451 return super.visitPrefixedIdentifier(node); | 8557 return super.visitPrefixedIdentifier(node); |
| 8452 } | 8558 } |
| 8453 | 8559 |
| 8454 @override | 8560 @override |
| 8455 Object visitSimpleIdentifier(SimpleIdentifier node) { | 8561 Object visitSimpleIdentifier(SimpleIdentifier node) { |
| 8456 // In cases where identifiers are being used for something other than an exp
ressions, | 8562 // In cases where identifiers are being used for something other than an exp
ressions, |
| 8457 // then they can be ignored. | 8563 // then they can be ignored. |
| 8458 AstNode parent = node.parent; | 8564 AstNode parent = node.parent; |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8831 /** | 8937 /** |
| 8832 * The type representing the built-in type 'Symbol'. | 8938 * The type representing the built-in type 'Symbol'. |
| 8833 */ | 8939 */ |
| 8834 InterfaceType _symbolType; | 8940 InterfaceType _symbolType; |
| 8835 | 8941 |
| 8836 /** | 8942 /** |
| 8837 * The type representing the built-in type 'Type'. | 8943 * The type representing the built-in type 'Type'. |
| 8838 */ | 8944 */ |
| 8839 InterfaceType _typeType; | 8945 InterfaceType _typeType; |
| 8840 | 8946 |
| 8947 /** |
| 8948 * The type representing typenames that can't be resolved. |
| 8949 */ |
| 8950 DartType _undefinedType; |
| 8951 |
| 8841 @override | 8952 @override |
| 8842 InterfaceType get boolType { | 8953 InterfaceType get boolType { |
| 8843 if (_boolType == null) { | 8954 if (_boolType == null) { |
| 8844 ClassElementImpl boolElement = ElementFactory.classElement2("bool", []); | 8955 ClassElementImpl boolElement = ElementFactory.classElement2("bool", []); |
| 8845 _boolType = boolElement.type; | 8956 _boolType = boolElement.type; |
| 8846 ConstructorElementImpl fromEnvironment = ElementFactory.constructorElement
(boolElement, "fromEnvironment", true, []); | 8957 ConstructorElementImpl fromEnvironment = ElementFactory.constructorElement
(boolElement, "fromEnvironment", true, []); |
| 8847 fromEnvironment.parameters = <ParameterElement> [ | 8958 fromEnvironment.parameters = <ParameterElement> [ |
| 8848 ElementFactory.requiredParameter2("name", stringType), | 8959 ElementFactory.requiredParameter2("name", stringType), |
| 8849 ElementFactory.namedParameter2("defaultValue", _boolType)]; | 8960 ElementFactory.namedParameter2("defaultValue", _boolType)]; |
| 8850 fromEnvironment.factory = true; | 8961 fromEnvironment.factory = true; |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9039 } | 9150 } |
| 9040 | 9151 |
| 9041 @override | 9152 @override |
| 9042 InterfaceType get typeType { | 9153 InterfaceType get typeType { |
| 9043 if (_typeType == null) { | 9154 if (_typeType == null) { |
| 9044 _typeType = ElementFactory.classElement2("Type", []).type; | 9155 _typeType = ElementFactory.classElement2("Type", []).type; |
| 9045 } | 9156 } |
| 9046 return _typeType; | 9157 return _typeType; |
| 9047 } | 9158 } |
| 9048 | 9159 |
| 9160 @override |
| 9161 DartType get undefinedType { |
| 9162 if (_undefinedType == null) { |
| 9163 _undefinedType = UndefinedTypeImpl.instance; |
| 9164 } |
| 9165 return _undefinedType; |
| 9166 } |
| 9167 |
| 9049 /** | 9168 /** |
| 9050 * Initialize the numeric types. They are created as a group so that we can (a
) create the right | 9169 * Initialize the numeric types. They are created as a group so that we can (a
) create the right |
| 9051 * hierarchy and (b) add members to them. | 9170 * hierarchy and (b) add members to them. |
| 9052 */ | 9171 */ |
| 9053 void _initializeNumericTypes() { | 9172 void _initializeNumericTypes() { |
| 9054 // | 9173 // |
| 9055 // Create the type hierarchy. | 9174 // Create the type hierarchy. |
| 9056 // | 9175 // |
| 9057 ClassElementImpl numElement = ElementFactory.classElement2("num", []); | 9176 ClassElementImpl numElement = ElementFactory.classElement2("num", []); |
| 9058 _numType = numElement.type; | 9177 _numType = numElement.type; |
| (...skipping 1860 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10919 runReflectiveTests(TypeResolverVisitorTest); | 11038 runReflectiveTests(TypeResolverVisitorTest); |
| 10920 runReflectiveTests(CheckedModeCompileTimeErrorCodeTest); | 11039 runReflectiveTests(CheckedModeCompileTimeErrorCodeTest); |
| 10921 runReflectiveTests(ErrorResolverTest); | 11040 runReflectiveTests(ErrorResolverTest); |
| 10922 runReflectiveTests(HintCodeTest); | 11041 runReflectiveTests(HintCodeTest); |
| 10923 runReflectiveTests(MemberMapTest); | 11042 runReflectiveTests(MemberMapTest); |
| 10924 runReflectiveTests(NonHintCodeTest); | 11043 runReflectiveTests(NonHintCodeTest); |
| 10925 runReflectiveTests(SimpleResolverTest); | 11044 runReflectiveTests(SimpleResolverTest); |
| 10926 runReflectiveTests(StrictModeTest); | 11045 runReflectiveTests(StrictModeTest); |
| 10927 runReflectiveTests(TypePropagationTest); | 11046 runReflectiveTests(TypePropagationTest); |
| 10928 } | 11047 } |
| OLD | NEW |