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 // This code was auto-generated, is not intended to be edited, and is subject to | 5 // This code was auto-generated, is not intended to be edited, and is subject to |
6 // significant change. Please see the README file for more information. | 6 // significant change. Please see the README file for more information. |
7 | 7 |
8 library engine.parser; | 8 library engine.parser; |
9 | 9 |
10 import 'java_core.dart'; | 10 import 'java_core.dart'; |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 return _parser.parseSimpleIdentifier(); | 301 return _parser.parseSimpleIdentifier(); |
302 } else if (identical(_oldNode, node.typeParameters)) { | 302 } else if (identical(_oldNode, node.typeParameters)) { |
303 return _parser.parseTypeParameterList(); | 303 return _parser.parseTypeParameterList(); |
304 } else if (identical(_oldNode, node.extendsClause)) { | 304 } else if (identical(_oldNode, node.extendsClause)) { |
305 return _parser.parseExtendsClause(); | 305 return _parser.parseExtendsClause(); |
306 } else if (identical(_oldNode, node.withClause)) { | 306 } else if (identical(_oldNode, node.withClause)) { |
307 return _parser.parseWithClause(); | 307 return _parser.parseWithClause(); |
308 } else if (identical(_oldNode, node.implementsClause)) { | 308 } else if (identical(_oldNode, node.implementsClause)) { |
309 return _parser.parseImplementsClause(); | 309 return _parser.parseImplementsClause(); |
310 } else if (node.members.contains(_oldNode)) { | 310 } else if (node.members.contains(_oldNode)) { |
311 return _parser.parseClassMember(node.name.name); | 311 ClassMember member = _parser.parseClassMember(node.name.name); |
| 312 if (member == null) { |
| 313 throw new InsufficientContextException(); |
| 314 } |
| 315 return member; |
312 } | 316 } |
313 return notAChild(node); | 317 return notAChild(node); |
314 } | 318 } |
315 | 319 |
316 ASTNode visitClassTypeAlias(ClassTypeAlias node) { | 320 ASTNode visitClassTypeAlias(ClassTypeAlias node) { |
317 if (identical(_oldNode, node.documentationComment)) { | 321 if (identical(_oldNode, node.documentationComment)) { |
318 throw new InsufficientContextException(); | 322 throw new InsufficientContextException(); |
319 } else if (node.metadata.contains(_oldNode)) { | 323 } else if (node.metadata.contains(_oldNode)) { |
320 return _parser.parseAnnotation(); | 324 return _parser.parseAnnotation(); |
321 } else if (identical(_oldNode, node.name)) { | 325 } else if (identical(_oldNode, node.name)) { |
(...skipping 1363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1685 return parseOperator(commentAndMetadata, modifiers.externalKeyword, null); | 1689 return parseOperator(commentAndMetadata, modifiers.externalKeyword, null); |
1686 } else if (!matchesIdentifier()) { | 1690 } else if (!matchesIdentifier()) { |
1687 if (isOperator(_currentToken)) { | 1691 if (isOperator(_currentToken)) { |
1688 // | 1692 // |
1689 // We appear to have found an operator declaration without the 'operator
' keyword. | 1693 // We appear to have found an operator declaration without the 'operator
' keyword. |
1690 // | 1694 // |
1691 validateModifiersForOperator(modifiers); | 1695 validateModifiersForOperator(modifiers); |
1692 return parseOperator(commentAndMetadata, modifiers.externalKeyword, null
); | 1696 return parseOperator(commentAndMetadata, modifiers.externalKeyword, null
); |
1693 } | 1697 } |
1694 reportError14(ParserErrorCode.EXPECTED_CLASS_MEMBER, _currentToken, []); | 1698 reportError14(ParserErrorCode.EXPECTED_CLASS_MEMBER, _currentToken, []); |
| 1699 if (commentAndMetadata.comment != null || !commentAndMetadata.metadata.isE
mpty) { |
| 1700 // |
| 1701 // We appear to have found an incomplete declaration at the end of the c
lass. At this point |
| 1702 // it consists of a metadata, which we don't want to loose, so we'll tre
at it as a method |
| 1703 // declaration with a missing name, parameters and empty body. |
| 1704 // |
| 1705 return new MethodDeclaration(commentAndMetadata.comment, commentAndMetad
ata.metadata, null, null, null, null, null, createSyntheticIdentifier(), new For
malParameterList(null, new List<FormalParameter>(), null, null, null), new Empty
FunctionBody(createSyntheticToken2(TokenType.SEMICOLON))); |
| 1706 } |
1695 return null; | 1707 return null; |
1696 } else if (matches4(peek(), TokenType.PERIOD) && matchesIdentifier2(peek2(2)
) && matches4(peek2(3), TokenType.OPEN_PAREN)) { | 1708 } else if (matches4(peek(), TokenType.PERIOD) && matchesIdentifier2(peek2(2)
) && matches4(peek2(3), TokenType.OPEN_PAREN)) { |
1697 return parseConstructor(commentAndMetadata, modifiers.externalKeyword, val
idateModifiersForConstructor(modifiers), modifiers.factoryKeyword, parseSimpleId
entifier(), andAdvance, parseSimpleIdentifier(), parseFormalParameterList()); | 1709 return parseConstructor(commentAndMetadata, modifiers.externalKeyword, val
idateModifiersForConstructor(modifiers), modifiers.factoryKeyword, parseSimpleId
entifier(), andAdvance, parseSimpleIdentifier(), parseFormalParameterList()); |
1698 } else if (matches4(peek(), TokenType.OPEN_PAREN)) { | 1710 } else if (matches4(peek(), TokenType.OPEN_PAREN)) { |
1699 SimpleIdentifier methodName = parseSimpleIdentifier(); | 1711 SimpleIdentifier methodName = parseSimpleIdentifier(); |
1700 FormalParameterList parameters = parseFormalParameterList(); | 1712 FormalParameterList parameters = parseFormalParameterList(); |
1701 if (matches5(TokenType.COLON) || modifiers.factoryKeyword != null || metho
dName.name == className) { | 1713 if (matches5(TokenType.COLON) || modifiers.factoryKeyword != null || metho
dName.name == className) { |
1702 return parseConstructor(commentAndMetadata, modifiers.externalKeyword, v
alidateModifiersForConstructor(modifiers), modifiers.factoryKeyword, methodName,
null, null, parameters); | 1714 return parseConstructor(commentAndMetadata, modifiers.externalKeyword, v
alidateModifiersForConstructor(modifiers), modifiers.factoryKeyword, methodName,
null, null, parameters); |
1703 } | 1715 } |
1704 validateModifiersForGetterOrSetterOrMethod(modifiers); | 1716 validateModifiersForGetterOrSetterOrMethod(modifiers); |
(...skipping 1060 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2765 // Pass in the error code to use to report the error? | 2777 // Pass in the error code to use to report the error? |
2766 if (identical(type, TokenType.SEMICOLON)) { | 2778 if (identical(type, TokenType.SEMICOLON)) { |
2767 reportError14(ParserErrorCode.EXPECTED_TOKEN, _currentToken.previous, [typ
e.lexeme]); | 2779 reportError14(ParserErrorCode.EXPECTED_TOKEN, _currentToken.previous, [typ
e.lexeme]); |
2768 } else { | 2780 } else { |
2769 reportError13(ParserErrorCode.EXPECTED_TOKEN, [type.lexeme]); | 2781 reportError13(ParserErrorCode.EXPECTED_TOKEN, [type.lexeme]); |
2770 } | 2782 } |
2771 return _currentToken; | 2783 return _currentToken; |
2772 } | 2784 } |
2773 | 2785 |
2774 /** | 2786 /** |
| 2787 * If [currentToken] is a semicolon, returns it; otherwise reports error and c
reates a |
| 2788 * synthetic one. |
| 2789 * |
| 2790 * TODO(scheglov) consider pushing this into [expect] |
| 2791 */ |
| 2792 Token expectSemicolon() { |
| 2793 if (matches5(TokenType.SEMICOLON)) { |
| 2794 return andAdvance; |
| 2795 } else { |
| 2796 reportError14(ParserErrorCode.EXPECTED_TOKEN, _currentToken.previous, [";"
]); |
| 2797 return createSyntheticToken2(TokenType.SEMICOLON); |
| 2798 } |
| 2799 } |
| 2800 |
| 2801 /** |
2775 * Search the given list of ranges for a range that contains the given index.
Return the range | 2802 * Search the given list of ranges for a range that contains the given index.
Return the range |
2776 * that was found, or `null` if none of the ranges contain the index. | 2803 * that was found, or `null` if none of the ranges contain the index. |
2777 * | 2804 * |
2778 * @param ranges the ranges to be searched | 2805 * @param ranges the ranges to be searched |
2779 * @param index the index contained in the returned range | 2806 * @param index the index contained in the returned range |
2780 * @return the range that was found | 2807 * @return the range that was found |
2781 */ | 2808 */ |
2782 List<int> findRange(List<List<int>> ranges, int index) { | 2809 List<int> findRange(List<List<int>> ranges, int index) { |
2783 int rangeCount = ranges.length; | 2810 int rangeCount = ranges.length; |
2784 for (int i = 0; i < rangeCount; i++) { | 2811 for (int i = 0; i < rangeCount; i++) { |
(...skipping 1041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3826 * </pre> | 3853 * </pre> |
3827 * | 3854 * |
3828 * @param referenceSource the source occurring between the square brackets wit
hin a documentation | 3855 * @param referenceSource the source occurring between the square brackets wit
hin a documentation |
3829 * comment | 3856 * comment |
3830 * @param sourceOffset the offset of the first character of the reference sour
ce | 3857 * @param sourceOffset the offset of the first character of the reference sour
ce |
3831 * @return the comment reference that was parsed, or `null` if no reference co
uld be found | 3858 * @return the comment reference that was parsed, or `null` if no reference co
uld be found |
3832 */ | 3859 */ |
3833 CommentReference parseCommentReference(String referenceSource, int sourceOffse
t) { | 3860 CommentReference parseCommentReference(String referenceSource, int sourceOffse
t) { |
3834 // TODO(brianwilkerson) The errors are not getting the right offset/length a
nd are being duplicated. | 3861 // TODO(brianwilkerson) The errors are not getting the right offset/length a
nd are being duplicated. |
3835 if (referenceSource.length == 0) { | 3862 if (referenceSource.length == 0) { |
3836 return null; | 3863 Token syntheticToken = new SyntheticStringToken(TokenType.IDENTIFIER, "",
sourceOffset); |
| 3864 return new CommentReference(null, new SimpleIdentifier(syntheticToken)); |
3837 } | 3865 } |
3838 try { | 3866 try { |
3839 BooleanErrorListener listener = new BooleanErrorListener(); | 3867 BooleanErrorListener listener = new BooleanErrorListener(); |
3840 Scanner scanner = new Scanner(null, new SubSequenceReader(referenceSource,
sourceOffset), listener); | 3868 Scanner scanner = new Scanner(null, new SubSequenceReader(referenceSource,
sourceOffset), listener); |
3841 scanner.setSourceStart(1, 1); | 3869 scanner.setSourceStart(1, 1); |
3842 Token firstToken = scanner.tokenize(); | 3870 Token firstToken = scanner.tokenize(); |
3843 if (listener.errorReported) { | 3871 if (listener.errorReported) { |
3844 return null; | 3872 return null; |
3845 } | 3873 } |
3846 Token newKeyword = null; | 3874 Token newKeyword = null; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3893 List<CommentReference> parseCommentReferences(List<Token> tokens) { | 3921 List<CommentReference> parseCommentReferences(List<Token> tokens) { |
3894 List<CommentReference> references = new List<CommentReference>(); | 3922 List<CommentReference> references = new List<CommentReference>(); |
3895 for (Token token in tokens) { | 3923 for (Token token in tokens) { |
3896 String comment = token.lexeme; | 3924 String comment = token.lexeme; |
3897 int length = comment.length; | 3925 int length = comment.length; |
3898 List<List<int>> codeBlockRanges = getCodeBlockRanges(comment); | 3926 List<List<int>> codeBlockRanges = getCodeBlockRanges(comment); |
3899 int leftIndex = comment.indexOf('['); | 3927 int leftIndex = comment.indexOf('['); |
3900 while (leftIndex >= 0 && leftIndex + 1 < length) { | 3928 while (leftIndex >= 0 && leftIndex + 1 < length) { |
3901 List<int> range = findRange(codeBlockRanges, leftIndex); | 3929 List<int> range = findRange(codeBlockRanges, leftIndex); |
3902 if (range == null) { | 3930 if (range == null) { |
| 3931 int nameOffset = token.offset + leftIndex + 1; |
3903 int rightIndex = JavaString.indexOf(comment, ']', leftIndex); | 3932 int rightIndex = JavaString.indexOf(comment, ']', leftIndex); |
3904 if (rightIndex >= 0) { | 3933 if (rightIndex >= 0) { |
3905 int firstChar = comment.codeUnitAt(leftIndex + 1); | 3934 int firstChar = comment.codeUnitAt(leftIndex + 1); |
3906 if (firstChar != 0x27 && firstChar != 0x22) { | 3935 if (firstChar != 0x27 && firstChar != 0x22) { |
3907 if (isLinkText(comment, rightIndex)) { | 3936 if (isLinkText(comment, rightIndex)) { |
3908 } else { | 3937 } else { |
3909 CommentReference reference = parseCommentReference(comment.subst
ring(leftIndex + 1, rightIndex), token.offset + leftIndex + 1); | 3938 CommentReference reference = parseCommentReference(comment.subst
ring(leftIndex + 1, rightIndex), nameOffset); |
3910 if (reference != null) { | 3939 if (reference != null) { |
3911 references.add(reference); | 3940 references.add(reference); |
3912 } | 3941 } |
3913 } | 3942 } |
3914 } | 3943 } |
3915 } else { | 3944 } else { |
| 3945 // terminating ']' is not typed yet |
| 3946 int charAfterLeft = comment.codeUnitAt(leftIndex + 1); |
| 3947 if (Character.isLetterOrDigit(charAfterLeft)) { |
| 3948 int nameEnd = StringUtilities.indexOfFirstNotLetterDigit(comment,
leftIndex + 1); |
| 3949 String name = comment.substring(leftIndex + 1, nameEnd); |
| 3950 Token nameToken = new StringToken(TokenType.IDENTIFIER, name, name
Offset); |
| 3951 references.add(new CommentReference(null, new SimpleIdentifier(nam
eToken))); |
| 3952 } else { |
| 3953 Token nameToken = new SyntheticStringToken(TokenType.IDENTIFIER, "
", nameOffset); |
| 3954 references.add(new CommentReference(null, new SimpleIdentifier(nam
eToken))); |
| 3955 } |
| 3956 // next character |
3916 rightIndex = leftIndex + 1; | 3957 rightIndex = leftIndex + 1; |
3917 } | 3958 } |
3918 leftIndex = JavaString.indexOf(comment, '[', rightIndex); | 3959 leftIndex = JavaString.indexOf(comment, '[', rightIndex); |
3919 } else { | 3960 } else { |
3920 leftIndex = JavaString.indexOf(comment, '[', range[1] + 1); | 3961 leftIndex = JavaString.indexOf(comment, '[', range[1] + 1); |
3921 } | 3962 } |
3922 } | 3963 } |
3923 } | 3964 } |
3924 return references; | 3965 return references; |
3925 } | 3966 } |
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4315 * metadata 'export' stringLiteral combinator*';' | 4356 * metadata 'export' stringLiteral combinator*';' |
4316 * </pre> | 4357 * </pre> |
4317 * | 4358 * |
4318 * @param commentAndMetadata the metadata to be associated with the directive | 4359 * @param commentAndMetadata the metadata to be associated with the directive |
4319 * @return the export directive that was parsed | 4360 * @return the export directive that was parsed |
4320 */ | 4361 */ |
4321 ExportDirective parseExportDirective(CommentAndMetadata commentAndMetadata) { | 4362 ExportDirective parseExportDirective(CommentAndMetadata commentAndMetadata) { |
4322 Token exportKeyword = expect(Keyword.EXPORT); | 4363 Token exportKeyword = expect(Keyword.EXPORT); |
4323 StringLiteral libraryUri = parseStringLiteral(); | 4364 StringLiteral libraryUri = parseStringLiteral(); |
4324 List<Combinator> combinators = parseCombinators(); | 4365 List<Combinator> combinators = parseCombinators(); |
4325 Token semicolon = expect2(TokenType.SEMICOLON); | 4366 Token semicolon = expectSemicolon(); |
4326 return new ExportDirective(commentAndMetadata.comment, commentAndMetadata.me
tadata, exportKeyword, libraryUri, combinators, semicolon); | 4367 return new ExportDirective(commentAndMetadata.comment, commentAndMetadata.me
tadata, exportKeyword, libraryUri, combinators, semicolon); |
4327 } | 4368 } |
4328 | 4369 |
4329 /** | 4370 /** |
4330 * Parse a list of expressions. | 4371 * Parse a list of expressions. |
4331 * | 4372 * |
4332 * <pre> | 4373 * <pre> |
4333 * expressionList ::= | 4374 * expressionList ::= |
4334 * expression (',' expression)* | 4375 * expression (',' expression)* |
4335 * </pre> | 4376 * </pre> |
(...skipping 472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4808 ImportDirective parseImportDirective(CommentAndMetadata commentAndMetadata) { | 4849 ImportDirective parseImportDirective(CommentAndMetadata commentAndMetadata) { |
4809 Token importKeyword = expect(Keyword.IMPORT); | 4850 Token importKeyword = expect(Keyword.IMPORT); |
4810 StringLiteral libraryUri = parseStringLiteral(); | 4851 StringLiteral libraryUri = parseStringLiteral(); |
4811 Token asToken = null; | 4852 Token asToken = null; |
4812 SimpleIdentifier prefix = null; | 4853 SimpleIdentifier prefix = null; |
4813 if (matches(Keyword.AS)) { | 4854 if (matches(Keyword.AS)) { |
4814 asToken = andAdvance; | 4855 asToken = andAdvance; |
4815 prefix = parseSimpleIdentifier(); | 4856 prefix = parseSimpleIdentifier(); |
4816 } | 4857 } |
4817 List<Combinator> combinators = parseCombinators(); | 4858 List<Combinator> combinators = parseCombinators(); |
4818 Token semicolon = expect2(TokenType.SEMICOLON); | 4859 Token semicolon = expectSemicolon(); |
4819 return new ImportDirective(commentAndMetadata.comment, commentAndMetadata.me
tadata, importKeyword, libraryUri, asToken, prefix, combinators, semicolon); | 4860 return new ImportDirective(commentAndMetadata.comment, commentAndMetadata.me
tadata, importKeyword, libraryUri, asToken, prefix, combinators, semicolon); |
4820 } | 4861 } |
4821 | 4862 |
4822 /** | 4863 /** |
4823 * Parse a list of initialized identifiers. | 4864 * Parse a list of initialized identifiers. |
4824 * | 4865 * |
4825 * <pre> | 4866 * <pre> |
4826 * ?? ::= | 4867 * ?? ::= |
4827 * 'static'? ('var' | type) initializedIdentifierList ';' | 4868 * 'static'? ('var' | type) initializedIdentifierList ';' |
4828 * | 'final' type? initializedIdentifierList ';' | 4869 * | 'final' type? initializedIdentifierList ';' |
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5465 } | 5506 } |
5466 } else { | 5507 } else { |
5467 operand = parseAssignableSelector(operand, true); | 5508 operand = parseAssignableSelector(operand, true); |
5468 } | 5509 } |
5469 } while (matches5(TokenType.OPEN_SQUARE_BRACKET) || matches5(TokenType.PER
IOD) || matches5(TokenType.OPEN_PAREN)); | 5510 } while (matches5(TokenType.OPEN_SQUARE_BRACKET) || matches5(TokenType.PER
IOD) || matches5(TokenType.OPEN_PAREN)); |
5470 return operand; | 5511 return operand; |
5471 } | 5512 } |
5472 if (!_currentToken.type.isIncrementOperator) { | 5513 if (!_currentToken.type.isIncrementOperator) { |
5473 return operand; | 5514 return operand; |
5474 } | 5515 } |
5475 if (operand is Literal || operand is FunctionExpressionInvocation) { | 5516 ensureAssignable(operand); |
5476 reportError13(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, []); | |
5477 } | |
5478 Token operator = andAdvance; | 5517 Token operator = andAdvance; |
5479 return new PostfixExpression(operand, operator); | 5518 return new PostfixExpression(operand, operator); |
5480 } | 5519 } |
5481 | 5520 |
5482 /** | 5521 /** |
5483 * Parse a primary expression. | 5522 * Parse a primary expression. |
5484 * | 5523 * |
5485 * <pre> | 5524 * <pre> |
5486 * primary ::= | 5525 * primary ::= |
5487 * thisExpression | 5526 * thisExpression |
(...skipping 1457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6945 | 6984 |
6946 /** | 6985 /** |
6947 * Validate that the given set of modifiers is appropriate for a constructor a
nd return the | 6986 * Validate that the given set of modifiers is appropriate for a constructor a
nd return the |
6948 * 'const' keyword if there is one. | 6987 * 'const' keyword if there is one. |
6949 * | 6988 * |
6950 * @param modifiers the modifiers being validated | 6989 * @param modifiers the modifiers being validated |
6951 * @return the 'const' or 'final' keyword associated with the constructor | 6990 * @return the 'const' or 'final' keyword associated with the constructor |
6952 */ | 6991 */ |
6953 Token validateModifiersForConstructor(Modifiers modifiers) { | 6992 Token validateModifiersForConstructor(Modifiers modifiers) { |
6954 if (modifiers.abstractKeyword != null) { | 6993 if (modifiers.abstractKeyword != null) { |
6955 reportError13(ParserErrorCode.ABSTRACT_CLASS_MEMBER, []); | 6994 reportError14(ParserErrorCode.ABSTRACT_CLASS_MEMBER, modifiers.abstractKey
word, []); |
6956 } | 6995 } |
6957 if (modifiers.finalKeyword != null) { | 6996 if (modifiers.finalKeyword != null) { |
6958 reportError14(ParserErrorCode.FINAL_CONSTRUCTOR, modifiers.finalKeyword, [
]); | 6997 reportError14(ParserErrorCode.FINAL_CONSTRUCTOR, modifiers.finalKeyword, [
]); |
6959 } | 6998 } |
6960 if (modifiers.staticKeyword != null) { | 6999 if (modifiers.staticKeyword != null) { |
6961 reportError14(ParserErrorCode.STATIC_CONSTRUCTOR, modifiers.staticKeyword,
[]); | 7000 reportError14(ParserErrorCode.STATIC_CONSTRUCTOR, modifiers.staticKeyword,
[]); |
6962 } | 7001 } |
6963 if (modifiers.varKeyword != null) { | 7002 if (modifiers.varKeyword != null) { |
6964 reportError14(ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE, modifiers.varK
eyword, []); | 7003 reportError14(ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE, modifiers.varK
eyword, []); |
6965 } | 7004 } |
(...skipping 2632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9598 if ("\n" == separator) { | 9637 if ("\n" == separator) { |
9599 _writer.print("\n"); | 9638 _writer.print("\n"); |
9600 indent(); | 9639 indent(); |
9601 } else if (i > 0) { | 9640 } else if (i > 0) { |
9602 _writer.print(separator); | 9641 _writer.print(separator); |
9603 } | 9642 } |
9604 _writer.print(tokens[i].lexeme); | 9643 _writer.print(tokens[i].lexeme); |
9605 } | 9644 } |
9606 } | 9645 } |
9607 } | 9646 } |
OLD | NEW |