1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-20 07:25:23 +02:00

Patch for Devin Steffler.

This patch includes:

- cleaned up style so that exceptions are not used to return a common result
- added some selection tests
- added a bandaid solution to bug 86993 (it does not fix the real problem though)
This commit is contained in:
John Camelon 2005-03-07 18:35:39 +00:00
parent 1ecfef7421
commit 2b758858a2
8 changed files with 1694 additions and 34 deletions

View file

@ -0,0 +1,36 @@
/*******************************************************************************
* Copyright (c) 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.internal.core.parser.ParserException;
/**
* @author dsteffle
*/
public class AST2SelectionParseBaseTest extends AST2BaseTest {
protected IASTNode parse(String code, ParserLanguage lang, int offset, int length) throws ParserException {
return parse(code, lang, false, false, offset, length);
}
protected IASTNode parse(String code, ParserLanguage lang, int offset, int length, boolean expectedToPass) throws ParserException {
return parse(code, lang, false, expectedToPass, offset, length);
}
protected IASTNode parse(String code, ParserLanguage lang, boolean useGNUExtensions, boolean expectNoProblems, int offset, int length) throws ParserException {
IASTTranslationUnit tu = parse(code, lang, useGNUExtensions, expectNoProblems);
return tu.selectNodeForLocation(tu.getFilePath(), offset, length);
}
}

View file

@ -0,0 +1,24 @@
/**********************************************************************
* Copyright (c) 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.core.dom.ast;
/**
* This interface is used to specify what the LocationMap has found when searching for IASTNodes
* corresponding to a selection from the preprocessor tree.
*
* @author dsteffle
*/
public interface IASTPreprocessorSelectionResult {
public IASTNode getSelectedNode();
public void setSelectedNode(IASTNode selectedNode);
public int getGlobalOffset();
public void setGlobalOffset(int globalOffset);
}

View file

@ -0,0 +1,47 @@
/**********************************************************************
* Copyright (c) 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorSelectionResult;
/**
* This class is used to wrap possible results from the ILocationResolver (when retrieving
* nodes from the preprocessor tree.
* @author dsteffle
*/
public class ASTPreprocessorSelectionResult implements IASTPreprocessorSelectionResult {
IASTNode selectedNode = null;
int globalOffset = 0;
public ASTPreprocessorSelectionResult(IASTNode node, int offset) {
this.selectedNode = node;
this.globalOffset = offset;
}
public IASTNode getSelectedNode() {
return selectedNode;
}
public void setSelectedNode(IASTNode selectedNode) {
this.selectedNode = selectedNode;
}
public int getGlobalOffset() {
return globalOffset;
}
public void setGlobalOffset(int globalOffset) {
this.globalOffset = globalOffset;
}
}

View file

