| 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 |