OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 fasta.body_builder; | 5 library fasta.body_builder; |
6 | 6 |
7 import '../fasta_codes.dart' | 7 import '../fasta_codes.dart' |
8 show FastaMessage, codeExpectedButGot, codeExpectedFunctionBody; | 8 show FastaMessage, codeExpectedButGot, codeExpectedFunctionBody; |
9 | 9 |
10 import '../parser/parser.dart' show FormalParameterType, MemberKind, optional; | 10 import '../parser/parser.dart' show FormalParameterType, MemberKind, optional; |
(...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
778 // remove the next line: | 778 // remove the next line: |
779 result = | 779 result = |
780 new KernelSuperMethodInvocation(node.name, node.arguments, null); | 780 new KernelSuperMethodInvocation(node.name, node.arguments, null); |
781 return result; | 781 return result; |
782 } else { | 782 } else { |
783 isNoSuchMethod = true; | 783 isNoSuchMethod = true; |
784 } | 784 } |
785 } | 785 } |
786 } | 786 } |
787 if (isNoSuchMethod) { | 787 if (isNoSuchMethod) { |
788 return throwNoSuchMethodError( | 788 return invokeSuperNoSuchMethod( |
789 node.name.name, node.arguments, node.fileOffset, | 789 node.name.name, node.arguments, node.fileOffset); |
790 isSuper: true); | |
791 } | 790 } |
792 Expression receiver = new KernelDirectPropertyGet( | 791 Expression receiver = new KernelDirectPropertyGet( |
793 new ThisExpression()..fileOffset = node.fileOffset, target); | 792 new ThisExpression()..fileOffset = node.fileOffset, target); |
794 // TODO(ahe): Use [DirectPropertyGet] when possible, that is, remove the | 793 // TODO(ahe): Use [DirectPropertyGet] when possible, that is, remove the |
795 // next line: | 794 // next line: |
796 receiver = new KernelSuperPropertyGet(node.name, target); | 795 receiver = new KernelSuperPropertyGet(node.name, target); |
797 return buildMethodInvocation( | 796 return buildMethodInvocation( |
798 receiver, callName, node.arguments, node.fileOffset); | 797 receiver, callName, node.arguments, node.fileOffset); |
799 } | 798 } |
800 | 799 |
801 bool areArgumentsCompatible(FunctionNode function, Arguments arguments) { | 800 bool areArgumentsCompatible(FunctionNode function, Arguments arguments) { |
802 // TODO(ahe): Implement this. | 801 // TODO(ahe): Implement this. |
803 return true; | 802 return true; |
804 } | 803 } |
805 | 804 |
806 @override | 805 @override |
807 Expression throwNoSuchMethodError( | 806 Expression throwNoSuchMethodError( |
808 String name, Arguments arguments, int charOffset, | 807 Expression receiver, String name, Arguments arguments, int charOffset, |
809 {bool isSuper: false, isGetter: false, isSetter: false}) { | 808 {bool isSuper: false, |
| 809 bool isGetter: false, |
| 810 bool isSetter: false, |
| 811 bool isStatic: false}) { |
810 String errorName = isSuper ? "super.$name" : name; | 812 String errorName = isSuper ? "super.$name" : name; |
811 String message; | 813 String message; |
812 if (isGetter) { | 814 if (isGetter) { |
813 message = "Getter not found: '$errorName'."; | 815 message = "Getter not found: '$errorName'."; |
814 } else if (isSetter) { | 816 } else if (isSetter) { |
815 message = "Setter not found: '$errorName'."; | 817 message = "Setter not found: '$errorName'."; |
816 } else { | 818 } else { |
817 message = "Method not found: '$errorName'."; | 819 message = "Method not found: '$errorName'."; |
818 } | 820 } |
819 if (constantExpressionRequired) { | 821 if (constantExpressionRequired) { |
820 return buildCompileTimeError(message, charOffset); | 822 return buildCompileTimeError(message, charOffset); |
821 } | 823 } |
822 warning(message, charOffset); | 824 warning(message, charOffset); |
823 Constructor constructor = | 825 return new Throw(library.loader.instantiateNoSuchMethodError( |
824 coreTypes.noSuchMethodErrorClass.constructors.first; | 826 receiver, name, arguments, charOffset, |
825 return new Throw(new ConstructorInvocation( | 827 isMethod: !isGetter && !isSetter, |
826 constructor, | 828 isGetter: isGetter, |
827 new KernelArguments(<Expression>[ | 829 isSetter: isSetter, |
828 new KernelNullLiteral(), | 830 isStatic: isStatic, |
829 new SymbolLiteral(name), | 831 isTopLevel: !isStatic && !isSuper)); |
830 new ListLiteral(arguments.positional), | |
831 new MapLiteral(arguments.named.map((arg) { | |
832 return new MapEntry(new SymbolLiteral(arg.name), arg.value); | |
833 }).toList()), | |
834 new KernelNullLiteral() | |
835 ]))); | |
836 } | 832 } |
837 | 833 |
838 @override | 834 @override |
| 835 Expression invokeSuperNoSuchMethod( |
| 836 String name, Arguments arguments, int charOffset, |
| 837 {bool isGetter: false, bool isSetter: false}) { |
| 838 String errorName = "super.$name"; |
| 839 String message; |
| 840 if (isGetter) { |
| 841 message = "Getter not found: '$errorName'."; |
| 842 name = "get:$name"; |
| 843 } else if (isSetter) { |
| 844 message = "Setter not found: '$errorName'."; |
| 845 name = "set:$name"; |
| 846 } else { |
| 847 message = "Method not found: '$errorName'."; |
| 848 } |
| 849 warning(message, charOffset); |
| 850 VariableDeclaration value; |
| 851 if (isSetter) { |
| 852 value = new VariableDeclaration.forValue(arguments.positional.single, |
| 853 isFinal: true) |
| 854 ..fileOffset = charOffset; |
| 855 arguments = new Arguments(<Expression>[ |
| 856 new VariableGet(value)..fileOffset = arguments.fileOffset |
| 857 ]); |
| 858 } |
| 859 Expression result = new SuperMethodInvocation( |
| 860 noSuchMethodName, |
| 861 new Arguments(<Expression>[ |
| 862 library.loader.instantiateInvocation( |
| 863 new ThisExpression()..fileOffset = charOffset, |
| 864 name, |
| 865 arguments, |
| 866 charOffset, |
| 867 true) |
| 868 ]) |
| 869 ..fileOffset = arguments.fileOffset); |
| 870 if (isSetter) { |
| 871 result = new Let( |
| 872 value, |
| 873 new Let( |
| 874 new VariableDeclaration.forValue(result, isFinal: true) |
| 875 ..fileOffset = charOffset, |
| 876 new VariableGet(value)..fileOffset = value.fileOffset)) |
| 877 ..fileOffset = charOffset; |
| 878 } |
| 879 return result; |
| 880 } |
| 881 |
| 882 @override |
839 Member lookupSuperMember(Name name, {bool isSetter: false}) { | 883 Member lookupSuperMember(Name name, {bool isSetter: false}) { |
840 Class superclass = classBuilder.cls.superclass; | 884 Class superclass = classBuilder.cls.superclass; |
841 return superclass == null | 885 return superclass == null |
842 ? null | 886 ? null |
843 : hierarchy.getDispatchTarget(superclass, name, setter: isSetter); | 887 : hierarchy.getDispatchTarget(superclass, name, setter: isSetter); |
844 } | 888 } |
845 | 889 |
846 @override | 890 @override |
847 Constructor lookupConstructor(Name name, {bool isSuper}) { | 891 Constructor lookupConstructor(Name name, {bool isSuper}) { |
848 Class cls = classBuilder.cls; | 892 Class cls = classBuilder.cls; |
(...skipping 1066 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1915 | 1959 |
1916 @override | 1960 @override |
1917 Expression buildStaticInvocation(Member target, Arguments arguments, | 1961 Expression buildStaticInvocation(Member target, Arguments arguments, |
1918 {bool isConst: false, int charOffset: -1, Member initialTarget}) { | 1962 {bool isConst: false, int charOffset: -1, Member initialTarget}) { |
1919 List<TypeParameter> typeParameters = target.function.typeParameters; | 1963 List<TypeParameter> typeParameters = target.function.typeParameters; |
1920 if (target is Constructor) { | 1964 if (target is Constructor) { |
1921 assert(!target.enclosingClass.isAbstract); | 1965 assert(!target.enclosingClass.isAbstract); |
1922 typeParameters = target.enclosingClass.typeParameters; | 1966 typeParameters = target.enclosingClass.typeParameters; |
1923 } | 1967 } |
1924 if (!checkArguments(target.function, arguments, typeParameters)) { | 1968 if (!checkArguments(target.function, arguments, typeParameters)) { |
1925 return throwNoSuchMethodError(target.name.name, arguments, charOffset); | 1969 return throwNoSuchMethodError(new NullLiteral()..fileOffset = charOffset, |
| 1970 target.name.name, arguments, charOffset); |
1926 } | 1971 } |
1927 if (target is Constructor) { | 1972 if (target is Constructor) { |
1928 return new KernelConstructorInvocation(target, initialTarget, arguments, | 1973 return new KernelConstructorInvocation(target, initialTarget, arguments, |
1929 isConst: isConst) | 1974 isConst: isConst) |
1930 ..fileOffset = charOffset; | 1975 ..fileOffset = charOffset; |
1931 } else if (target is Procedure && target.kind == ProcedureKind.Factory) { | 1976 } else if (target is Procedure && target.kind == ProcedureKind.Factory) { |
1932 return new KernelFactoryConstructorInvocation( | 1977 return new KernelFactoryConstructorInvocation( |
1933 target, initialTarget, arguments, | 1978 target, initialTarget, arguments, |
1934 isConst: isConst) | 1979 isConst: isConst) |
1935 ..fileOffset = charOffset; | 1980 ..fileOffset = charOffset; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2064 charOffset: nameToken.charOffset, | 2109 charOffset: nameToken.charOffset, |
2065 initialTarget: initialTarget)); | 2110 initialTarget: initialTarget)); |
2066 return; | 2111 return; |
2067 } else { | 2112 } else { |
2068 errorName = debugName(type.name, name); | 2113 errorName = debugName(type.name, name); |
2069 } | 2114 } |
2070 } else { | 2115 } else { |
2071 errorName = debugName(getNodeName(type), name); | 2116 errorName = debugName(getNodeName(type), name); |
2072 } | 2117 } |
2073 errorName ??= name; | 2118 errorName ??= name; |
2074 push(throwNoSuchMethodError(errorName, arguments, nameToken.charOffset)); | 2119 push(throwNoSuchMethodError( |
| 2120 new NullLiteral()..fileOffset = token.charOffset, |
| 2121 errorName, |
| 2122 arguments, |
| 2123 nameToken.charOffset)); |
2075 }(); | 2124 }(); |
2076 constantExpressionRequired = savedConstantExpressionRequired; | 2125 constantExpressionRequired = savedConstantExpressionRequired; |
2077 } | 2126 } |
2078 | 2127 |
2079 @override | 2128 @override |
2080 void endConstExpression(Token token) { | 2129 void endConstExpression(Token token) { |
2081 debugEvent("endConstExpression"); | 2130 debugEvent("endConstExpression"); |
2082 endNewExpression(token); | 2131 endNewExpression(token); |
2083 } | 2132 } |
2084 | 2133 |
(...skipping 1240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3325 if (starToken == null) { | 3374 if (starToken == null) { |
3326 return AsyncMarker.Async; | 3375 return AsyncMarker.Async; |
3327 } else { | 3376 } else { |
3328 assert(identical(starToken.stringValue, "*")); | 3377 assert(identical(starToken.stringValue, "*")); |
3329 return AsyncMarker.AsyncStar; | 3378 return AsyncMarker.AsyncStar; |
3330 } | 3379 } |
3331 } else { | 3380 } else { |
3332 return internalError("Unknown async modifier: $asyncToken"); | 3381 return internalError("Unknown async modifier: $asyncToken"); |
3333 } | 3382 } |
3334 } | 3383 } |
OLD | NEW |