Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 34338 Details for
Bug 42253
[plan][dom/ast] Make AST more robust against syntax errors
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Released code
patch022.txt (text/plain), 50.04 KB, created by
David Audel
on 2006-02-08 07:50:48 EST
(
hide
)
Description:
Released code
Filename:
MIME Type:
Creator:
David Audel
Created:
2006-02-08 07:50:48 EST
Size:
50.04 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.jdt.core >Index: dom/org/eclipse/jdt/core/dom/ASTParser.java >=================================================================== >RCS file: /home/eclipse/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTParser.java,v >retrieving revision 1.51 >diff -u -r1.51 ASTParser.java >--- dom/org/eclipse/jdt/core/dom/ASTParser.java 23 Jan 2006 10:08:24 -0000 1.51 >+++ dom/org/eclipse/jdt/core/dom/ASTParser.java 8 Feb 2006 11:49:29 -0000 >@@ -970,7 +970,7 @@ > } > } > } >- rootNodeToCompilationUnit(ast, compilationUnit, block, recordedParsingInformation); >+ rootNodeToCompilationUnit(ast, compilationUnit, block, recordedParsingInformation, data); > ast.setDefaultNodeFlag(0); > ast.setOriginalModificationCount(ast.modificationCount()); > return block; >@@ -993,7 +993,7 @@ > compilationUnit.setLineEndTable(recordedParsingInformation.lineEnds); > if (expression != null) { > Expression expression2 = converter.convert(expression); >- rootNodeToCompilationUnit(expression2.getAST(), compilationUnit, expression2, codeSnippetParsingUtil.recordedParsingInformation); >+ rootNodeToCompilationUnit(expression2.getAST(), compilationUnit, expression2, codeSnippetParsingUtil.recordedParsingInformation, null); > ast.setDefaultNodeFlag(0); > ast.setOriginalModificationCount(ast.modificationCount()); > return expression2; >@@ -1016,7 +1016,7 @@ > compilationUnit.setLineEndTable(recordedParsingInformation.lineEnds); > if (nodes != null) { > TypeDeclaration typeDeclaration = converter.convert(nodes); >- rootNodeToCompilationUnit(typeDeclaration.getAST(), compilationUnit, typeDeclaration, codeSnippetParsingUtil.recordedParsingInformation); >+ rootNodeToCompilationUnit(typeDeclaration.getAST(), compilationUnit, typeDeclaration, codeSnippetParsingUtil.recordedParsingInformation, null); > ast.setDefaultNodeFlag(0); > ast.setOriginalModificationCount(ast.modificationCount()); > return typeDeclaration; >@@ -1033,14 +1033,14 @@ > throw new IllegalStateException(); > } > >- private void propagateErrors(ASTNode astNode, IProblem[] problems) { >+ private void propagateErrors(ASTNode astNode, IProblem[] problems, RecoveryScannerData data) { > ASTSyntaxErrorPropagator syntaxErrorPropagator = new ASTSyntaxErrorPropagator(problems); > astNode.accept(syntaxErrorPropagator); >- ASTRecoveryPropagator recoveryPropagator = new ASTRecoveryPropagator(problems); >+ ASTRecoveryPropagator recoveryPropagator = new ASTRecoveryPropagator(problems, data); > astNode.accept(recoveryPropagator); > } > >- private void rootNodeToCompilationUnit(AST ast, CompilationUnit compilationUnit, ASTNode node, RecordedParsingInformation recordedParsingInformation) { >+ private void rootNodeToCompilationUnit(AST ast, CompilationUnit compilationUnit, ASTNode node, RecordedParsingInformation recordedParsingInformation, RecoveryScannerData data) { > final int problemsCount = recordedParsingInformation.problemsCount; > switch(node.getNodeType()) { > case ASTNode.BLOCK : >@@ -1050,7 +1050,7 @@ > // propagate and record problems > final IProblem[] problems = recordedParsingInformation.problems; > for (int i = 0, max = block.statements().size(); i < max; i++) { >- propagateErrors((ASTNode) block.statements().get(i), problems); >+ propagateErrors((ASTNode) block.statements().get(i), problems, data); > } > compilationUnit.setProblems(problems); > } >@@ -1068,7 +1068,7 @@ > // propagate and record problems > final IProblem[] problems = recordedParsingInformation.problems; > for (int i = 0, max = typeDeclaration.bodyDeclarations().size(); i < max; i++) { >- propagateErrors((ASTNode) typeDeclaration.bodyDeclarations().get(i), problems); >+ propagateErrors((ASTNode) typeDeclaration.bodyDeclarations().get(i), problems, data); > } > compilationUnit.setProblems(problems); > } >@@ -1081,7 +1081,7 @@ > if (problemsCount != 0) { > // propagate and record problems > final IProblem[] problems = recordedParsingInformation.problems; >- propagateErrors(expression, problems); >+ propagateErrors(expression, problems, data); > compilationUnit.setProblems(problems); > } > ExpressionStatement expressionStatement = ast.newExpressionStatement(expression); >Index: dom/org/eclipse/jdt/core/dom/ASTRecoveryPropagator.java >=================================================================== >RCS file: /home/eclipse/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTRecoveryPropagator.java,v >retrieving revision 1.1 >diff -u -r1.1 ASTRecoveryPropagator.java >--- dom/org/eclipse/jdt/core/dom/ASTRecoveryPropagator.java 17 Jan 2006 18:44:23 -0000 1.1 >+++ dom/org/eclipse/jdt/core/dom/ASTRecoveryPropagator.java 8 Feb 2006 11:49:29 -0000 >@@ -11,27 +11,282 @@ > > package org.eclipse.jdt.core.dom; > >+import java.util.Vector; >+ > import org.eclipse.jdt.core.compiler.IProblem; >+import org.eclipse.jdt.internal.compiler.parser.RecoveryScannerData; >+import org.eclipse.jdt.internal.compiler.parser.TerminalTokens; >+import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToIntArray; > > /** > * Internal AST visitor for propagating syntax errors. > */ > class ASTRecoveryPropagator extends DefaultASTVisitor { >+ private static final int NOTHING = -1; >+ HashtableOfObjectToIntArray endingTokens = new HashtableOfObjectToIntArray(); >+ { >+ this.endingTokens.put(AnonymousClassDeclaration.class, new int[]{TerminalTokens.TokenNameRBRACE}); >+ this.endingTokens.put(ArrayAccess.class, new int[]{TerminalTokens.TokenNameRBRACKET}); >+ this.endingTokens.put(ArrayCreation.class, new int[]{NOTHING, TerminalTokens.TokenNameRBRACKET}); >+ this.endingTokens.put(ArrayInitializer.class, new int[]{TerminalTokens.TokenNameRBRACE}); >+ this.endingTokens.put(ArrayType.class, new int[]{TerminalTokens.TokenNameRBRACKET}); >+ this.endingTokens.put(AssertStatement.class, new int[]{TerminalTokens.TokenNameSEMICOLON}); >+ this.endingTokens.put(Block.class, new int[]{TerminalTokens.TokenNameRBRACE}); >+ this.endingTokens.put(BooleanLiteral.class, new int[]{TerminalTokens.TokenNamefalse, TerminalTokens.TokenNametrue}); >+ this.endingTokens.put(BreakStatement.class, new int[]{TerminalTokens.TokenNameSEMICOLON}); >+ this.endingTokens.put(CharacterLiteral.class, new int[]{TerminalTokens.TokenNameCharacterLiteral}); >+ this.endingTokens.put(ClassInstanceCreation.class, new int[]{TerminalTokens.TokenNameRBRACE, TerminalTokens.TokenNameRPAREN}); >+ this.endingTokens.put(ConstructorInvocation.class, new int[]{TerminalTokens.TokenNameSEMICOLON}); >+ this.endingTokens.put(ContinueStatement.class, new int[]{TerminalTokens.TokenNameSEMICOLON}); >+ this.endingTokens.put(DoStatement.class, new int[]{TerminalTokens.TokenNameRPAREN}); >+ this.endingTokens.put(EmptyStatement.class, new int[]{TerminalTokens.TokenNameSEMICOLON}); >+ this.endingTokens.put(ExpressionStatement.class, new int[]{TerminalTokens.TokenNameSEMICOLON}); >+ this.endingTokens.put(FieldDeclaration.class, new int[]{TerminalTokens.TokenNameSEMICOLON}); >+ this.endingTokens.put(ImportDeclaration.class, new int[]{TerminalTokens.TokenNameSEMICOLON}); >+ this.endingTokens.put(Initializer.class, new int[]{TerminalTokens.TokenNameRBRACE}); >+ this.endingTokens.put(MethodDeclaration.class, new int[]{NOTHING, TerminalTokens.TokenNameSEMICOLON}); >+ this.endingTokens.put(MethodInvocation.class, new int[]{TerminalTokens.TokenNameRPAREN}); >+ this.endingTokens.put(NullLiteral.class, new int[]{TerminalTokens.TokenNamenull}); >+ this.endingTokens.put(NumberLiteral.class, new int[]{TerminalTokens.TokenNameIntegerLiteral, TerminalTokens.TokenNameLongLiteral, TerminalTokens.TokenNameFloatingPointLiteral, TerminalTokens.TokenNameDoubleLiteral}); >+ this.endingTokens.put(PackageDeclaration.class, new int[]{TerminalTokens.TokenNameSEMICOLON}); >+ this.endingTokens.put(ParenthesizedExpression.class, new int[]{TerminalTokens.TokenNameRPAREN}); >+ this.endingTokens.put(PostfixExpression.class, new int[]{TerminalTokens.TokenNamePLUS_PLUS, TerminalTokens.TokenNameMINUS_MINUS}); >+ this.endingTokens.put(PrimitiveType.class, new int[]{TerminalTokens.TokenNamebyte, TerminalTokens.TokenNameshort, TerminalTokens.TokenNamechar, TerminalTokens.TokenNameint, TerminalTokens.TokenNamelong, TerminalTokens.TokenNamefloat, TerminalTokens.TokenNameboolean, TerminalTokens.TokenNamedouble, TerminalTokens.TokenNamevoid}); >+ this.endingTokens.put(ReturnStatement.class, new int[]{TerminalTokens.TokenNameSEMICOLON}); >+ this.endingTokens.put(SimpleName.class, new int[]{TerminalTokens.TokenNameIdentifier}); >+ this.endingTokens.put(SingleVariableDeclaration.class, new int[]{TerminalTokens.TokenNameSEMICOLON}); >+ this.endingTokens.put(StringLiteral.class, new int[]{TerminalTokens.TokenNameStringLiteral}); >+ this.endingTokens.put(SuperConstructorInvocation.class, new int[]{TerminalTokens.TokenNameSEMICOLON}); >+ this.endingTokens.put(SuperMethodInvocation.class, new int[]{TerminalTokens.TokenNameRPAREN}); >+ this.endingTokens.put(SwitchCase.class, new int[]{TerminalTokens.TokenNameCOLON}); >+ this.endingTokens.put(SwitchStatement.class, new int[]{TerminalTokens.TokenNameRBRACE}); >+ this.endingTokens.put(SynchronizedStatement.class, new int[]{TerminalTokens.TokenNameRBRACE}); >+ this.endingTokens.put(ThisExpression.class, new int[]{TerminalTokens.TokenNamethis}); >+ this.endingTokens.put(ThrowStatement.class, new int[]{TerminalTokens.TokenNameSEMICOLON}); >+ this.endingTokens.put(TypeDeclaration.class, new int[]{TerminalTokens.TokenNameRBRACE}); >+ this.endingTokens.put(TypeLiteral.class, new int[]{TerminalTokens.TokenNameclass}); >+ this.endingTokens.put(VariableDeclarationStatement.class, new int[]{TerminalTokens.TokenNameSEMICOLON}); >+ } >+ > private IProblem[] problems; >+ private boolean[] usedOrIrrelevantProblems; >+ >+ private RecoveryScannerData data; >+ private int blockDepth = 0; >+ private int lastEnd; >+ >+ private int[] insertedTokensKind; >+ private int[] insertedTokensPosition; >+ private boolean[] insertedTokensFlagged; >+ >+ private boolean[] removedTokensFlagged; >+ private boolean[] replacedTokensFlagged; >+ >+ private Vector stack = new Vector(); > >- ASTRecoveryPropagator(IProblem[] problems) { >+ ASTRecoveryPropagator(IProblem[] problems, RecoveryScannerData data) { > // visit Javadoc.tags() as well > this.problems = problems; >+ this.usedOrIrrelevantProblems = new boolean[problems.length]; >+ >+ this.data = data; >+ >+ if(this.data != null) { >+ >+ int length = 0; >+ for (int i = 0; i < data.insertedTokensPtr + 1; i++) { >+ length += data.insertedTokens[i].length; >+ } >+ this.insertedTokensKind = new int[length]; >+ this.insertedTokensPosition = new int[length]; >+ this.insertedTokensFlagged = new boolean[length]; >+ int tokenCount = 0; >+ for (int i = 0; i < data.insertedTokensPtr + 1; i++) { >+ for (int j = 0; j < data.insertedTokens[i].length; j++) { >+ this.insertedTokensKind[tokenCount] = data.insertedTokens[i][j]; >+ this.insertedTokensPosition[tokenCount] = data.insertedTokensPosition[i]; >+ tokenCount++; >+ } >+ } >+ >+ if(data.removedTokensPtr != -1) { >+ this.removedTokensFlagged = new boolean[data.removedTokensPtr + 1]; >+ } >+ if(data.replacedTokensPtr != -1) { >+ this.replacedTokensFlagged = new boolean[data.replacedTokensPtr + 1]; >+ } >+ } >+ } >+ >+ public void endVisit(Block node) { >+ this.blockDepth--; >+ if(this.blockDepth <= 0) { >+ flagNodeWithInsertedTokens(); >+ } >+ super.endVisit(node); >+ } >+ >+ >+ >+ public boolean visit(Block node) { >+ boolean visitChildren = super.visit(node); >+ this.blockDepth++; >+ return visitChildren; > } > > protected boolean visitNode(ASTNode node) { >- return checkAndTagAsMalformed(node); >+ if(this.blockDepth > 0) { >+ int start = node.getStartPosition(); >+ int end = start + node.getLength() - 1; >+ >+ // continue to visit the node only if it contains tokens modifications >+ >+ if(this.insertedTokensFlagged != null) { >+ for (int i = 0; i < this.insertedTokensFlagged.length; i++) { >+ if(this.insertedTokensPosition[i] >= start && >+ this.insertedTokensPosition[i] <= end) { >+ return true; >+ } >+ } >+ } >+ >+ if(this.removedTokensFlagged != null) { >+ for (int i = 0; i <= this.data.removedTokensPtr; i++) { >+ if(this.data.removedTokensStart[i] >= start && >+ this.data.removedTokensEnd[i] <= end) { >+ return true; >+ } >+ } >+ } >+ >+ if(this.replacedTokensFlagged != null) { >+ for (int i = 0; i <= this.data.removedTokensPtr; i++) { >+ if(this.data.replacedTokensStart[i] >= start && >+ this.data.replacedTokensEnd[i] <= end) { >+ return true; >+ } >+ } >+ } >+ >+ return false; >+ } >+ return true; >+ } >+ >+ protected void endVisitNode(ASTNode node) { >+ int start = node.getStartPosition(); >+ int end = start + node.getLength() - 1; >+ >+ // is inside diet part of the ast >+ if(this.blockDepth < 1) { >+ if(this.markIncludedProblems(start, end)) { >+ node.setFlags(node.getFlags() | ASTNode.RECOVERED); >+ } >+ } else { >+ this.markIncludedProblems(start, end); >+ >+ if(this.insertedTokensFlagged != null) { >+ if(this.lastEnd != end) { >+ flagNodeWithInsertedTokens(); >+ } >+ this.stack.add(node); >+ } >+ >+ if(this.removedTokensFlagged != null) { >+ for (int i = 0; i <= this.data.removedTokensPtr; i++) { >+ if(!this.removedTokensFlagged[i] && >+ this.data.removedTokensStart[i] >= start && >+ this.data.removedTokensEnd[i] <= end) { >+ node.setFlags(node.getFlags() | ASTNode.RECOVERED); >+ this.removedTokensFlagged[i] = true; >+ } >+ } >+ } >+ >+ if(this.replacedTokensFlagged != null) { >+ for (int i = 0; i <= this.data.replacedTokensPtr; i++) { >+ if(!this.replacedTokensFlagged[i] && >+ this.data.replacedTokensStart[i] >= start && >+ this.data.replacedTokensEnd[i] <= end) { >+ node.setFlags(node.getFlags() | ASTNode.RECOVERED); >+ this.replacedTokensFlagged[i] = true; >+ } >+ } >+ } >+ } >+ this.lastEnd = end; > } > >- private boolean checkAndTagAsMalformed(ASTNode node) { >- boolean tagWithErrors = false; >- search: for (int i = 0, max = this.problems.length; i < max; i++) { >+ private void flagNodeWithInsertedTokens() { >+ if(this.insertedTokensKind != null && this.insertedTokensKind.length > 0) { >+ int s = this.stack.size(); >+ for (int i = s - 1; i > -1; i--) { >+ flagNodesWithInsertedTokensAtEnd((ASTNode)this.stack.get(i)); >+ } >+ for (int i = 0; i < s; i++) { >+ flagNodesWithInsertedTokensInside((ASTNode)this.stack.get(i)); >+ } >+ this.stack = new Vector(); >+ } >+ } >+ >+ private boolean flagNodesWithInsertedTokensAtEnd(ASTNode node) { >+ int[] expectedEndingToken = this.endingTokens.get(node.getClass()); >+ if (expectedEndingToken != null) { >+ int start = node.getStartPosition(); >+ int end = start + node.getLength() - 1; >+ >+ boolean flagParent = false; >+ done : for (int i = this.insertedTokensKind.length - 1; i > -1 ; i--) { >+ if(!this.insertedTokensFlagged[i] && >+ this.insertedTokensPosition[i] == end){ >+ this.insertedTokensFlagged[i] = true; >+ for (int j = 0; j < expectedEndingToken.length; j++) { >+ if(expectedEndingToken[j] == this.insertedTokensKind[i]) { >+ node.setFlags(node.getFlags() | ASTNode.RECOVERED); >+ break done; >+ } >+ } >+ flagParent = true; >+ } >+ } >+ >+ if(flagParent) { >+ ASTNode parent = node.getParent(); >+ while (parent != null) { >+ parent.setFlags(node.getFlags() | ASTNode.RECOVERED); >+ if((parent.getStartPosition() + parent.getLength() - 1) != end) { >+ parent = null; >+ } else { >+ parent = parent.getParent(); >+ } >+ } >+ } >+ } >+ return true; >+ } >+ >+ private boolean flagNodesWithInsertedTokensInside(ASTNode node) { >+ int start = node.getStartPosition(); >+ int end = start + node.getLength() - 1; >+ for (int i = 0; i < this.insertedTokensKind.length; i++) { >+ if(!this.insertedTokensFlagged[i] && >+ start <= this.insertedTokensPosition[i] && >+ this.insertedTokensPosition[i] < end){ >+ node.setFlags(node.getFlags() | ASTNode.RECOVERED); >+ this.insertedTokensFlagged[i] = true; >+ } >+ } >+ return true; >+ } >+ >+ private boolean markIncludedProblems(int start, int end) { >+ boolean foundProblems = false; >+ next: for (int i = 0, max = this.problems.length; i < max; i++) { > IProblem problem = this.problems[i]; >+ >+ if(this.usedOrIrrelevantProblems[i]) continue next; >+ > switch(problem.getID()) { > case IProblem.ParsingErrorOnKeywordNoSuggestion : > case IProblem.ParsingErrorOnKeyword : >@@ -64,18 +319,19 @@ > case IProblem.InvalidDigit : > break; > default: >- continue search; >+ this.usedOrIrrelevantProblems[i] = true; >+ continue next; >+ > } >+ > int problemStart = problem.getSourceStart(); > int problemEnd = problem.getSourceEnd(); >- int start = node.getStartPosition(); >- int end = start + node.getLength(); > if ((start <= problemStart) && (problemStart <= end) || > (start <= problemEnd) && (problemEnd <= end)) { >- node.setFlags(node.getFlags() | ASTNode.RECOVERED); >- tagWithErrors = true; >+ this.usedOrIrrelevantProblems[i] = true; >+ foundProblems = true; > } > } >- return tagWithErrors; >+ return foundProblems; > } > } >Index: dom/org/eclipse/jdt/core/dom/ASTConverter.java >=================================================================== >RCS file: /home/eclipse/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java,v >retrieving revision 1.228 >diff -u -r1.228 ASTConverter.java >--- dom/org/eclipse/jdt/core/dom/ASTConverter.java 6 Feb 2006 16:50:05 -0000 1.228 >+++ dom/org/eclipse/jdt/core/dom/ASTConverter.java 8 Feb 2006 11:49:28 -0000 >@@ -114,7 +114,7 @@ > } > } > } >- if(this.scanner instanceof RecoveryScanner && ((RecoveryScanner)this.scanner).isFakeTokenInserted()) { >+ if(this.scanner instanceof RecoveryScanner && ((RecoveryScanner)this.scanner).isInsertedToken()) { > expression.sourceEnd = this.scanner.startPosition; > } else { > expression.sourceEnd = this.scanner.startPosition - 1; >@@ -1196,7 +1196,8 @@ > > public CompilationUnit convert(org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration unit, char[] source) { > if(unit.compilationResult.recoveryScannerData != null) { >- this.scanner = new RecoveryScanner(this.scanner, unit.compilationResult.recoveryScannerData.removeUnused()); >+ RecoveryScanner recoveryScanner = new RecoveryScanner(this.scanner, unit.compilationResult.recoveryScannerData.removeUnused()); >+ this.scanner = recoveryScanner; > this.docParser.scanner = this.scanner; > } > this.compilationUnitSource = source; >@@ -1257,7 +1258,8 @@ > } > ASTSyntaxErrorPropagator syntaxErrorPropagator = new ASTSyntaxErrorPropagator(resizedProblems); > compilationUnit.accept(syntaxErrorPropagator); >- ASTRecoveryPropagator recoveryPropagator = new ASTRecoveryPropagator(resizedProblems); >+ ASTRecoveryPropagator recoveryPropagator = >+ new ASTRecoveryPropagator(resizedProblems, unit.compilationResult.recoveryScannerData); > compilationUnit.accept(recoveryPropagator); > compilationUnit.setProblems(resizedProblems); > } >@@ -4125,13 +4127,13 @@ > balance --; > break; > case TerminalTokens.TokenNameCOMMA : >- if(this.scanner instanceof RecoveryScanner && ((RecoveryScanner)this.scanner).isFakeTokenInserted()) { >+ if(this.scanner instanceof RecoveryScanner && ((RecoveryScanner)this.scanner).isInsertedToken()) { > return this.scanner.startPosition; > } > if (balance == 0) return this.scanner.startPosition - 1; > break; > case TerminalTokens.TokenNameSEMICOLON : >- if(this.scanner instanceof RecoveryScanner && ((RecoveryScanner)this.scanner).isFakeTokenInserted()) { >+ if(this.scanner instanceof RecoveryScanner && ((RecoveryScanner)this.scanner).isInsertedToken()) { > return this.scanner.startPosition; > } > return this.scanner.startPosition - 1; >Index: model/org/eclipse/jdt/core/ICompilationUnit.java >=================================================================== >RCS file: /home/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/core/ICompilationUnit.java,v >retrieving revision 1.54 >diff -u -r1.54 ICompilationUnit.java >--- model/org/eclipse/jdt/core/ICompilationUnit.java 23 Jan 2006 10:08:24 -0000 1.54 >+++ model/org/eclipse/jdt/core/ICompilationUnit.java 8 Feb 2006 11:49:30 -0000 >@@ -512,6 +512,11 @@ > * creation of the DOM AST was not requested, or if the requested level of AST > * API is not supported, or if the working copy was already consistent. > * </p> >+ * >+ * <p> >+ * The statement recovery is disable if this method is use. To recover statements with syntax >+ * errors {@link #reconcile(int, boolean, boolean, WorkingCopyOwner, IProgressMonitor)} must be use. >+ * </p> > * > * @param astLevel either {@link #NO_AST} if no AST is wanted, > * or the {@linkplain AST#newAST(int) AST API level} of the AST if one is wanted >Index: compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java >=================================================================== >RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java,v >retrieving revision 1.337 >diff -u -r1.337 Parser.java >--- compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java 6 Feb 2006 14:13:54 -0000 1.337 >+++ compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java 8 Feb 2006 11:49:24 -0000 >@@ -2654,11 +2654,32 @@ > } > protected void consumeEmptyStatement() { > // EmptyStatement ::= ';' >- if (this.scanner.source[this.endStatementPosition] == ';') { >+ char[] source = this.scanner.source; >+ if (source[this.endStatementPosition] == ';') { > pushOnAstStack(new EmptyStatement(this.endStatementPosition, this.endStatementPosition)); > } else { >- // we have a Unicode for the ';' (/u003B) >- pushOnAstStack(new EmptyStatement(this.endStatementPosition - 5, this.endStatementPosition)); >+ if(source.length > 5) { >+ int c1 = 0, c2 = 0, c3 = 0, c4 = 0; >+ int pos = this.endStatementPosition - 4; >+ while (source[pos] == 'u') { >+ pos--; >+ } >+ if (source[pos] == '\\' && >+ !((c1 = Character.getNumericValue(source[this.endStatementPosition - 3])) > 15 >+ || c1 < 0 >+ || (c2 = Character.getNumericValue(source[this.endStatementPosition - 2])) > 15 >+ || c2 < 0 >+ || (c3 = Character.getNumericValue(source[this.endStatementPosition - 1])) > 15 >+ || c3 < 0 >+ || (c4 = Character.getNumericValue(source[this.endStatementPosition])) > 15 >+ || c4 < 0) && >+ ((char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4)) == ';'){ >+ // we have a Unicode for the ';' (/u003B) >+ pushOnAstStack(new EmptyStatement(pos, this.endStatementPosition)); >+ return; >+ } >+ } >+ pushOnAstStack(new EmptyStatement(this.endStatementPosition, this.endStatementPosition)); > } > } > protected void consumeEmptySwitchBlock() { >Index: compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.java >=================================================================== >RCS file: /home/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.java,v >retrieving revision 1.4 >diff -u -r1.4 RecoveryScanner.java >--- compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.java 20 Jan 2006 14:07:16 -0000 1.4 >+++ compiler/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.java 8 Feb 2006 11:49:24 -0000 >@@ -21,6 +21,7 @@ > private int pendingTokensPtr = -1; > private char[] fakeTokenSource = null; > private boolean isInserted = true; >+ private boolean precededByRemoved = false; > private int skipNextInsertedTokens = -1; > > public boolean record = true; >@@ -120,6 +121,7 @@ > } > > this.fakeTokenSource = null; >+ this.precededByRemoved = false; > > if(this.data.insertedTokens != null) { > for (int i = 0; i <= this.data.insertedTokensPtr; i++) { >@@ -128,6 +130,7 @@ > this.pendingTokens = this.data.insertedTokens[i]; > this.pendingTokensPtr = this.data.insertedTokens[i].length - 1; > this.fakeTokenSource = CharOperation.NO_CHAR; >+ this.isInserted = true; > this.startPosition = this.currentPosition - 1; > this.skipNextInsertedTokens = i; > return this.pendingTokens[this.pendingTokensPtr--]; >@@ -148,6 +151,7 @@ > this.pendingTokens = this.data.replacedTokens[i]; > this.pendingTokensPtr = this.data.replacedTokens[i].length - 1; > this.fakeTokenSource = CharOperation.NO_CHAR; >+ this.isInserted = false; > this.currentPosition = this.data.replacedTokensEnd[i] + 1; > return this.pendingTokens[this.pendingTokensPtr--]; > } >@@ -160,6 +164,7 @@ > this.data.removedTokensEnd[i] >= this.currentPosition - 1) { > this.data.removedTokenUsed[i] = true; > this.currentPosition = this.data.removedTokensEnd[i] + 1; >+ this.precededByRemoved = false; > return getNextToken(); > } > } >@@ -190,14 +195,18 @@ > return this.fakeTokenSource != null; > } > >- public boolean isFakeTokenInserted() { >+ public boolean isInsertedToken() { > return this.fakeTokenSource != null && this.isInserted; > } > >- public boolean isFakeTokenReplaced() { >+ public boolean isReplacedToken() { > return this.fakeTokenSource != null && !this.isInserted; > } > >+ public boolean isPrecededByRemovedToken() { >+ return this.precededByRemoved; >+ } >+ > public void setData(RecoveryScannerData data) { > if(data == null) { > this.data = new RecoveryScannerData(); >Index: compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObjectToIntArray.java >=================================================================== >RCS file: compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObjectToIntArray.java >diff -N compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObjectToIntArray.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ compiler/org/eclipse/jdt/internal/compiler/util/HashtableOfObjectToIntArray.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,147 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2005 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Eclipse Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/epl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.internal.compiler.util; >+ >+/** >+ * Hashtable of {Object --> int[] } >+ */ >+public final class HashtableOfObjectToIntArray implements Cloneable { >+ >+ // to avoid using Enumerations, walk the individual tables skipping nulls >+ public Object[] keyTable; >+ public int[][] valueTable; >+ >+ public int elementSize; // number of elements in the table >+ int threshold; >+ >+ public HashtableOfObjectToIntArray() { >+ this(13); >+ } >+ >+ public HashtableOfObjectToIntArray(int size) { >+ >+ this.elementSize = 0; >+ this.threshold = size; // size represents the expected number of elements >+ int extraRoom = (int) (size * 1.75f); >+ if (this.threshold == extraRoom) >+ extraRoom++; >+ this.keyTable = new Object[extraRoom]; >+ this.valueTable = new int[extraRoom][]; >+ } >+ >+ public Object clone() throws CloneNotSupportedException { >+ HashtableOfObjectToIntArray result = (HashtableOfObjectToIntArray) super.clone(); >+ result.elementSize = this.elementSize; >+ result.threshold = this.threshold; >+ >+ int length = this.keyTable.length; >+ result.keyTable = new Object[length]; >+ System.arraycopy(this.keyTable, 0, result.keyTable, 0, length); >+ >+ length = this.valueTable.length; >+ result.valueTable = new int[length][]; >+ System.arraycopy(this.valueTable, 0, result.valueTable, 0, length); >+ return result; >+ } >+ >+ public boolean containsKey(Object key) { >+ >+ int index = (key.hashCode()& 0x7FFFFFFF) % this.valueTable.length; >+ Object currentKey; >+ while ((currentKey = this.keyTable[index]) != null) { >+ if (currentKey.equals(key)) >+ return true; >+ index = (index + 1) % this.keyTable.length; >+ } >+ return false; >+ } >+ >+ public int[] get(Object key) { >+ >+ int index = (key.hashCode()& 0x7FFFFFFF) % this.valueTable.length; >+ Object currentKey; >+ while ((currentKey = this.keyTable[index]) != null) { >+ if (currentKey.equals(key)) >+ return this.valueTable[index]; >+ index = (index + 1) % this.keyTable.length; >+ } >+ return null; >+ } >+ >+ public void keysToArray(Object[] array) { >+ int index = 0; >+ for (int i=0, length=this.keyTable.length; i<length; i++) { >+ if (this.keyTable[i] != null) >+ array[index++] = this.keyTable[i]; >+ } >+ } >+ >+ public int[] put(Object key, int[] value) { >+ >+ int index = (key.hashCode()& 0x7FFFFFFF) % this.valueTable.length; >+ Object currentKey; >+ while ((currentKey = this.keyTable[index]) != null) { >+ if (currentKey.equals(key)) >+ return this.valueTable[index] = value; >+ index = (index + 1) % this.keyTable.length; >+ } >+ this.keyTable[index] = key; >+ this.valueTable[index] = value; >+ >+ // assumes the threshold is never equal to the size of the table >+ if (++elementSize > threshold) >+ rehash(); >+ return value; >+ } >+ >+ public int[] removeKey(Object key) { >+ >+ int index = (key.hashCode()& 0x7FFFFFFF) % this.valueTable.length; >+ Object currentKey; >+ while ((currentKey = this.keyTable[index]) != null) { >+ if (currentKey.equals(key)) { >+ int[] value = this.valueTable[index]; >+ elementSize--; >+ this.keyTable[index] = null; >+ rehash(); >+ return value; >+ } >+ index = (index + 1) % this.keyTable.length; >+ } >+ return null; >+ } >+ >+ private void rehash() { >+ >+ HashtableOfObjectToIntArray newHashtable = new HashtableOfObjectToIntArray(elementSize * 2); // double the number of expected elements >+ Object currentKey; >+ for (int i = this.keyTable.length; --i >= 0;) >+ if ((currentKey = this.keyTable[i]) != null) >+ newHashtable.put(currentKey, this.valueTable[i]); >+ >+ this.keyTable = newHashtable.keyTable; >+ this.valueTable = newHashtable.valueTable; >+ this.threshold = newHashtable.threshold; >+ } >+ >+ public int size() { >+ return elementSize; >+ } >+ >+ public String toString() { >+ String s = ""; //$NON-NLS-1$ >+ Object key; >+ for (int i = 0, length = this.keyTable.length; i < length; i++) >+ if ((key = this.keyTable[i]) != null) >+ s += key + " -> " + this.valueTable[i] + "\n"; //$NON-NLS-2$ //$NON-NLS-1$ >+ return s; >+ } >+} >#P org.eclipse.jdt.core.tests.model >Index: src/org/eclipse/jdt/core/tests/dom/ASTConverterRecoveryTest.java >=================================================================== >RCS file: /home/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/dom/ASTConverterRecoveryTest.java,v >retrieving revision 1.5 >diff -u -r1.5 ASTConverterRecoveryTest.java >--- src/org/eclipse/jdt/core/tests/dom/ASTConverterRecoveryTest.java 6 Feb 2006 14:14:23 -0000 1.5 >+++ src/org/eclipse/jdt/core/tests/dom/ASTConverterRecoveryTest.java 8 Feb 2006 11:49:34 -0000 >@@ -21,8 +21,10 @@ > import org.eclipse.jdt.core.dom.ArrayInitializer; > import org.eclipse.jdt.core.dom.Block; > import org.eclipse.jdt.core.dom.CompilationUnit; >+import org.eclipse.jdt.core.dom.EmptyStatement; > import org.eclipse.jdt.core.dom.Expression; > import org.eclipse.jdt.core.dom.ExpressionStatement; >+import org.eclipse.jdt.core.dom.ForStatement; > import org.eclipse.jdt.core.dom.ITypeBinding; > import org.eclipse.jdt.core.dom.MethodDeclaration; > import org.eclipse.jdt.core.dom.MethodInvocation; >@@ -32,6 +34,7 @@ > import org.eclipse.jdt.core.dom.StringLiteral; > import org.eclipse.jdt.core.dom.VariableDeclarationFragment; > import org.eclipse.jdt.core.dom.VariableDeclarationStatement; >+import org.eclipse.jdt.core.dom.VariableDeclarationExpression; > > public class ASTConverterRecoveryTest extends ConverterTestSetup { > public ASTConverterRecoveryTest(String name) { >@@ -352,4 +355,369 @@ > checkSourceRange(simpleName, ",", source); //$NON-NLS-1$ > > } >+ >+ // check RECOVERED flag (insert tokens) >+ public void test0006() throws JavaModelException { >+ this.workingCopies = new ICompilationUnit[1]; >+ this.workingCopies[0] = getWorkingCopy( >+ "/Converter/src/test/X.java", >+ "package test;\n"+ >+ "\n"+ >+ "public class X {\n"+ >+ " void foo() {\n"+ >+ " bar()\n"+ >+ " }\n"+ >+ "}\n"); >+ >+ char[] source = this.workingCopies[0].getSource().toCharArray(); >+ ASTNode result = runConversion(AST.JLS3, this.workingCopies[0], true, true); >+ >+ assertASTNodeEquals( >+ "package test;\n" + >+ "public class X {\n" + >+ " void foo(){\n" + >+ " bar();\n" + >+ " }\n" + >+ "}\n", >+ result); >+ >+ ASTNode node = getASTNode((CompilationUnit) result, 0, 0); >+ assertNotNull(node); >+ assertTrue("Not a method declaration", node.getNodeType() == ASTNode.METHOD_DECLARATION); //$NON-NLS-1$ >+ MethodDeclaration methodDeclaration = (MethodDeclaration) node; >+ assertTrue("Flag as RECOVERED", (methodDeclaration.getFlags() & ASTNode.RECOVERED) == 0); >+ Block block = methodDeclaration.getBody(); >+ assertTrue("Flag as RECOVERED", (block.getFlags() & ASTNode.RECOVERED) == 0); >+ List statements = block.statements(); >+ assertEquals("wrong size", 1, statements.size()); //$NON-NLS-1$ >+ Statement statement = (Statement) statements.get(0); >+ assertTrue("Not an expression statement", statement.getNodeType() == ASTNode.EXPRESSION_STATEMENT); //$NON-NLS-1$ >+ ExpressionStatement expressionStatement = (ExpressionStatement) statement; >+ checkSourceRange(expressionStatement, "bar()", source); //$NON-NLS-1$ >+ assertTrue("Not flag as RECOVERED", (expressionStatement.getFlags() & ASTNode.RECOVERED) != 0); >+ Expression expression = expressionStatement.getExpression(); >+ assertTrue("Not a method invocation", expression.getNodeType() == ASTNode.METHOD_INVOCATION); //$NON-NLS-1$ >+ MethodInvocation methodInvocation = (MethodInvocation)expression; >+ checkSourceRange(methodInvocation, "bar()", source); //$NON-NLS-1$ >+ assertTrue("Flag as RECOVERED", (methodInvocation.getFlags() & ASTNode.RECOVERED) == 0); >+ } >+ >+ // check RECOVERED flag (insert tokens) >+ public void test0007() throws JavaModelException { >+ this.workingCopies = new ICompilationUnit[1]; >+ this.workingCopies[0] = getWorkingCopy( >+ "/Converter/src/test/X.java", >+ "package test;\n"+ >+ "\n"+ >+ "public class X {\n"+ >+ " void foo() {\n"+ >+ " bar(baz()\n"+ >+ " }\n"+ >+ "}\n"); >+ >+ char[] source = this.workingCopies[0].getSource().toCharArray(); >+ ASTNode result = runConversion(AST.JLS3, this.workingCopies[0], true, true); >+ >+ assertASTNodeEquals( >+ "package test;\n" + >+ "public class X {\n" + >+ " void foo(){\n" + >+ " bar(baz());\n" + >+ " }\n" + >+ "}\n", >+ result); >+ >+ ASTNode node = getASTNode((CompilationUnit) result, 0, 0); >+ assertNotNull(node); >+ assertTrue("Not a method declaration", node.getNodeType() == ASTNode.METHOD_DECLARATION); //$NON-NLS-1$ >+ MethodDeclaration methodDeclaration = (MethodDeclaration) node; >+ assertTrue("Flag as RECOVERED", (methodDeclaration.getFlags() & ASTNode.RECOVERED) == 0); >+ Block block = methodDeclaration.getBody(); >+ assertTrue("Flag as RECOVERED", (block.getFlags() & ASTNode.RECOVERED) == 0); >+ List statements = block.statements(); >+ assertEquals("wrong size", 1, statements.size()); //$NON-NLS-1$ >+ Statement statement = (Statement) statements.get(0); >+ assertTrue("Not an expression statement", statement.getNodeType() == ASTNode.EXPRESSION_STATEMENT); //$NON-NLS-1$ >+ ExpressionStatement expressionStatement = (ExpressionStatement) statement; >+ checkSourceRange(expressionStatement, "bar(baz()", source); //$NON-NLS-1$ >+ assertTrue("Not flag as RECOVERED", (expressionStatement.getFlags() & ASTNode.RECOVERED) != 0); >+ Expression expression = expressionStatement.getExpression(); >+ assertTrue("Not a method invocation", expression.getNodeType() == ASTNode.METHOD_INVOCATION); //$NON-NLS-1$ >+ MethodInvocation methodInvocation = (MethodInvocation)expression; >+ checkSourceRange(methodInvocation, "bar(baz()", source); //$NON-NLS-1$ >+ assertTrue("Not flag as RECOVERED", (methodInvocation.getFlags() & ASTNode.RECOVERED) != 0); >+ List arguments = methodInvocation.arguments(); >+ assertEquals("wrong size", 1, arguments.size()); //$NON-NLS-1$ >+ Expression argument = (Expression) arguments.get(0); >+ assertTrue("Not a method invocation", argument.getNodeType() == ASTNode.METHOD_INVOCATION); //$NON-NLS-1$ >+ MethodInvocation methodInvocation2 = (MethodInvocation) argument; >+ checkSourceRange(methodInvocation2, "baz()", source); //$NON-NLS-1$ >+ assertTrue("Flag as RECOVERED", (methodInvocation2.getFlags() & ASTNode.RECOVERED) == 0); >+ } >+ >+ // check RECOVERED flag (insert tokens) >+ public void test0008() throws JavaModelException { >+ this.workingCopies = new ICompilationUnit[1]; >+ this.workingCopies[0] = getWorkingCopy( >+ "/Converter/src/test/X.java", >+ "package test;\n"+ >+ "\n"+ >+ "public class X {\n"+ >+ " void foo() {\n"+ >+ " for(int i\n"+ >+ " }\n"+ >+ "}\n"); >+ >+ char[] source = this.workingCopies[0].getSource().toCharArray(); >+ ASTNode result = runConversion(AST.JLS3, this.workingCopies[0], true, true); >+ >+ assertASTNodeEquals( >+ "package test;\n" + >+ "public class X {\n" + >+ " void foo(){\n" + >+ " for (int i; ; ) ;\n" + >+ " }\n" + >+ "}\n", >+ result); >+ >+ ASTNode node = getASTNode((CompilationUnit) result, 0, 0); >+ assertNotNull(node); >+ assertTrue("Not a method declaration", node.getNodeType() == ASTNode.METHOD_DECLARATION); //$NON-NLS-1$ >+ MethodDeclaration methodDeclaration = (MethodDeclaration) node; >+ assertTrue("Flag as RECOVERED", (methodDeclaration.getFlags() & ASTNode.RECOVERED) == 0); >+ Block block = methodDeclaration.getBody(); >+ assertTrue("Not flag as RECOVERED", (block.getFlags() & ASTNode.RECOVERED) != 0); >+ List statements = block.statements(); >+ assertEquals("wrong size", 1, statements.size()); //$NON-NLS-1$ >+ Statement statement = (Statement) statements.get(0); >+ assertTrue("Not a for statement", statement.getNodeType() == ASTNode.FOR_STATEMENT); //$NON-NLS-1$ >+ ForStatement forStatement = (ForStatement) statement; >+ checkSourceRange(forStatement, "for(int i", source); //$NON-NLS-1$ >+ assertTrue("Not flag as RECOVERED", (forStatement.getFlags() & ASTNode.RECOVERED) != 0); >+ List initializers = forStatement.initializers(); >+ assertEquals("wrong size", 1, statements.size()); //$NON-NLS-1$ >+ Expression expression = (Expression)initializers.get(0); >+ assertTrue("Not a method invocation", expression.getNodeType() == ASTNode.VARIABLE_DECLARATION_EXPRESSION); //$NON-NLS-1$ >+ VariableDeclarationExpression variableDeclarationExpression = (VariableDeclarationExpression)expression; >+ checkSourceRange(variableDeclarationExpression, "int i", source); //$NON-NLS-1$ >+ assertTrue("Not flag as RECOVERED", (variableDeclarationExpression.getFlags() & ASTNode.RECOVERED) != 0); >+ List fragments = variableDeclarationExpression.fragments(); >+ assertEquals("wrong size", 1, fragments.size()); //$NON-NLS-1$ >+ VariableDeclarationFragment fragment = (VariableDeclarationFragment)fragments.get(0); >+ checkSourceRange(fragment, "i", source); //$NON-NLS-1$ >+ assertTrue("Not flag as RECOVERED", (fragment.getFlags() & ASTNode.RECOVERED) != 0); >+ SimpleName name = fragment.getName(); >+ checkSourceRange(name, "i", source); //$NON-NLS-1$ >+ assertTrue("Flag as RECOVERED", (name.getFlags() & ASTNode.RECOVERED) == 0); >+ Statement statement2 = forStatement.getBody(); >+ assertTrue("Not an empty statement", statement2.getNodeType() == ASTNode.EMPTY_STATEMENT); //$NON-NLS-1$ >+ EmptyStatement emptyStatement = (EmptyStatement)statement2; >+ checkSourceRange(emptyStatement, "i", source); //$NON-NLS-1$ >+ assertTrue("Not flag as RECOVERED", (emptyStatement.getFlags() & ASTNode.RECOVERED) != 0); >+ } >+ >+ // check RECOVERED flag (remove tokens) >+ public void test0009() throws JavaModelException { >+ this.workingCopies = new ICompilationUnit[1]; >+ this.workingCopies[0] = getWorkingCopy( >+ "/Converter/src/test/X.java", >+ "package test;\n"+ >+ "\n"+ >+ "public class X {\n"+ >+ " void foo() {\n"+ >+ " bar(baz());#\n"+ >+ " }\n"+ >+ "}\n"); >+ >+ char[] source = this.workingCopies[0].getSource().toCharArray(); >+ ASTNode result = runConversion(AST.JLS3, this.workingCopies[0], true, true); >+ >+ assertASTNodeEquals( >+ "package test;\n" + >+ "public class X {\n" + >+ " void foo(){\n" + >+ " bar(baz());\n" + >+ " }\n" + >+ "}\n", >+ result); >+ >+ ASTNode node = getASTNode((CompilationUnit) result, 0, 0); >+ assertNotNull(node); >+ assertTrue("Not a method declaration", node.getNodeType() == ASTNode.METHOD_DECLARATION); //$NON-NLS-1$ >+ MethodDeclaration methodDeclaration = (MethodDeclaration) node; >+ assertTrue("Flag as RECOVERED", (methodDeclaration.getFlags() & ASTNode.RECOVERED) == 0); >+ Block block = methodDeclaration.getBody(); >+ assertTrue("Not flag as RECOVERED", (block.getFlags() & ASTNode.RECOVERED) != 0); >+ List statements = block.statements(); >+ assertEquals("wrong size", 1, statements.size()); //$NON-NLS-1$ >+ Statement statement = (Statement) statements.get(0); >+ assertTrue("Not an expression statement", statement.getNodeType() == ASTNode.EXPRESSION_STATEMENT); //$NON-NLS-1$ >+ ExpressionStatement expressionStatement = (ExpressionStatement) statement; >+ checkSourceRange(expressionStatement, "bar(baz());", source); //$NON-NLS-1$ >+ assertTrue("Flag as RECOVERED", (expressionStatement.getFlags() & ASTNode.RECOVERED) == 0); >+ Expression expression = expressionStatement.getExpression(); >+ assertTrue("Not a method invocation", expression.getNodeType() == ASTNode.METHOD_INVOCATION); //$NON-NLS-1$ >+ MethodInvocation methodInvocation = (MethodInvocation)expression; >+ checkSourceRange(methodInvocation, "bar(baz())", source); //$NON-NLS-1$ >+ assertTrue("Flag as RECOVERED", (methodInvocation.getFlags() & ASTNode.RECOVERED) == 0); >+ List arguments = methodInvocation.arguments(); >+ assertEquals("wrong size", 1, arguments.size()); //$NON-NLS-1$ >+ Expression argument = (Expression) arguments.get(0); >+ assertTrue("Not a method invocation", argument.getNodeType() == ASTNode.METHOD_INVOCATION); //$NON-NLS-1$ >+ MethodInvocation methodInvocation2 = (MethodInvocation) argument; >+ checkSourceRange(methodInvocation2, "baz()", source); //$NON-NLS-1$ >+ assertTrue("Flag as RECOVERED", (methodInvocation2.getFlags() & ASTNode.RECOVERED) == 0); >+ } >+ >+ // check RECOVERED flag (remove tokens) >+ public void test0010() throws JavaModelException { >+ this.workingCopies = new ICompilationUnit[1]; >+ this.workingCopies[0] = getWorkingCopy( >+ "/Converter/src/test/X.java", >+ "package test;\n"+ >+ "\n"+ >+ "public class X {\n"+ >+ " void foo() {\n"+ >+ " bar(baz())#;\n"+ >+ " }\n"+ >+ "}\n"); >+ >+ char[] source = this.workingCopies[0].getSource().toCharArray(); >+ ASTNode result = runConversion(AST.JLS3, this.workingCopies[0], true, true); >+ >+ assertASTNodeEquals( >+ "package test;\n" + >+ "public class X {\n" + >+ " void foo(){\n" + >+ " bar(baz());\n" + >+ " }\n" + >+ "}\n", >+ result); >+ >+ ASTNode node = getASTNode((CompilationUnit) result, 0, 0); >+ assertNotNull(node); >+ assertTrue("Not a method declaration", node.getNodeType() == ASTNode.METHOD_DECLARATION); //$NON-NLS-1$ >+ MethodDeclaration methodDeclaration = (MethodDeclaration) node; >+ assertTrue("Flag as RECOVERED", (methodDeclaration.getFlags() & ASTNode.RECOVERED) == 0); >+ Block block = methodDeclaration.getBody(); >+ assertTrue("Flag as RECOVERED", (block.getFlags() & ASTNode.RECOVERED) == 0); >+ List statements = block.statements(); >+ assertEquals("wrong size", 1, statements.size()); //$NON-NLS-1$ >+ Statement statement = (Statement) statements.get(0); >+ assertTrue("Not an expression statement", statement.getNodeType() == ASTNode.EXPRESSION_STATEMENT); //$NON-NLS-1$ >+ ExpressionStatement expressionStatement = (ExpressionStatement) statement; >+ checkSourceRange(expressionStatement, "bar(baz())#;", source); //$NON-NLS-1$ >+ assertTrue("Not flag as RECOVERED", (expressionStatement.getFlags() & ASTNode.RECOVERED) != 0); >+ Expression expression = expressionStatement.getExpression(); >+ assertTrue("Not a method invocation", expression.getNodeType() == ASTNode.METHOD_INVOCATION); //$NON-NLS-1$ >+ MethodInvocation methodInvocation = (MethodInvocation)expression; >+ checkSourceRange(methodInvocation, "bar(baz())", source); //$NON-NLS-1$ >+ assertTrue("Flag as RECOVERED", (methodInvocation.getFlags() & ASTNode.RECOVERED) == 0); >+ List arguments = methodInvocation.arguments(); >+ assertEquals("wrong size", 1, arguments.size()); //$NON-NLS-1$ >+ Expression argument = (Expression) arguments.get(0); >+ assertTrue("Not a method invocation", argument.getNodeType() == ASTNode.METHOD_INVOCATION); //$NON-NLS-1$ >+ MethodInvocation methodInvocation2 = (MethodInvocation) argument; >+ checkSourceRange(methodInvocation2, "baz()", source); //$NON-NLS-1$ >+ assertTrue("Flag as RECOVERED", (methodInvocation2.getFlags() & ASTNode.RECOVERED) == 0); >+ } >+ >+ // check RECOVERED flag (remove tokens) >+ public void test0011() throws JavaModelException { >+ this.workingCopies = new ICompilationUnit[1]; >+ this.workingCopies[0] = getWorkingCopy( >+ "/Converter/src/test/X.java", >+ "package test;\n"+ >+ "\n"+ >+ "public class X {\n"+ >+ " void foo() {\n"+ >+ " bar(baz()#);\n"+ >+ " }\n"+ >+ "}\n"); >+ >+ char[] source = this.workingCopies[0].getSource().toCharArray(); >+ ASTNode result = runConversion(AST.JLS3, this.workingCopies[0], true, true); >+ >+ assertASTNodeEquals( >+ "package test;\n" + >+ "public class X {\n" + >+ " void foo(){\n" + >+ " bar(baz());\n" + >+ " }\n" + >+ "}\n", >+ result); >+ >+ ASTNode node = getASTNode((CompilationUnit) result, 0, 0); >+ assertNotNull(node); >+ assertTrue("Not a method declaration", node.getNodeType() == ASTNode.METHOD_DECLARATION); //$NON-NLS-1$ >+ MethodDeclaration methodDeclaration = (MethodDeclaration) node; >+ assertTrue("Flag as RECOVERED", (methodDeclaration.getFlags() & ASTNode.RECOVERED) == 0); >+ Block block = methodDeclaration.getBody(); >+ assertTrue("Flag as RECOVERED", (block.getFlags() & ASTNode.RECOVERED) == 0); >+ List statements = block.statements(); >+ assertEquals("wrong size", 1, statements.size()); //$NON-NLS-1$ >+ Statement statement = (Statement) statements.get(0); >+ assertTrue("Not an expression statement", statement.getNodeType() == ASTNode.EXPRESSION_STATEMENT); //$NON-NLS-1$ >+ ExpressionStatement expressionStatement = (ExpressionStatement) statement; >+ checkSourceRange(expressionStatement, "bar(baz()#);", source); //$NON-NLS-1$ >+ assertTrue("Flag as RECOVERED", (expressionStatement.getFlags() & ASTNode.RECOVERED) == 0); >+ Expression expression = expressionStatement.getExpression(); >+ assertTrue("Not a method invocation", expression.getNodeType() == ASTNode.METHOD_INVOCATION); //$NON-NLS-1$ >+ MethodInvocation methodInvocation = (MethodInvocation)expression; >+ checkSourceRange(methodInvocation, "bar(baz()#)", source); //$NON-NLS-1$ >+ assertTrue("Not flag as RECOVERED", (methodInvocation.getFlags() & ASTNode.RECOVERED) != 0); >+ List arguments = methodInvocation.arguments(); >+ assertEquals("wrong size", 1, arguments.size()); //$NON-NLS-1$ >+ Expression argument = (Expression) arguments.get(0); >+ assertTrue("Not a method invocation", argument.getNodeType() == ASTNode.METHOD_INVOCATION); //$NON-NLS-1$ >+ MethodInvocation methodInvocation2 = (MethodInvocation) argument; >+ checkSourceRange(methodInvocation2, "baz()", source); //$NON-NLS-1$ >+ assertTrue("Flag as RECOVERED", (methodInvocation2.getFlags() & ASTNode.RECOVERED) == 0); >+ } >+ >+ // check RECOVERED flag (insert tokens) >+ public void test0012() throws JavaModelException { >+ this.workingCopies = new ICompilationUnit[1]; >+ this.workingCopies[0] = getWorkingCopy( >+ "/Converter/src/test/X.java", >+ "package test;\n"+ >+ "\n"+ >+ "public class X {\n"+ >+ " void foo() {\n"+ >+ " bar()#\n"+ >+ " }\n"+ >+ "}\n"); >+ >+ char[] source = this.workingCopies[0].getSource().toCharArray(); >+ ASTNode result = runConversion(AST.JLS3, this.workingCopies[0], true, true); >+ >+ assertASTNodeEquals( >+ "package test;\n" + >+ "public class X {\n" + >+ " void foo(){\n" + >+ " bar();\n" + >+ " }\n" + >+ "}\n", >+ result); >+ >+ ASTNode node = getASTNode((CompilationUnit) result, 0, 0); >+ assertNotNull(node); >+ assertTrue("Not a method declaration", node.getNodeType() == ASTNode.METHOD_DECLARATION); //$NON-NLS-1$ >+ MethodDeclaration methodDeclaration = (MethodDeclaration) node; >+ assertTrue("Flag as RECOVERED", (methodDeclaration.getFlags() & ASTNode.RECOVERED) == 0); >+ Block block = methodDeclaration.getBody(); >+ assertTrue("Flag as RECOVERED", (block.getFlags() & ASTNode.RECOVERED) == 0); >+ List statements = block.statements(); >+ assertEquals("wrong size", 1, statements.size()); //$NON-NLS-1$ >+ Statement statement = (Statement) statements.get(0); >+ assertTrue("Not an expression statement", statement.getNodeType() == ASTNode.EXPRESSION_STATEMENT); //$NON-NLS-1$ >+ ExpressionStatement expressionStatement = (ExpressionStatement) statement; >+ checkSourceRange(expressionStatement, "bar()#", source); //$NON-NLS-1$ >+ assertTrue("Not flag as RECOVERED", (expressionStatement.getFlags() & ASTNode.RECOVERED) != 0); >+ Expression expression = expressionStatement.getExpression(); >+ assertTrue("Not a method invocation", expression.getNodeType() == ASTNode.METHOD_INVOCATION); //$NON-NLS-1$ >+ MethodInvocation methodInvocation = (MethodInvocation)expression; >+ checkSourceRange(methodInvocation, "bar()", source); //$NON-NLS-1$ >+ assertTrue("Flag as RECOVERED", (methodInvocation.getFlags() & ASTNode.RECOVERED) == 0); >+ } > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 42253
:
31884
|
33154
| 34338