@ -24,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorSelectionResult;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
import org.eclipse.cdt.core.dom.ast.IASTProblem; import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IASTStatement;
@ -341,16 +342,22 @@ public class CASTTranslationUnit extends CASTNode implements
public IASTNode selectNodeForLocation(String path, int realOffset, public IASTNode selectNodeForLocation(String path, int realOffset,
int realLength) { int realLength) {
IASTNode node = null; IASTNode node = null;
IASTPreprocessorSelectionResult result = null;
int globalOffset = 0;
try { try {
node = resolver.getPreprocessorNode(path, realOffset, realLength); result = resolver.getPreprocessorNode(path, realOffset, realLength);
} catch (InvalidPreprocessorNodeException ipne) { } catch (InvalidPreprocessorNodeException ipne) {
// extract global offset from the exception, use it to get the node globalOffset = ipne.getGlobalOffset();
// from the AST if it's valid }
int globalOffset = ipne.getGlobalOffset();
if (result != null && result.getSelectedNode() != null) {
node = result.getSelectedNode();
} else {
// use the globalOffset to get the node from the AST if it's valid
globalOffset = result == null ? globalOffset : result.getGlobalOffset();
if (globalOffset >= 0) { if (globalOffset >= 0) {
CFindNodeForOffsetAction nodeFinder = new CFindNodeForOffsetAction( CFindNodeForOffsetAction nodeFinder = new CFindNodeForOffsetAction(globalOffset, realLength);
globalOffset, realLength);
getVisitor().visitTranslationUnit(nodeFinder); getVisitor().visitTranslationUnit(nodeFinder);
node = nodeFinder.getNode(); node = nodeFinder.getNode();
} }

View file

@ -25,6 +25,7 @@ import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorSelectionResult;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
import org.eclipse.cdt.core.dom.ast.IASTProblem; import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IASTStatement;
@ -38,6 +39,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionTryBlockDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionTryBlockDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisitor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
@ -203,7 +205,8 @@ public class CPPASTTranslationUnit extends CPPASTNode implements
} }
// skip the rest of this node if the selection is outside of its bounds // skip the rest of this node if the selection is outside of its bounds
if (node instanceof ASTNode && // TODO take out fix below for bug 86993 check for: !(node instanceof ICPPASTLinkageSpecification)
if (node instanceof ASTNode && !(node instanceof ICPPASTLinkageSpecification) &&
offset > ((ASTNode)node).getOffset() + ((ASTNode)node).getLength()) offset > ((ASTNode)node).getOffset() + ((ASTNode)node).getLength())
return PROCESS_SKIP; return PROCESS_SKIP;
@ -215,7 +218,8 @@ public class CPPASTTranslationUnit extends CPPASTNode implements
*/ */
public int processDeclaration(IASTDeclaration declaration) { public int processDeclaration(IASTDeclaration declaration) {
// use declarations to determine if the search has gone past the offset (i.e. don't know the order the visitor visits the nodes) // use declarations to determine if the search has gone past the offset (i.e. don't know the order the visitor visits the nodes)
if (declaration instanceof ASTNode && ((ASTNode)declaration).getOffset() > offset) // TODO take out fix below for bug 86993 check for: !(declaration instanceof ICPPASTLinkageSpecification)
if (declaration instanceof ASTNode && !(declaration instanceof ICPPASTLinkageSpecification) && ((ASTNode)declaration).getOffset() > offset)
return PROCESS_ABORT; return PROCESS_ABORT;
return processNode(declaration); return processNode(declaration);
@ -332,12 +336,20 @@ public class CPPASTTranslationUnit extends CPPASTNode implements
*/ */
public IASTNode selectNodeForLocation(String path, int realOffset, int realLength) { public IASTNode selectNodeForLocation(String path, int realOffset, int realLength) {
IASTNode node = null; IASTNode node = null;
IASTPreprocessorSelectionResult result = null;
int globalOffset = 0;
try { try {
node = resolver.getPreprocessorNode(path, realOffset, realLength); result = resolver.getPreprocessorNode(path, realOffset, realLength);
} catch (InvalidPreprocessorNodeException ipne) { } catch (InvalidPreprocessorNodeException ipne) {
// extract global offset from the exception, use it to get the node from the AST if it's valid globalOffset = ipne.getGlobalOffset();
int globalOffset = ipne.getGlobalOffset(); }
if (result != null && result.getSelectedNode() != null) {
node = result.getSelectedNode();
} else {
// use the globalOffset to get the node from the AST if it's valid
globalOffset = result == null ? globalOffset : result.getGlobalOffset();
if (globalOffset >= 0) { if (globalOffset >= 0) {
CPPFindNodeForOffsetAction nodeFinder = new CPPFindNodeForOffsetAction(globalOffset, realLength); CPPFindNodeForOffsetAction nodeFinder = new CPPFindNodeForOffsetAction(globalOffset, realLength);
getVisitor().visitTranslationUnit(nodeFinder); getVisitor().visitTranslationUnit(nodeFinder);

View file

@ -10,10 +10,10 @@
**********************************************************************/ **********************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner2; package org.eclipse.cdt.internal.core.parser.scanner2;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorSelectionResult;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
import org.eclipse.cdt.core.dom.ast.IASTProblem; import org.eclipse.cdt.core.dom.ast.IASTProblem;
@ -36,6 +36,6 @@ public interface ILocationResolver {
public void cleanup(); public void cleanup();
public IASTNode getPreprocessorNode( String path, int offset, int length ) throws InvalidPreprocessorNodeException; public IASTPreprocessorSelectionResult getPreprocessorNode( String path, int offset, int length ) throws InvalidPreprocessorNodeException;
} }

View file

@ -32,6 +32,7 @@ import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorObjectStyleMacroDefinition; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorObjectStyleMacroDefinition;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorPragmaStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorPragmaStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorSelectionResult;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorUndefStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorUndefStatement;
import org.eclipse.cdt.core.dom.ast.IASTProblem; import org.eclipse.cdt.core.dom.ast.IASTProblem;
@ -40,6 +41,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.CodeReader;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTPreprocessorSelectionResult;
/** /**
* @author jcamelon * @author jcamelon
@ -1713,7 +1715,7 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog {
return foundContext; return foundContext;
} }
private IASTNode getPreprocessorNode(int globalOffset, int length, _Context startContext) throws InvalidPreprocessorNodeException { private IASTPreprocessorSelectionResult getPreprocessorNode(int globalOffset, int length, _Context startContext) throws InvalidPreprocessorNodeException {
IASTNode result = null; IASTNode result = null;
if (!(startContext instanceof _CompositeContext)) throw new InvalidPreprocessorNodeException(NOT_VALID_MACRO, globalOffset); if (!(startContext instanceof _CompositeContext)) throw new InvalidPreprocessorNodeException(NOT_VALID_MACRO, globalOffset);
List contexts = ((_CompositeContext)startContext).getSubContexts(); List contexts = ((_CompositeContext)startContext).getSubContexts();
@ -1747,17 +1749,15 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog {
} }
} }
if (result == null) return new ASTPreprocessorSelectionResult(result, globalOffset);
throw new InvalidPreprocessorNodeException(NOT_VALID_MACRO, globalOffset);
return result;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.scanner2.ILocationResolver#getPreprocessorNode(int, int) * @see org.eclipse.cdt.internal.core.parser.scanner2.ILocationResolver#getPreprocessorNode(int, int)
*/ */
public IASTNode getPreprocessorNode(String path, int offset, int length) throws InvalidPreprocessorNodeException { public IASTPreprocessorSelectionResult getPreprocessorNode(String path, int offset, int length) throws InvalidPreprocessorNodeException {
IASTNode result = null; IASTPreprocessorSelectionResult result = null;
int globalOffset = 0; int globalOffset = 0;
_Context foundContext = tu; _Context foundContext = tu;
@ -1776,9 +1776,6 @@ public class LocationMap implements ILocationResolver, IScannerPreprocessorLog {
result = getPreprocessorNode(globalOffset, length, foundContext); result = getPreprocessorNode(globalOffset, length, foundContext);
if (result == null)
throw new InvalidPreprocessorNodeException(NOT_VALID_MACRO, globalOffset);
return result; return result;
} }