mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 14:42:11 +02:00
Bug 315185 - [hover] When hovering over a macro argument the expansion as a whole is evaluated
This commit is contained in:
parent
95e00954fb
commit
cea5f68197
1 changed files with 75 additions and 8 deletions
|
@ -13,13 +13,20 @@
|
||||||
package org.eclipse.cdt.debug.ui.editors;
|
package org.eclipse.cdt.debug.ui.editors;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorMacroExpansion;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
||||||
|
@ -200,7 +207,26 @@ public abstract class AbstractDebugTextHover implements ICEditorTextHover, IText
|
||||||
int length = hoverRegion.getLength();
|
int length = hoverRegion.getLength();
|
||||||
IASTName name= ast.getNodeSelector(null).findEnclosingName(offset, length);
|
IASTName name= ast.getNodeSelector(null).findEnclosingName(offset, length);
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
computeExpressionExtent(name, expressionPosition);
|
IASTImageLocation imageLoc = name.getImageLocation();
|
||||||
|
int kind = imageLoc.getLocationKind();
|
||||||
|
switch (kind) {
|
||||||
|
case IASTImageLocation.ARGUMENT_TO_MACRO_EXPANSION:
|
||||||
|
computeMacroArgumentExtent(expressionPosition, name);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (name.getParent() instanceof IASTPreprocessorMacroExpansion) {
|
||||||
|
// special case: macro expansion as expression
|
||||||
|
IASTNode node = ast.getNodeSelector(null).findEnclosingNodeInExpansion(imageLoc.getNodeOffset(), imageLoc.getNodeLength());
|
||||||
|
if (node instanceof IASTExpression) {
|
||||||
|
IASTFileLocation exprLoc = node.getFileLocation();
|
||||||
|
if (exprLoc.getNodeOffset() == imageLoc.getNodeOffset()) {
|
||||||
|
computeExpressionExtent(node, expressionPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
computeExpressionExtent(name, expressionPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// not a name, but might still be an expression (e.g. this)
|
// not a name, but might still be an expression (e.g. this)
|
||||||
IASTNode node = ast.getNodeSelector(null).findFirstContainedNode(offset, length);
|
IASTNode node = ast.getNodeSelector(null).findFirstContainedNode(offset, length);
|
||||||
|
@ -211,24 +237,65 @@ public abstract class AbstractDebugTextHover implements ICEditorTextHover, IText
|
||||||
}
|
}
|
||||||
return Status.OK_STATUS;
|
return Status.OK_STATUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void computeMacroArgumentExtent(final Position pos, IASTName name) {
|
||||||
|
IASTImageLocation imageLoc = name.getImageLocation();
|
||||||
|
int startOffset = imageLoc.getNodeOffset();
|
||||||
|
int endOffset = startOffset + imageLoc.getNodeLength();
|
||||||
|
// do some black magic to consider field reference expressions
|
||||||
|
IASTNode expr = name.getParent();
|
||||||
|
int macroOffset = name.getFileLocation().getNodeOffset();
|
||||||
|
if (expr instanceof IASTFieldReference) {
|
||||||
|
IASTExpression ownerExpr= ((IASTFieldReference) expr).getFieldOwner();
|
||||||
|
while (ownerExpr instanceof IASTFieldReference || ownerExpr instanceof IASTArraySubscriptExpression) {
|
||||||
|
if (ownerExpr instanceof IASTArraySubscriptExpression) {
|
||||||
|
ownerExpr = ((IASTArraySubscriptExpression) ownerExpr).getArrayExpression();
|
||||||
|
} else {
|
||||||
|
ownerExpr= ((IASTFieldReference) ownerExpr).getFieldOwner();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ownerExpr instanceof IASTIdExpression) {
|
||||||
|
IASTName ownerName = ((IASTIdExpression) ownerExpr).getName();
|
||||||
|
IASTImageLocation ownerImageLoc = ownerName.getImageLocation();
|
||||||
|
final int nameOffset= ownerImageLoc.getNodeOffset();
|
||||||
|
// offset should be inside macro expansion
|
||||||
|
if (nameOffset < startOffset && nameOffset > macroOffset) {
|
||||||
|
startOffset = nameOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ExpressionChecker checker = new ExpressionChecker();
|
||||||
|
if (checker.check(expr)) {
|
||||||
|
pos.offset = startOffset;
|
||||||
|
pos.length = endOffset - startOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
private void computeExpressionExtent(IASTNode node0, Position pos) {
|
private void computeExpressionExtent(IASTNode node0, Position pos) {
|
||||||
IASTNode node = node0;
|
IASTNode node = node0;
|
||||||
while (node != null && !(node instanceof IASTExpression) && !(node instanceof IASTDeclaration)) {
|
while (node != null && !(node instanceof IASTExpression) && !(node instanceof IASTDeclaration)) {
|
||||||
node = node.getParent();
|
node = node.getParent();
|
||||||
}
|
}
|
||||||
if (node instanceof IASTExpression) {
|
IASTNodeLocation loc = null;
|
||||||
|
if (node instanceof IASTExpression && !(node instanceof IASTIdExpression)) {
|
||||||
ExpressionChecker checker = new ExpressionChecker();
|
ExpressionChecker checker = new ExpressionChecker();
|
||||||
if (checker.check(node)) {
|
if (checker.check(node)) {
|
||||||
IASTNodeLocation loc = node.getFileLocation();
|
loc = node.getFileLocation();
|
||||||
pos.offset = loc.getNodeOffset();
|
|
||||||
pos.length = loc.getNodeLength();
|
|
||||||
}
|
}
|
||||||
} else if (node0 instanceof IASTName) {
|
} else if (node0 instanceof IASTName) {
|
||||||
// fallback: use simple name
|
// fallback: use simple name
|
||||||
IASTNodeLocation loc = node0.getFileLocation();
|
loc = ((IASTName) node0).getImageLocation();
|
||||||
pos.offset = loc.getNodeOffset();
|
if (loc == null) {
|
||||||
pos.length = loc.getNodeLength();
|
IASTNodeLocation[] locations = node0.getNodeLocations();
|
||||||
|
// avoid macro expansions
|
||||||
|
if (locations.length == 1 && !(locations[0] instanceof IASTMacroExpansionLocation)) {
|
||||||
|
loc = locations[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (loc != null) {
|
||||||
|
pos.offset = loc.getNodeOffset();
|
||||||
|
pos.length = loc.getNodeLength();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
job.setPriority(Job.SHORT);
|
job.setPriority(Job.SHORT);
|
||||||
|
|
Loading…
Add table
Reference in a new issue