2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.intellij
.psi
.impl
.source
.parsing
;
18 import com
.intellij
.codeInsight
.daemon
.JavaErrorMessages
;
19 import com
.intellij
.lang
.ASTFactory
;
20 import com
.intellij
.lexer
.*;
21 import com
.intellij
.openapi
.diagnostic
.Logger
;
22 import com
.intellij
.psi
.JavaTokenType
;
23 import com
.intellij
.psi
.PsiManager
;
24 import com
.intellij
.psi
.TokenType
;
25 import com
.intellij
.psi
.impl
.source
.DummyHolderFactory
;
26 import com
.intellij
.psi
.impl
.source
.tree
.*;
27 import com
.intellij
.psi
.jsp
.AbstractJspJavaLexer
;
28 import com
.intellij
.psi
.tree
.IElementType
;
29 import com
.intellij
.psi
.tree
.ILazyParseableElementType
;
30 import com
.intellij
.util
.SmartList
;
31 import org
.jetbrains
.annotations
.Nullable
;
33 import java
.util
.ArrayList
;
34 import java
.util
.List
;
36 public class StatementParsing
extends Parsing
{
37 private static final Logger LOG
= Logger
.getInstance("#com.intellij.psi.impl.source.parsing.StatementParsing");
39 public interface StatementParser
{
41 CompositeElement
parseStatement(Lexer lexer
);
44 public interface StatementParsingHandler
{
45 @Nullable StatementParser
getParserForToken(IElementType token
);
48 private List
<StatementParsingHandler
> myCustomHandlers
= null;
50 public StatementParsing(JavaParsingContext context
) {
54 public void registerCustomStatementParser(StatementParsingHandler handler
) {
55 if (myCustomHandlers
== null) {
56 myCustomHandlers
= new ArrayList
<StatementParsingHandler
>();
59 myCustomHandlers
.add(handler
);
62 public CompositeElement
parseCodeBlockText(PsiManager manager
, CharSequence buffer
) {
63 return parseCodeBlockText(manager
, null, buffer
, 0, buffer
.length(), -1);
66 public CompositeElement
parseCodeBlockText(PsiManager manager
,
73 lexer
= new JavaLexer(myContext
.getLanguageLevel());
75 final FilterLexer filterLexer
= new FilterLexer(lexer
, new FilterLexer
.SetFilter(StdTokenSets
.WHITE_SPACE_OR_COMMENT_BIT_SET
));
76 if (state
< 0) filterLexer
.start(buffer
, startOffset
, endOffset
);
77 else filterLexer
.start(buffer
, startOffset
, endOffset
, state
);
79 final FileElement dummyRoot
= DummyHolderFactory
.createHolder(manager
, null, myContext
.getCharTable()).getTreeElement();
80 CompositeElement block
= ASTFactory
.lazy(JavaElementType
.CODE_BLOCK
, null);
81 dummyRoot
.rawAddChildren(block
);
82 parseCodeBlockDeep(block
, filterLexer
, true);
83 if (block
.getFirstChildNode() == null) return null;
85 ParseUtil
.insertMissingTokens(block
, lexer
, startOffset
, endOffset
, state
, WhiteSpaceAndCommentsProcessor
.INSTANCE
, myContext
);
89 public TreeElement
parseStatements(PsiManager manager
,
96 lexer
= new JavaLexer(myContext
.getLanguageLevel());
98 final FilterLexer filterLexer
= new FilterLexer(lexer
, new FilterLexer
.SetFilter(StdTokenSets
.WHITE_SPACE_OR_COMMENT_BIT_SET
));
99 if (state
< 0) filterLexer
.start(buffer
, startOffset
, endOffset
);
100 else filterLexer
.start(buffer
, startOffset
, endOffset
, state
);
102 final FileElement dummyRoot
= DummyHolderFactory
.createHolder(manager
, null, myContext
.getCharTable()).getTreeElement();
103 parseStatements(dummyRoot
, filterLexer
, RBRACE_IS_ERROR
);
105 ParseUtil
.insertMissingTokens(dummyRoot
,
110 WhiteSpaceAndCommentsProcessor
.INSTANCE
, myContext
);
111 return dummyRoot
.getFirstChildNode();
114 public TreeElement
parseCodeBlock(Lexer lexer
, boolean deep
) {
115 if (lexer
.getTokenType() != JavaTokenType
.LBRACE
) return null;
116 Lexer badLexer
= lexer
instanceof StoppableLexerAdapter ?
((StoppableLexerAdapter
)lexer
).getDelegate() : lexer
;
117 if (badLexer
instanceof FilterLexer
){
118 final Lexer original
= ((FilterLexer
)badLexer
).getOriginal();
119 if (original
instanceof AbstractJspJavaLexer
){
120 deep
= true; // deep parsing of code blocks in JSP would lead to incorrect parsing on transforming
125 int start
= lexer
.getTokenStart();
130 IElementType tokenType
= lexer
.getTokenType();
131 if (tokenType
== null){
132 end
= lexer
.getTokenStart();
135 if (tokenType
== JavaTokenType
.LBRACE
){
138 else if (tokenType
== JavaTokenType
.RBRACE
){
141 if (braceCount
== 0){
142 end
= lexer
.getTokenEnd();
147 if (braceCount
== 1 && (tokenType
== JavaTokenType
.SEMICOLON
|| tokenType
== JavaTokenType
.RBRACE
)) {
150 final LexerPosition position
= lexer
.getCurrentPosition();
151 List
<IElementType
> list
= new SmartList
<IElementType
>();
153 final IElementType type
= lexer
.getTokenType();
154 if (ElementType
.PRIMITIVE_TYPE_BIT_SET
.contains(type
) || type
== JavaTokenType
.IDENTIFIER
|| ElementType
.MODIFIER_BIT_SET
.contains(type
) ||
155 type
== JavaTokenType
.LT
|| type
== JavaTokenType
.GT
|| type
== JavaTokenType
.GTGT
|| type
== JavaTokenType
.GTGTGT
|| type
==
156 JavaTokenType
.COMMA
|| type
==
158 type
== JavaTokenType
.EXTENDS_KEYWORD
|| type
== JavaTokenType
.IMPLEMENTS_KEYWORD
) {
165 if (lexer
.getTokenType() == JavaTokenType
.LPARENTH
&& list
.size() >= 2) {
166 final IElementType last
= list
.get(list
.size() - 1);
167 final IElementType prevLast
= list
.get(list
.size() - 2);
168 if (last
== JavaTokenType
.IDENTIFIER
&& (prevLast
== JavaTokenType
.IDENTIFIER
|| ElementType
.PRIMITIVE_TYPE_BIT_SET
.contains(prevLast
))) {
169 lexer
.restore(position
);
170 end
= lexer
.getTokenStart();
179 final TreeElement chameleon
= ASTFactory
.lazy(JavaElementType
.CODE_BLOCK
, myContext
.getCharTable().intern(lexer
.getBufferSequence(), start
, end
));
180 if (braceCount
!= 0){
181 chameleon
.putUserData(TreeUtil
.UNCLOSED_ELEMENT_PROPERTY
, "");
186 CompositeElement codeBlock
= ASTFactory
.lazy(JavaElementType
.CODE_BLOCK
, null);
187 parseCodeBlockDeep(codeBlock
, lexer
, false);
192 private void parseCodeBlockDeep(CompositeElement elementToAdd
,
194 boolean parseToEndOfLexer
) {
195 LOG
.assertTrue(lexer
.getTokenType() == JavaTokenType
.LBRACE
, lexer
.getTokenType());
197 elementToAdd
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
200 parseStatements(elementToAdd
, lexer
, parseToEndOfLexer ? LAST_RBRACE_IS_END
: RBRACE_IS_END
);
202 final TreeElement lastChild
= elementToAdd
.getLastChildNode();
203 if (lastChild
== null || lastChild
.getElementType() != JavaTokenType
.RBRACE
){
204 CompositeElement errorElement
= Factory
.createErrorElement(JavaErrorMessages
.message("expected.rbrace"));
205 elementToAdd
.rawAddChildren(errorElement
);
206 elementToAdd
.putUserData(TreeUtil
.UNCLOSED_ELEMENT_PROPERTY
, "");
210 private static final int RBRACE_IS_ERROR
= 1;
211 private static final int RBRACE_IS_END
= 2;
212 private static final int LAST_RBRACE_IS_END
= 3;
214 private void parseStatements(CompositeElement elementToAdd
, Lexer lexer
, int rbraceMode
){
215 while(lexer
.getTokenType() != null){
216 TreeElement statement
= parseStatement(lexer
);
217 if (statement
!= null){
218 elementToAdd
.rawAddChildren(statement
);
222 IElementType tokenType
= lexer
.getTokenType();
223 TreeElement tokenElement
= ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable());
226 if (tokenType
== JavaTokenType
.RBRACE
){
228 if (rbraceMode
== RBRACE_IS_ERROR
) {
230 else if (rbraceMode
== RBRACE_IS_END
) {
231 elementToAdd
.rawAddChildren(tokenElement
);
234 else if (rbraceMode
== LAST_RBRACE_IS_END
) {
235 if (lexer
.getTokenType() == null) {
236 elementToAdd
.rawAddChildren(tokenElement
);
244 LOG
.assertTrue(false);
249 if (tokenType
== JavaTokenType
.ELSE_KEYWORD
){
250 error
= JavaErrorMessages
.message("else.without.if");
252 else if (tokenType
== JavaTokenType
.CATCH_KEYWORD
){
253 error
= JavaErrorMessages
.message("catch.without.try");
255 else if (tokenType
== JavaTokenType
.FINAL_KEYWORD
){
256 error
= JavaErrorMessages
.message("finally.without.try");
259 error
= JavaErrorMessages
.message("unexpected.token");
261 CompositeElement errorElement
= Factory
.createErrorElement(error
);
262 errorElement
.rawAddChildren(tokenElement
);
263 elementToAdd
.rawAddChildren(errorElement
);
268 public TreeElement
parseStatementText(CharSequence buffer
) {
269 Lexer lexer
= new JavaLexer(myContext
.getLanguageLevel());
270 final FilterLexer filterLexer
= new FilterLexer(lexer
, new FilterLexer
.SetFilter(StdTokenSets
.WHITE_SPACE_OR_COMMENT_BIT_SET
));
271 filterLexer
.start(buffer
);
273 TreeElement statement
= parseStatement(filterLexer
);
274 if (statement
== null) return null;
275 if (filterLexer
.getTokenType() != null) return null;
277 if(statement
instanceof CompositeElement
)
278 ParseUtil
.insertMissingTokens((CompositeElement
)statement
, lexer
, 0, buffer
.length(), -1, WhiteSpaceAndCommentsProcessor
.INSTANCE
, myContext
);
283 public TreeElement
parseStatement(Lexer lexer
) {
284 IElementType tokenType
= lexer
.getTokenType();
285 if (myCustomHandlers
!= null) {
286 for (StatementParsingHandler handler
: myCustomHandlers
) {
287 final StatementParser parser
= handler
.getParserForToken(tokenType
);
288 if (parser
!= null) {
289 return parser
.parseStatement(lexer
);
294 if (tokenType
== JavaTokenType
.IF_KEYWORD
) {
295 return parseIfStatement(lexer
);
297 if (tokenType
== JavaTokenType
.WHILE_KEYWORD
) {
298 return parseWhileStatement(lexer
);
300 if (tokenType
== JavaTokenType
.FOR_KEYWORD
) {
301 return parseForStatement(lexer
);
303 if (tokenType
== JavaTokenType
.DO_KEYWORD
) {
304 return parseDoWhileStatement(lexer
);
306 if (tokenType
== JavaTokenType
.SWITCH_KEYWORD
) {
307 return parseSwitchStatement(lexer
);
309 if (tokenType
== JavaTokenType
.CASE_KEYWORD
|| tokenType
== JavaTokenType
.DEFAULT_KEYWORD
) {
310 return parseSwitchLabelStatement(lexer
);
312 if (tokenType
== JavaTokenType
.BREAK_KEYWORD
) {
313 return parseBreakStatement(lexer
);
315 if (tokenType
== JavaTokenType
.CONTINUE_KEYWORD
) {
316 return parseContinueStatement(lexer
);
318 if (tokenType
== JavaTokenType
.RETURN_KEYWORD
) {
319 return parseReturnStatement(lexer
);
321 if (tokenType
== JavaTokenType
.THROW_KEYWORD
) {
322 return parseThrowStatement(lexer
);
324 if (tokenType
== JavaTokenType
.SYNCHRONIZED_KEYWORD
) {
325 return parseSynchronizedStatement(lexer
);
327 if (tokenType
== JavaTokenType
.TRY_KEYWORD
) {
328 return parseTryStatement(lexer
);
330 if (tokenType
== JavaTokenType
.ASSERT_KEYWORD
) {
331 return parseAssertStatement(lexer
);
333 if (tokenType
== JavaTokenType
.LBRACE
) {
334 return parseBlockStatement(lexer
);
336 if (tokenType
instanceof ILazyParseableElementType
) {
337 TreeElement declaration
= ASTFactory
.lazy((ILazyParseableElementType
)tokenType
, myContext
.tokenText(lexer
));
341 if (tokenType
== JavaTokenType
.SEMICOLON
) {
342 CompositeElement element
= ASTFactory
.composite(JavaElementType
.EMPTY_STATEMENT
);
343 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
347 if (tokenType
== JavaTokenType
.IDENTIFIER
|| tokenType
== JavaTokenType
.AT
) {
348 final LexerPosition refPos
= lexer
.getCurrentPosition();
349 parseAnnotationListTo(lexer
, null); // @Ann ClassName.field++;
350 skipQualifiedName(lexer
);
351 final IElementType suspectedLT
= lexer
.getTokenType();
352 lexer
.restore(refPos
);
353 LOG
.assertTrue(lexer
.getTokenType() == JavaTokenType
.IDENTIFIER
|| lexer
.getTokenType() == JavaTokenType
.AT
);
354 if (suspectedLT
== JavaTokenType
.LT
) {
355 final TreeElement decl
= myContext
.getDeclarationParsing().parseDeclaration(lexer
, DeclarationParsing
.Context
.CODE_BLOCK_CONTEXT
);
356 CompositeElement declStatement
= ASTFactory
.composite(JavaElementType
.DECLARATION_STATEMENT
);
358 declStatement
.rawAddChildren(decl
);
361 final CompositeElement type
= parseType(lexer
, false, false);
362 if (type
!= null) declStatement
.rawAddChildren(type
);
363 final CompositeElement errorElement
= Factory
.createErrorElement(JavaErrorMessages
.message("expected.identifier"));
364 declStatement
.rawAddChildren(errorElement
);
366 return declStatement
;
370 final LexerPosition pos
= lexer
.getCurrentPosition();
371 CompositeElement expr
= myContext
.getExpressionParsing().parseExpression(lexer
);
372 final LexerPosition pos1
= lexer
.getCurrentPosition();
375 CompositeElement element
= null;
376 while (lexer
.getTokenType() == JavaTokenType
.COMMA
) {
377 CompositeElement list
= ASTFactory
.composite(JavaElementType
.EXPRESSION_LIST
);
378 element
= ASTFactory
.composite(JavaElementType
.EXPRESSION_LIST_STATEMENT
);
379 element
.rawAddChildren(list
);
380 list
.rawAddChildren(expr
);
381 final LexerPosition commaPos
= lexer
.getCurrentPosition();
382 TreeElement comma
= ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable());
384 CompositeElement expr1
= myContext
.getExpressionParsing().parseExpression(lexer
);
386 lexer
.restore(commaPos
);
389 list
.rawAddChildren(comma
);
390 list
.rawAddChildren(expr1
);
394 processClosingSemicolon(element
, lexer
);
397 if (expr
.getElementType() != JavaElementType
.REFERENCE_EXPRESSION
) {
398 element
= ASTFactory
.composite(JavaElementType
.EXPRESSION_STATEMENT
);
399 element
.rawAddChildren(expr
);
400 processClosingSemicolon(element
, lexer
);
406 TreeElement decl
= myContext
.getDeclarationParsing().parseDeclaration(lexer
, DeclarationParsing
.Context
.CODE_BLOCK_CONTEXT
);
408 CompositeElement declStatement
= ASTFactory
.composite(JavaElementType
.DECLARATION_STATEMENT
);
409 declStatement
.rawAddChildren(decl
);
410 return declStatement
;
413 if (lexer
.getTokenType() == JavaTokenType
.IDENTIFIER
) {
414 TreeElement identifier
= ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable());
416 if (lexer
.getTokenType() == JavaTokenType
.COLON
) {
417 CompositeElement element
= ASTFactory
.composite(JavaElementType
.LABELED_STATEMENT
);
418 element
.rawAddChildren(identifier
);
419 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
421 TreeElement statement
= parseStatement(lexer
);
422 if (statement
!= null) {
423 element
.rawAddChildren(statement
);
432 CompositeElement element
= ASTFactory
.composite(JavaElementType
.EXPRESSION_STATEMENT
);
433 element
.rawAddChildren(expr
);
434 processClosingSemicolon(element
, lexer
);
441 private static void skipQualifiedName(Lexer lexer
) {
442 if (lexer
.getTokenType() != JavaTokenType
.IDENTIFIER
) return;
445 if (lexer
.getTokenType() != JavaTokenType
.DOT
) return;
446 final LexerPosition position
= lexer
.getCurrentPosition();
448 if (lexer
.getTokenType() != JavaTokenType
.IDENTIFIER
){
449 lexer
.restore(position
);
455 private CompositeElement
parseIfStatement(Lexer lexer
) {
456 LOG
.assertTrue(lexer
.getTokenType() == JavaTokenType
.IF_KEYWORD
);
457 CompositeElement element
= ASTFactory
.composite(JavaElementType
.IF_STATEMENT
);
458 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
461 if (!processExpressionInParens(lexer
, element
)){
465 TreeElement thenStatement
= parseStatement(lexer
);
466 if (thenStatement
== null){
467 element
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.statement")));
471 element
.rawAddChildren(thenStatement
);
473 if (lexer
.getTokenType() != JavaTokenType
.ELSE_KEYWORD
){
477 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
479 TreeElement elseStatement
= parseStatement(lexer
);
480 if (elseStatement
== null){
481 element
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.statement")));
484 element
.rawAddChildren(elseStatement
);
488 private CompositeElement
parseWhileStatement(Lexer lexer
) {
489 LOG
.assertTrue(lexer
.getTokenType() == JavaTokenType
.WHILE_KEYWORD
);
490 CompositeElement element
= ASTFactory
.composite(JavaElementType
.WHILE_STATEMENT
);
491 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
494 if (!processExpressionInParens(lexer
, element
)){
498 TreeElement statement
= parseStatement(lexer
);
499 if (statement
== null){
500 element
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.statement")));
504 element
.rawAddChildren(statement
);
508 private CompositeElement
parseForStatement(Lexer lexer
) {
509 LOG
.assertTrue(lexer
.getTokenType() == JavaTokenType
.FOR_KEYWORD
);
510 final TreeElement forKeyword
= ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable());
513 if (lexer
.getTokenType() != JavaTokenType
.LPARENTH
){
514 CompositeElement errorForElement
= ASTFactory
.composite(JavaElementType
.FOR_STATEMENT
);
515 errorForElement
.rawAddChildren(forKeyword
);
516 errorForElement
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.lparen")));
517 return errorForElement
;
520 final TreeElement lparenth
= ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable());
523 final LexerPosition afterLParenth
= lexer
.getCurrentPosition();
524 final TreeElement parameter
= myContext
.getDeclarationParsing().parseParameter(lexer
, false);
525 if (parameter
== null || parameter
.getElementType() != JavaElementType
.PARAMETER
|| lexer
.getTokenType() != JavaTokenType
.COLON
) {
526 lexer
.restore(afterLParenth
);
527 return parseForLoopFromInitialization(forKeyword
, lparenth
, lexer
);
530 return parseForEachFromColon(forKeyword
, lparenth
, parameter
, lexer
);
534 private CompositeElement
parseForEachFromColon(TreeElement forKeyword
,
535 TreeElement lparenth
,
536 TreeElement parameter
,
538 LOG
.assertTrue(lexer
.getTokenType() == JavaTokenType
.COLON
);
539 final CompositeElement element
= ASTFactory
.composite(JavaElementType
.FOREACH_STATEMENT
);
540 element
.rawAddChildren(forKeyword
);
541 element
.rawAddChildren(lparenth
);
542 element
.rawAddChildren(parameter
);
543 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
545 final CompositeElement expr
= myContext
.getExpressionParsing().parseExpression(lexer
);
547 element
.rawAddChildren(expr
);
550 element
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.expression")));
552 if (lexer
.getTokenType() == JavaTokenType
.RPARENTH
) {
553 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
555 final TreeElement body
= parseStatement(lexer
);
557 element
.rawAddChildren(body
);
559 element
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.statement")));
563 element
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.rparen")));
568 private CompositeElement
parseForLoopFromInitialization(final TreeElement forKeyword
,
569 final TreeElement lparenth
,
570 Lexer lexer
) {// parsing normal for statement for statement
571 CompositeElement element
= ASTFactory
.composite(JavaElementType
.FOR_STATEMENT
);
572 element
.rawAddChildren(forKeyword
);
573 element
.rawAddChildren(lparenth
);
574 TreeElement init
= parseStatement(lexer
);
576 element
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.statement")));
577 if (lexer
.getTokenType() != JavaTokenType
.RPARENTH
){
582 element
.rawAddChildren(init
);
584 CompositeElement expr
= myContext
.getExpressionParsing().parseExpression(lexer
);
586 element
.rawAddChildren(expr
);
589 if (lexer
.getTokenType() != JavaTokenType
.SEMICOLON
){
590 element
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.semicolon")));
591 if (lexer
.getTokenType() != JavaTokenType
.RPARENTH
){
596 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
598 parseExpressionOrExpressionList(lexer
, element
);
599 if (lexer
.getTokenType() != JavaTokenType
.RPARENTH
){
600 element
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.rparen")));
606 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
609 TreeElement statement
= parseStatement(lexer
);
610 if (statement
== null){
611 element
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.statement")));
615 element
.rawAddChildren(statement
);
620 private void parseExpressionOrExpressionList(Lexer lexer
, CompositeElement element
) {
621 CompositeElement expression
= myContext
.getExpressionParsing().parseExpression(lexer
);
622 if (expression
!= null) {
623 final CompositeElement expressionStatement
;
624 if (lexer
.getTokenType() != JavaTokenType
.COMMA
) {
625 expressionStatement
= ASTFactory
.composite(JavaElementType
.EXPRESSION_STATEMENT
);
626 expressionStatement
.rawAddChildren(expression
);
628 expressionStatement
= ASTFactory
.composite(JavaElementType
.EXPRESSION_LIST_STATEMENT
);
629 final CompositeElement expressionList
= ASTFactory
.composite(JavaElementType
.EXPRESSION_LIST
);
630 expressionList
.rawAddChildren(expression
);
632 expressionList
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
634 final CompositeElement nextExpression
= myContext
.getExpressionParsing().parseExpression(lexer
);
635 if (nextExpression
!= null) {
636 expressionList
.rawAddChildren(nextExpression
);
638 expressionList
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.expression")));
640 } while (lexer
.getTokenType() == JavaTokenType
.COMMA
);
641 expressionStatement
.rawAddChildren(expressionList
);
643 element
.rawAddChildren(expressionStatement
);
647 private CompositeElement
parseDoWhileStatement(Lexer lexer
) {
648 LOG
.assertTrue(lexer
.getTokenType() == JavaTokenType
.DO_KEYWORD
);
649 CompositeElement element
= ASTFactory
.composite(JavaElementType
.DO_WHILE_STATEMENT
);
650 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
653 TreeElement statement
= parseStatement(lexer
);
654 if (statement
== null){
655 element
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.statement")));
659 element
.rawAddChildren(statement
);
661 if (lexer
.getTokenType() != JavaTokenType
.WHILE_KEYWORD
){
662 element
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.while")));
666 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
669 if (!processExpressionInParens(lexer
, element
)){
673 processClosingSemicolon(element
, lexer
);
678 private CompositeElement
parseSwitchStatement(Lexer lexer
) {
679 LOG
.assertTrue(lexer
.getTokenType() == JavaTokenType
.SWITCH_KEYWORD
);
680 CompositeElement element
= ASTFactory
.composite(JavaElementType
.SWITCH_STATEMENT
);
681 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
684 if (!processExpressionInParens(lexer
, element
)){
688 TreeElement codeBlock
= parseCodeBlock(lexer
, DEEP_PARSE_BLOCKS_IN_STATEMENTS
);
689 if (codeBlock
== null){
690 element
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.lbrace")));
694 element
.rawAddChildren(codeBlock
);
699 private CompositeElement
parseSwitchLabelStatement(Lexer lexer
) {
700 LOG
.assertTrue(lexer
.getTokenType() == JavaTokenType
.CASE_KEYWORD
|| lexer
.getTokenType() == JavaTokenType
.DEFAULT_KEYWORD
);
701 IElementType tokenType
= lexer
.getTokenType();
702 final LexerPosition pos
= lexer
.getCurrentPosition();
703 CompositeElement element
= ASTFactory
.composite(JavaElementType
.SWITCH_LABEL_STATEMENT
);
704 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
706 if (tokenType
== JavaTokenType
.CASE_KEYWORD
){
707 TreeElement expr
= myContext
.getExpressionParsing().parseExpression(lexer
);
712 element
.rawAddChildren(expr
);
714 if (lexer
.getTokenType() == JavaTokenType
.COLON
){
715 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
719 element
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.colon")));
724 private CompositeElement
parseBreakStatement(Lexer lexer
) {
725 LOG
.assertTrue(lexer
.getTokenType() == JavaTokenType
.BREAK_KEYWORD
);
726 CompositeElement element
= ASTFactory
.composite(JavaElementType
.BREAK_STATEMENT
);
727 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
730 if (lexer
.getTokenType() == JavaTokenType
.IDENTIFIER
){
731 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
735 processClosingSemicolon(element
, lexer
);
739 private CompositeElement
parseContinueStatement(Lexer lexer
) {
740 LOG
.assertTrue(lexer
.getTokenType() == JavaTokenType
.CONTINUE_KEYWORD
);
741 CompositeElement element
= ASTFactory
.composite(JavaElementType
.CONTINUE_STATEMENT
);
742 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
745 if (lexer
.getTokenType() == JavaTokenType
.IDENTIFIER
){
746 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
750 processClosingSemicolon(element
, lexer
);
754 private CompositeElement
parseReturnStatement(Lexer lexer
) {
755 LOG
.assertTrue(lexer
.getTokenType() == JavaTokenType
.RETURN_KEYWORD
);
756 CompositeElement element
= ASTFactory
.composite(JavaElementType
.RETURN_STATEMENT
);
757 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
760 TreeElement expr
= myContext
.getExpressionParsing().parseExpression(lexer
);
762 element
.rawAddChildren(expr
);
765 processClosingSemicolon(element
, lexer
);
769 private CompositeElement
parseThrowStatement(Lexer lexer
) {
770 LOG
.assertTrue(lexer
.getTokenType() == JavaTokenType
.THROW_KEYWORD
);
772 CompositeElement element
= ASTFactory
.composite(JavaElementType
.THROW_STATEMENT
);
773 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
776 TreeElement expr
= myContext
.getExpressionParsing().parseExpression(lexer
);
778 element
.rawAddChildren(expr
);
781 element
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.expression")));
785 processClosingSemicolon(element
, lexer
);
789 private CompositeElement
parseSynchronizedStatement(Lexer lexer
) {
790 LOG
.assertTrue(lexer
.getTokenType() == JavaTokenType
.SYNCHRONIZED_KEYWORD
);
791 CompositeElement element
= ASTFactory
.composite(JavaElementType
.SYNCHRONIZED_STATEMENT
);
792 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
795 if (!processExpressionInParens(lexer
, element
)){
799 TreeElement codeBlock
= parseCodeBlock(lexer
, DEEP_PARSE_BLOCKS_IN_STATEMENTS
);
800 if (codeBlock
== null){
801 element
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.lbrace")));
805 element
.rawAddChildren(codeBlock
);
809 private CompositeElement
parseTryStatement(Lexer lexer
) {
810 LOG
.assertTrue(lexer
.getTokenType() == JavaTokenType
.TRY_KEYWORD
);
812 //int pos = ParseUtil.savePosition(lexer);
813 CompositeElement element
= ASTFactory
.composite(JavaElementType
.TRY_STATEMENT
);
814 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
817 TreeElement codeBlock
= parseCodeBlock(lexer
, DEEP_PARSE_BLOCKS_IN_STATEMENTS
);
818 if (codeBlock
== null){
819 element
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.lbrace")));
822 element
.rawAddChildren(codeBlock
);
824 if (lexer
.getTokenType() != JavaTokenType
.CATCH_KEYWORD
&& lexer
.getTokenType() != JavaTokenType
.FINALLY_KEYWORD
){
825 element
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.catch.or.finally")));
829 while(lexer
.getTokenType() == JavaTokenType
.CATCH_KEYWORD
){
830 CompositeElement catchSection
= parseCatchSection(lexer
);
831 element
.rawAddChildren(catchSection
);
832 final TreeElement lastChild
= catchSection
.getLastChildNode();
833 assert lastChild
!= null;
834 if (lastChild
.getElementType() == TokenType
.ERROR_ELEMENT
) break;
837 if (lexer
.getTokenType() == JavaTokenType
.FINALLY_KEYWORD
){
838 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
841 codeBlock
= parseCodeBlock(lexer
, DEEP_PARSE_BLOCKS_IN_STATEMENTS
);
842 if (codeBlock
== null){
843 element
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.lbrace")));
846 element
.rawAddChildren(codeBlock
);
852 private CompositeElement
parseCatchSection(Lexer lexer
) {
853 CompositeElement catchSection
= ASTFactory
.composite(JavaElementType
.CATCH_SECTION
);
854 catchSection
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
857 if (lexer
.getTokenType() != JavaTokenType
.LPARENTH
) {
858 catchSection
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.lparen")));
862 catchSection
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
865 TreeElement parm
= myContext
.getDeclarationParsing().parseParameter(lexer
, false);
867 catchSection
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.parameter")));
869 catchSection
.rawAddChildren(parm
);
872 if (lexer
.getTokenType() != JavaTokenType
.RPARENTH
) {
873 catchSection
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.rparen")));
877 catchSection
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
880 TreeElement codeBlock
= parseCodeBlock(lexer
, DEEP_PARSE_BLOCKS_IN_STATEMENTS
);
881 if (codeBlock
== null) {
882 catchSection
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.lbrace")));
885 catchSection
.rawAddChildren(codeBlock
);
889 private CompositeElement
parseAssertStatement(Lexer lexer
) {
890 LOG
.assertTrue(lexer
.getTokenType() == JavaTokenType
.ASSERT_KEYWORD
);
892 CompositeElement element
= ASTFactory
.composite(JavaElementType
.ASSERT_STATEMENT
);
893 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
896 TreeElement expr
= myContext
.getExpressionParsing().parseExpression(lexer
);
898 element
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.boolean.expression")));
902 element
.rawAddChildren(expr
);
904 if (lexer
.getTokenType() == JavaTokenType
.COLON
){
905 element
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
908 TreeElement expr2
= myContext
.getExpressionParsing().parseExpression(lexer
);
910 element
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.expression")));
914 element
.rawAddChildren(expr2
);
917 processClosingSemicolon(element
, lexer
);
921 private CompositeElement
parseBlockStatement(Lexer lexer
) {
922 LOG
.assertTrue(lexer
.getTokenType() == JavaTokenType
.LBRACE
);
923 CompositeElement element
= ASTFactory
.composite(JavaElementType
.BLOCK_STATEMENT
);
924 TreeElement codeBlock
= parseCodeBlock(lexer
, DEEP_PARSE_BLOCKS_IN_STATEMENTS
);
925 element
.rawAddChildren(codeBlock
);
929 private boolean processExpressionInParens(Lexer lexer
, CompositeElement parent
) {
930 if (lexer
.getTokenType() != JavaTokenType
.LPARENTH
){
931 parent
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.lparen")));
935 parent
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
938 final LexerPosition beforeExprPos
= lexer
.getCurrentPosition();
939 CompositeElement expr
= myContext
.getExpressionParsing().parseExpression(lexer
);
940 if (expr
== null || lexer
.getTokenType() == JavaTokenType
.SEMICOLON
){
942 lexer
.restore(beforeExprPos
);
944 parent
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.expression")));
945 if (lexer
.getTokenType() != JavaTokenType
.RPARENTH
){
950 parent
.rawAddChildren(expr
);
952 if (lexer
.getTokenType() != JavaTokenType
.RPARENTH
){
953 parent
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.rparen")));
959 parent
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
965 private void processClosingSemicolon(CompositeElement statement
, Lexer lexer
) {
966 if (lexer
.getTokenType() == JavaTokenType
.SEMICOLON
){
967 statement
.rawAddChildren(ParseUtil
.createTokenElement(lexer
, myContext
.getCharTable()));
971 statement
.rawAddChildren(Factory
.createErrorElement(JavaErrorMessages
.message("expected.semicolon")));
976 public TreeElement
parseCatchSectionText(CharSequence buffer
) {
977 Lexer lexer
= new JavaLexer(myContext
.getLanguageLevel());
978 final FilterLexer filterLexer
= new FilterLexer(lexer
, new FilterLexer
.SetFilter(StdTokenSets
.WHITE_SPACE_OR_COMMENT_BIT_SET
));
979 filterLexer
.start(buffer
);
981 CompositeElement catchSection
= parseCatchSection(filterLexer
);
982 if (catchSection
== null) return null;
983 if (filterLexer
.getTokenType() != null) return null;
985 ParseUtil
.insertMissingTokens(catchSection
, lexer
, 0, buffer
.length(), -1, WhiteSpaceAndCommentsProcessor
.INSTANCE
, myContext
);