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 package com.google.dart.compiler.parser; | 5 package com.google.dart.compiler.parser; |
6 | 6 |
7 import com.google.common.annotations.VisibleForTesting; | 7 import com.google.common.annotations.VisibleForTesting; |
8 import com.google.common.io.CharStreams; | 8 import com.google.common.io.CharStreams; |
9 import com.google.dart.compiler.DartCompilationError; | 9 import com.google.dart.compiler.DartCompilationError; |
10 import com.google.dart.compiler.DartCompilerErrorCode; | 10 import com.google.dart.compiler.DartCompilerErrorCode; |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 | 176 |
177 public DartParser(ParserContext ctx, boolean isDietParse, Set<String> prefixes
) { | 177 public DartParser(ParserContext ctx, boolean isDietParse, Set<String> prefixes
) { |
178 super(ctx); | 178 super(ctx); |
179 this.isDietParse = isDietParse; | 179 this.isDietParse = isDietParse; |
180 this.prefixes = prefixes; | 180 this.prefixes = prefixes; |
181 } | 181 } |
182 | 182 |
183 private DartParser(Source source, DartCompilerListener listener) throws IOExce
ption { | 183 private DartParser(Source source, DartCompilerListener listener) throws IOExce
ption { |
184 this(source, source.getSourceReader(), listener); | 184 this(source, source.getSourceReader(), listener); |
185 } | 185 } |
186 | 186 |
187 private DartParser(Source source, | 187 private DartParser(Source source, |
188 Reader sourceReader, | 188 Reader sourceReader, |
189 DartCompilerListener listener) throws IOException { | 189 DartCompilerListener listener) throws IOException { |
190 this(new DartScannerParserContext(source, read(sourceReader), listener)); | 190 this(new DartScannerParserContext(source, read(sourceReader), listener)); |
191 } | 191 } |
192 | 192 |
193 public static DartParser getSourceParser(Source source, DartCompilerListener l
istener) | 193 public static DartParser getSourceParser(Source source, DartCompilerListener l
istener) |
194 throws IOException { | 194 throws IOException { |
195 return new DartParser(source, listener); | 195 return new DartParser(source, listener); |
196 } | 196 } |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 if (node != null) { | 267 if (node != null) { |
268 unit.addTopLevelNode(node); | 268 unit.addTopLevelNode(node); |
269 } | 269 } |
270 } | 270 } |
271 expect(Token.EOS); | 271 expect(Token.EOS); |
272 return done(unit); | 272 return done(unit); |
273 } | 273 } |
274 | 274 |
275 /** | 275 /** |
276 * A version of the parser which only parses the directives of a library. | 276 * A version of the parser which only parses the directives of a library. |
277 * | 277 * |
278 * TODO(jbrosenberg): consider parsing the whole file here, in order to avoid | 278 * TODO(jbrosenberg): consider parsing the whole file here, in order to avoid |
279 * duplicate work. Probably requires removing use of LibraryUnit's, etc. | 279 * duplicate work. Probably requires removing use of LibraryUnit's, etc. |
280 * Also, this minimal parse does have benefit in the incremental compilation | 280 * Also, this minimal parse does have benefit in the incremental compilation |
281 * case. | 281 * case. |
282 */ | 282 */ |
283 public LibraryUnit preProcessLibraryDirectives(LibrarySource source) { | 283 public LibraryUnit preProcessLibraryDirectives(LibrarySource source) { |
284 beginCompilationUnit(); | 284 beginCompilationUnit(); |
285 LibraryUnit libUnit = new LibraryUnit(source); | 285 LibraryUnit libUnit = new LibraryUnit(source); |
286 if (peek(0) == Token.LIBRARY) { | 286 if (peek(0) == Token.LIBRARY) { |
287 beginLibraryDirective(); | 287 beginLibraryDirective(); |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
629 DartIdentifier name = parseIdentifier(); | 629 DartIdentifier name = parseIdentifier(); |
630 List<DartTypeParameter> typeParameters = parseTypeParametersOpt(); | 630 List<DartTypeParameter> typeParameters = parseTypeParametersOpt(); |
631 List<DartParameter> params = parseFormalParameterList(); | 631 List<DartParameter> params = parseFormalParameterList(); |
632 expect(Token.SEMICOLON); | 632 expect(Token.SEMICOLON); |
633 | 633 |
634 return done(new DartFunctionTypeAlias(name, returnType, params, typeParamete
rs)); | 634 return done(new DartFunctionTypeAlias(name, returnType, params, typeParamete
rs)); |
635 } | 635 } |
636 | 636 |
637 /** | 637 /** |
638 * Parse a field or method, which may be inside a class or at the top level. | 638 * Parse a field or method, which may be inside a class or at the top level. |
639 * | 639 * |
640 * <pre> | 640 * <pre> |
641 * // This rule is organized in a way that may not be most readable, but | 641 * // This rule is organized in a way that may not be most readable, but |
642 * // gives the best error messages. | 642 * // gives the best error messages. |
643 * classMemberDefinition | 643 * classMemberDefinition |
644 * : declaration ';' | 644 * : declaration ';' |
645 * | methodDeclaration bodyOrNative | 645 * | methodDeclaration bodyOrNative |
646 * ; | 646 * ; |
647 * | 647 * |
648 * // Note: this syntax is not official, but used in dart_interpreter. It | 648 * // Note: this syntax is not official, but used in dart_interpreter. It |
649 * // is unlikely that Dart will support numbered natives. | 649 * // is unlikely that Dart will support numbered natives. |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
719 * ; | 719 * ; |
720 * | 720 * |
721 * operator | 721 * operator |
722 * : unaryOperator | 722 * : unaryOperator |
723 * | binaryOperator | 723 * | binaryOperator |
724 * | '[' ']' { "[]".equals($text) }? | 724 * | '[' ']' { "[]".equals($text) }? |
725 * | '[' ']' '=' { "[]=".equals($text) }? | 725 * | '[' ']' '=' { "[]=".equals($text) }? |
726 * | NEGATE | 726 * | NEGATE |
727 * ; | 727 * ; |
728 * </pre> | 728 * </pre> |
729 * | 729 * |
730 * @param allowStatic true if the static modifier is allowed | 730 * @param allowStatic true if the static modifier is allowed |
731 * @return a {@link DartNode} representing the grammar fragment above | 731 * @return a {@link DartNode} representing the grammar fragment above |
732 */ | 732 */ |
733 private DartNode parseFieldOrMethod(boolean allowStatic) { | 733 private DartNode parseFieldOrMethod(boolean allowStatic) { |
734 beginClassMember(); | 734 beginClassMember(); |
735 Modifiers modifiers = Modifiers.NONE; | 735 Modifiers modifiers = Modifiers.NONE; |
736 if (optionalPseudoKeyword(STATIC_KEYWORD)) { | 736 if (optionalPseudoKeyword(STATIC_KEYWORD)) { |
737 if (!allowStatic) { | 737 if (!allowStatic) { |
738 reportError(position(), DartCompilerErrorCode.TOP_LEVEL_IS_STATIC); | 738 reportError(position(), DartCompilerErrorCode.TOP_LEVEL_IS_STATIC); |
739 } else { | 739 } else { |
(...skipping 2014 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2754 case RPAREN: | 2754 case RPAREN: |
2755 expect(Token.RPAREN); | 2755 expect(Token.RPAREN); |
2756 --parenCount; | 2756 --parenCount; |
2757 break; | 2757 break; |
2758 | 2758 |
2759 case LPAREN: | 2759 case LPAREN: |
2760 expect(Token.LPAREN); | 2760 expect(Token.LPAREN); |
2761 ++parenCount; | 2761 ++parenCount; |
2762 break; | 2762 break; |
2763 | 2763 |
| 2764 case EOS: |
| 2765 reportErrorWithoutAdvancing(DartCompilerErrorCode.UNEXPECTED_TOKEN); |
| 2766 return; |
| 2767 |
2764 case LBRACE: | 2768 case LBRACE: |
2765 case SEMICOLON: | 2769 case SEMICOLON: |
2766 return; | 2770 return; |
2767 | 2771 |
2768 default: | 2772 default: |
2769 next(); | 2773 next(); |
2770 break; | 2774 break; |
2771 } | 2775 } |
2772 } | 2776 } |
2773 } | 2777 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2812 } | 2816 } |
2813 } | 2817 } |
2814 } | 2818 } |
2815 | 2819 |
2816 /** | 2820 /** |
2817 * Collect plausible statement tokens and return a synthetic error statement | 2821 * Collect plausible statement tokens and return a synthetic error statement |
2818 * containing them. | 2822 * containing them. |
2819 * <p> | 2823 * <p> |
2820 * Note that this is a crude heuristic that needs to be improved for better | 2824 * Note that this is a crude heuristic that needs to be improved for better |
2821 * error recovery. | 2825 * error recovery. |
2822 * | 2826 * |
2823 * @return a {@link DartSyntheticErrorStatement} | 2827 * @return a {@link DartSyntheticErrorStatement} |
2824 */ | 2828 */ |
2825 private DartStatement parseErrorStatement() { | 2829 private DartStatement parseErrorStatement() { |
2826 StringBuilder buf = new StringBuilder(); | 2830 StringBuilder buf = new StringBuilder(); |
2827 boolean done = false; | 2831 boolean done = false; |
2828 int braceCount = 1; | 2832 int braceCount = 1; |
2829 while (!done) { | 2833 while (!done) { |
2830 buf.append(getPeekTokenValue(0)); | 2834 buf.append(getPeekTokenValue(0)); |
2831 next(); | 2835 next(); |
2832 switch (peek(0)) { | 2836 switch (peek(0)) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2867 | 2871 |
2868 case LBRACE: | 2872 case LBRACE: |
2869 ++braceCount; | 2873 ++braceCount; |
2870 //$FALL-THROUGH$ | 2874 //$FALL-THROUGH$ |
2871 default: | 2875 default: |
2872 // give error message | 2876 // give error message |
2873 expect(Token.SEMICOLON); | 2877 expect(Token.SEMICOLON); |
2874 break; | 2878 break; |
2875 } | 2879 } |
2876 | 2880 |
2877 while (true) { | 2881 while (true) { |
2878 switch (peek(0)) { | 2882 switch (peek(0)) { |
2879 case EOS: | 2883 case EOS: |
2880 return; | 2884 return; |
2881 | 2885 |
2882 case SEMICOLON: | 2886 case SEMICOLON: |
2883 if (braceCount < 2) { | 2887 if (braceCount < 2) { |
2884 // if we have seen open braces while skipping, keep looking | 2888 // if we have seen open braces while skipping, keep looking |
2885 return; | 2889 return; |
2886 } | 2890 } |
2887 next(); | 2891 next(); |
2888 break; | 2892 break; |
2889 | 2893 |
2890 case RBRACE: | 2894 case RBRACE: |
2891 if (--braceCount == 0) { | 2895 if (--braceCount == 0) { |
2892 return; | 2896 return; |
2893 } | 2897 } |
2894 break; | 2898 break; |
2895 | 2899 |
2896 case LBRACE: | 2900 case LBRACE: |
2897 ++braceCount; | 2901 ++braceCount; |
2898 //$FALL-THROUGH$ | 2902 //$FALL-THROUGH$ |
2899 default: | 2903 default: |
2900 next(); | 2904 next(); |
2901 break; | 2905 break; |
2902 } | 2906 } |
2903 } | 2907 } |
2904 } | 2908 } |
2905 | 2909 |
2906 /** | 2910 /** |
2907 * Report an error without advancing past the next token. | 2911 * Report an error without advancing past the next token. |
2908 * | 2912 * |
2909 * @param errCode the error code to report, which may take a string parameter | 2913 * @param errCode the error code to report, which may take a string parameter |
2910 * containing the actual token found | 2914 * containing the actual token found |
2911 */ | 2915 */ |
2912 private void reportErrorWithoutAdvancing(DartCompilerErrorCode errCode) { | 2916 private void reportErrorWithoutAdvancing(DartCompilerErrorCode errCode) { |
2913 startLookahead(); | 2917 startLookahead(); |
2914 Token actual = peek(0); | 2918 Token actual = peek(0); |
2915 next(); | 2919 next(); |
2916 reportError(position(), errCode, actual); | 2920 reportError(position(), errCode, actual); |
2917 rollback(); | 2921 rollback(); |
2918 } | 2922 } |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3171 | 3175 |
3172 if (peek(0) == Token.CASE) { | 3176 if (peek(0) == Token.CASE) { |
3173 members.add(parseCaseMember(label)); | 3177 members.add(parseCaseMember(label)); |
3174 } else if (optional(Token.RBRACE)) { | 3178 } else if (optional(Token.RBRACE)) { |
3175 if (label != null) { | 3179 if (label != null) { |
3176 reportError(position(), DartCompilerErrorCode.EXPECTED_CASE_OR_DEFAULT
); | 3180 reportError(position(), DartCompilerErrorCode.EXPECTED_CASE_OR_DEFAULT
); |
3177 } | 3181 } |
3178 done = true; | 3182 done = true; |
3179 done(null); | 3183 done(null); |
3180 } else { | 3184 } else { |
3181 if (peek(0) != Token.EOS) { | 3185 if (peek(0) != Token.EOS) { |
3182 members.add(parseDefaultMember(label)); | 3186 members.add(parseDefaultMember(label)); |
3183 } | 3187 } |
3184 expectCloseBrace(); | 3188 expectCloseBrace(); |
3185 done = true; // Ensure termination. | 3189 done = true; // Ensure termination. |
3186 } | 3190 } |
3187 } | 3191 } |
3188 return done(new DartSwitchStatement(expr, members)); | 3192 return done(new DartSwitchStatement(expr, members)); |
3189 } | 3193 } |
3190 | 3194 |
3191 /** | 3195 /** |
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3462 } else { | 3466 } else { |
3463 ctx.error(dartError); | 3467 ctx.error(dartError); |
3464 errorHistory.add(dartError.hashCode()); | 3468 errorHistory.add(dartError.hashCode()); |
3465 } | 3469 } |
3466 } | 3470 } |
3467 | 3471 |
3468 private void reportError(DartNode node, ErrorCode errorCode, Object... argumen
ts) { | 3472 private void reportError(DartNode node, ErrorCode errorCode, Object... argumen
ts) { |
3469 reportError(new DartCompilationError(node, errorCode, arguments)); | 3473 reportError(new DartCompilationError(node, errorCode, arguments)); |
3470 } | 3474 } |
3471 } | 3475 } |
OLD | NEW |