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:
parent
1ecfef7421
commit
2b758858a2
8 changed files with 1694 additions and 34 deletions
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
File diff suppressed because it is too large
Load diff
|
@ -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);
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue