mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-18 22:45:23 +02:00
Bug 520913 - hover / open declaration for decltype and typeof keywords
Change-Id: I15db25080aa476e3e0e6f9c6ce063e9bd1e2b2b4 Signed-off-by: Michael Woski <woskimi@yahoo.de>
This commit is contained in:
parent
11817c1c6a
commit
f546a833d6
6 changed files with 175 additions and 91 deletions
|
@ -110,6 +110,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDecltypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTEnumerationSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
|
||||
|
@ -130,6 +131,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTRangeBasedForStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeTemplateParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSwitchStatement;
|
||||
|
@ -139,6 +141,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeId;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
|
||||
|
@ -4449,4 +4452,53 @@ public class CPPSemantics {
|
|||
}
|
||||
return expressionType;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method performs type deduction for auto, decltype or typeof
|
||||
* declarations. This is used by {@code CSourceHover} and
|
||||
* {@code OpenDeclarationsJob} after checking (see
|
||||
* {@code SemanticUtil#isAutoOrDecltype(String)}) whether the selected text
|
||||
* equals any of the mentioned keywords.
|
||||
*
|
||||
* @param node
|
||||
* The decl-specifier or decltype-specifier in which the 'auto'
|
||||
* or 'decltype' occurs.
|
||||
* @return the deduced type or null
|
||||
*/
|
||||
public static IType resolveDecltypeOrAutoType(IASTNode node) {
|
||||
IType type = null;
|
||||
if (node instanceof ICPPASTDecltypeSpecifier) {
|
||||
type = ((ICPPASTDecltypeSpecifier) node).getDecltypeExpression().getExpressionType();
|
||||
}
|
||||
if (node instanceof ICPPASTSimpleDeclSpecifier) {
|
||||
int builtin = ((ICPPASTSimpleDeclSpecifier) node).getType();
|
||||
if (builtin == ICPPASTSimpleDeclSpecifier.t_auto || builtin == ICPPASTSimpleDeclSpecifier.t_typeof
|
||||
|| builtin == ICPPASTSimpleDeclSpecifier.t_decltype) {
|
||||
IASTNode parent = node.getParent();
|
||||
IASTDeclarator declarator = null;
|
||||
if (parent instanceof IASTSimpleDeclaration) {
|
||||
IASTDeclarator[] declarators = ((IASTSimpleDeclaration) parent).getDeclarators();
|
||||
// It's invalid for different declarators to deduce
|
||||
// different types with 'auto', so just get the type based on the
|
||||
// first declarator.
|
||||
if (declarators.length > 0)
|
||||
declarator = declarators[0];
|
||||
} else if (parent instanceof IASTParameterDeclaration
|
||||
&& builtin != ICPPASTSimpleDeclSpecifier.t_auto) {
|
||||
declarator = ((IASTParameterDeclaration) parent).getDeclarator();
|
||||
} else if (parent instanceof ICPPASTTypeId && builtin != ICPPASTSimpleDeclSpecifier.t_auto) {
|
||||
declarator = ((ICPPASTTypeId) parent).getAbstractDeclarator();
|
||||
} else if (parent instanceof ICPPASTFunctionDefinition) {
|
||||
declarator = ((ICPPASTFunctionDefinition) parent).getDeclarator();
|
||||
}
|
||||
if (declarator != null) {
|
||||
type = CPPVisitor.createType(declarator);
|
||||
if (type instanceof ICPPFunctionType) {
|
||||
type = ((ICPPFunctionType) type).getReturnType();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -739,6 +739,10 @@ public class SemanticUtil {
|
|||
return false;
|
||||
}
|
||||
|
||||
public static boolean isAutoOrDecltype(String code) {
|
||||
return (code.equals(Keywords.AUTO) || code.equals(Keywords.TYPEOF) || code.equals(Keywords.DECLTYPE));
|
||||
}
|
||||
|
||||
public static boolean isEmptyParameterList(IType[] parameters) {
|
||||
if (parameters.length == 0) {
|
||||
return true;
|
||||
|
|
|
@ -1311,4 +1311,31 @@ public class CPPSelectionTestsNoIndexer extends BaseSelectionTests {
|
|||
IASTNode target = testF3(file, offset);
|
||||
assertInstance(target, IASTName.class);
|
||||
}
|
||||
}
|
||||
|
||||
// struct Waldo {};
|
||||
// template<typename T>
|
||||
// struct Basket{};
|
||||
// Waldo find();
|
||||
// Waldo myFriend;
|
||||
// int main(decltype(myFriend) p) {
|
||||
// auto waldo = find();
|
||||
// Basket<typeof(waldo)> basket;
|
||||
// decltype(waldo) wuff;
|
||||
// }
|
||||
public void testDeclType_520913() throws Exception {
|
||||
String code = getAboveComment();
|
||||
IFile file = importFile("testBug520913.cpp", code);
|
||||
|
||||
int offset = code.indexOf("main") + 10;
|
||||
IASTNode target = testF3(file, offset);
|
||||
assertInstance(target, IASTName.class);
|
||||
|
||||
offset = code.indexOf("typeof");
|
||||
target = testF3(file, offset);
|
||||
assertInstance(target, IASTName.class);
|
||||
assertEquals("Waldo", ((IASTName) target).toString());
|
||||
|
||||
offset = code.indexOf("wuff") - 10;
|
||||
target = testF3(file, offset);
|
||||
assertInstance(target, IASTName.class);
|
||||
}}
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||
import org.eclipse.cdt.core.model.ICLanguageKeywords;
|
||||
import org.eclipse.cdt.core.model.ILanguage;
|
||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||
|
@ -41,6 +42,8 @@ import org.eclipse.cdt.ui.CUIPlugin;
|
|||
import org.eclipse.cdt.ui.ICModelBasedEditor;
|
||||
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||
import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
|
||||
import org.eclipse.cdt.internal.formatter.scanner.Scanner;
|
||||
import org.eclipse.cdt.internal.formatter.scanner.Token;
|
||||
|
@ -76,33 +79,10 @@ public class CElementHyperlinkDetector extends AbstractHyperlinkDetector {
|
|||
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) {
|
||||
if (ast == null)
|
||||
return Status.CANCEL_STATUS;
|
||||
final int offset= region.getOffset();
|
||||
final int length= Math.max(1, region.getLength());
|
||||
final IASTNodeSelector nodeSelector= ast.getNodeSelector(null);
|
||||
IASTNode linkASTNode = null;
|
||||
|
||||
IASTNode linkASTNode = getLinkASTNode(document, ast, region);
|
||||
|
||||
IASTNodeLocation linkLocation = null;
|
||||
|
||||
IASTName selectedName= nodeSelector.findEnclosingName(offset, length);
|
||||
if (selectedName != null) { // found a name
|
||||
// Prefer include statement over the include name
|
||||
if (selectedName.getParent() instanceof IASTPreprocessorIncludeStatement) {
|
||||
linkASTNode = selectedName.getParent();
|
||||
} else {
|
||||
linkASTNode = selectedName;
|
||||
}
|
||||
} else {
|
||||
final IASTNode implicit = nodeSelector.findEnclosingImplicitName(offset, length);
|
||||
if (implicit != null) {
|
||||
linkASTNode = implicit;
|
||||
} else {
|
||||
// Search for include statement
|
||||
final IASTNode cand= nodeSelector.findEnclosingNode(offset, length);
|
||||
if (cand instanceof IASTPreprocessorIncludeStatement) {
|
||||
linkASTNode = cand;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (linkASTNode != null) {
|
||||
if (linkASTNode instanceof IASTName) {
|
||||
IASTName astName = (IASTName) linkASTNode;
|
||||
|
@ -167,6 +147,55 @@ public class CElementHyperlinkDetector extends AbstractHyperlinkDetector {
|
|||
return new IHyperlink[] { new CElementHyperlink(hyperlinkRegion[0], openAction) };
|
||||
}
|
||||
|
||||
private static IASTNode getLinkASTNode(IDocument document, IASTTranslationUnit ast, IRegion region) {
|
||||
final int offset= region.getOffset();
|
||||
final int length= Math.max(1, region.getLength());
|
||||
|
||||
final IASTNodeSelector nodeSelector= ast.getNodeSelector(null);
|
||||
if (isOverAutoOrDecltype(document, offset)) {
|
||||
IASTNode node = nodeSelector.findEnclosingNode(offset, length);
|
||||
IASTTypeId enclosingTypeId = ASTQueries.findAncestorWithType(node, IASTTypeId.class);
|
||||
if (enclosingTypeId != null) {
|
||||
return enclosingTypeId;
|
||||
}
|
||||
}
|
||||
|
||||
IASTName selectedName= nodeSelector.findEnclosingName(offset, length);
|
||||
if (selectedName != null) { // found a name
|
||||
// Prefer include statement over the include name
|
||||
if (selectedName.getParent() instanceof IASTPreprocessorIncludeStatement) {
|
||||
return selectedName.getParent();
|
||||
} else {
|
||||
return selectedName;
|
||||
}
|
||||
} else {
|
||||
final IASTNode implicit = nodeSelector.findEnclosingImplicitName(offset, length);
|
||||
if (implicit != null) {
|
||||
return implicit;
|
||||
} else {
|
||||
// Search for include statement
|
||||
final IASTNode cand= nodeSelector.findEnclosingNode(offset, length);
|
||||
if (cand instanceof IASTPreprocessorIncludeStatement) {
|
||||
return cand;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isOverAutoOrDecltype(IDocument document, int offset) {
|
||||
try {
|
||||
IRegion wordRegion = CWordFinder.findWord(document, offset);
|
||||
if (wordRegion != null && wordRegion.getLength() > 0) {
|
||||
String word = document.get(wordRegion.getOffset(), wordRegion.getLength());
|
||||
return SemanticUtil.isAutoOrDecltype(word);
|
||||
}
|
||||
} catch (BadLocationException e) {
|
||||
// Fall through and return false.
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identifier at the given offset, or {@code null} if the there is no identifier
|
||||
* at the offset.
|
||||
|
@ -175,8 +204,10 @@ public class CElementHyperlinkDetector extends AbstractHyperlinkDetector {
|
|||
IRegion wordRegion= CWordFinder.findWord(document, offset);
|
||||
if (wordRegion != null && wordRegion.getLength() > 0) {
|
||||
String word = document.get(wordRegion.getOffset(), wordRegion.getLength());
|
||||
if (!Character.isDigit(word.charAt(0)) && !isLanguageKeyword(language, word)) {
|
||||
return wordRegion;
|
||||
if (!Character.isDigit(word.charAt(0))) {
|
||||
if (SemanticUtil.isAutoOrDecltype(word) || !isLanguageKeyword(language, word)) {
|
||||
return wordRegion;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -15,8 +15,8 @@ package org.eclipse.cdt.internal.ui.search.actions;
|
|||
import static java.lang.Math.max;
|
||||
import static java.lang.Math.min;
|
||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
|
||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
|
||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.PTR;
|
||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -63,7 +63,6 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
|
|||
import org.eclipse.cdt.core.dom.ast.IParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit;
|
||||
|
@ -101,6 +100,7 @@ import org.eclipse.cdt.ui.CUIPlugin;
|
|||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.HeuristicResolver;
|
||||
|
@ -246,13 +246,11 @@ class OpenDeclarationsJob extends Job implements ASTRunnable {
|
|||
|
||||
final IASTNodeSelector nodeSelector = ast.getNodeSelector(null);
|
||||
|
||||
IASTName sourceName= nodeSelector.findEnclosingName(selectionStart, selectionLength);
|
||||
IASTName sourceName = nodeSelector.findEnclosingName(selectionStart, selectionLength);
|
||||
IName[] implicitTargets = findImplicitTargets(ast, nodeSelector, selectionStart, selectionLength);
|
||||
if (sourceName == null) {
|
||||
if (implicitTargets.length > 0) {
|
||||
if (navigateViaCElements(fTranslationUnit.getCProject(), fIndex, implicitTargets))
|
||||
return Status.OK_STATUS;
|
||||
}
|
||||
if (sourceName == null || SemanticUtil.isAutoOrDecltype(fSelectedText)) {
|
||||
if (navigateViaCElements(fTranslationUnit.getCProject(), fIndex, implicitTargets))
|
||||
return Status.OK_STATUS;
|
||||
} else {
|
||||
boolean found= false;
|
||||
final IASTNode parent = sourceName.getParent();
|
||||
|
@ -479,28 +477,21 @@ class OpenDeclarationsJob extends Job implements ASTRunnable {
|
|||
definitions = ArrayUtil.addAll(definitions, declNames);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if (SemanticUtil.isAutoOrDecltype(fSelectedText)) {
|
||||
IASTNode enclosingNode = nodeSelector.findEnclosingNode(offset, length);
|
||||
if (enclosingNode instanceof ICPPASTSimpleDeclSpecifier) {
|
||||
if (((ICPPASTSimpleDeclSpecifier) enclosingNode).getType() == ICPPASTSimpleDeclSpecifier.t_auto) {
|
||||
if (enclosingNode.getParent() instanceof IASTSimpleDeclaration) {
|
||||
IASTDeclarator[] declarators = ((IASTSimpleDeclaration) enclosingNode.getParent()).getDeclarators();
|
||||
if (declarators.length > 0) {
|
||||
// It's invalid for different declarators to deduce different
|
||||
// types with 'auto', so just get the type based on the first
|
||||
// declarator.
|
||||
IType type = CPPVisitor.createType(declarators[0]);
|
||||
// Strip qualifiers, references, and pointers, but NOT
|
||||
// typedefs, since for typedefs we want to navigate to the
|
||||
// typedef declaration.
|
||||
type = SemanticUtil.getNestedType(type, CVTYPE | REF | PTR);
|
||||
if (type instanceof IBinding) {
|
||||
IName[] declNames = findDeclNames(ast, NameKind.REFERENCE, (IBinding) type);
|
||||
definitions = ArrayUtil.addAll(definitions, declNames);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
IType type = CPPSemantics.resolveDecltypeOrAutoType(enclosingNode);
|
||||
if (type instanceof ICPPUnknownType) {
|
||||
IType hType = HeuristicResolver.resolveUnknownType((ICPPUnknownType) type, enclosingNode);
|
||||
if (hType != null)
|
||||
type = hType;
|
||||
}
|
||||
// Strip qualifiers, references, and pointers, but NOT
|
||||
// typedefs, since for typedefs we want to refer to the
|
||||
// typedef declaration.
|
||||
type = SemanticUtil.getNestedType(type, CVTYPE | REF | PTR);
|
||||
if (type instanceof IBinding) {
|
||||
IName[] declNames = findDeclNames(ast, NameKind.REFERENCE, (IBinding) type);
|
||||
definitions = ArrayUtil.addAll(definitions, declNames);
|
||||
}
|
||||
}
|
||||
return ArrayUtil.trim(definitions);
|
||||
|
|
|
@ -53,7 +53,6 @@ import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
|
|||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||
|
@ -76,11 +75,9 @@ import org.eclipse.cdt.core.dom.ast.IProblemType;
|
|||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
||||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeId;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplateInstance;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
|
||||
|
@ -94,7 +91,6 @@ import org.eclipse.cdt.core.model.ILanguage;
|
|||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||
import org.eclipse.cdt.core.parser.KeywordSetKey;
|
||||
import org.eclipse.cdt.core.parser.Keywords;
|
||||
import org.eclipse.cdt.core.parser.ParserFactory;
|
||||
import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
|
@ -103,8 +99,12 @@ import org.eclipse.cdt.ui.text.ICPartitions;
|
|||
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.HeuristicResolver;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeOfDependentExpression;
|
||||
import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
|
||||
import org.eclipse.cdt.internal.corext.util.Strings;
|
||||
|
||||
|
@ -161,33 +161,12 @@ public class CSourceHover extends AbstractCEditorTextHover {
|
|||
if (ast != null) {
|
||||
try {
|
||||
IASTNodeSelector nodeSelector = ast.getNodeSelector(null);
|
||||
if (fSelection.equals(Keywords.AUTO)) {
|
||||
IASTNode node = nodeSelector.findEnclosingNode(fTextRegion.getOffset(), fTextRegion.getLength());
|
||||
if (node instanceof ICPPASTDeclSpecifier) {
|
||||
ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) node;
|
||||
IASTNode parent = declSpec.getParent();
|
||||
IASTDeclarator[] declarators = IASTDeclarator.EMPTY_DECLARATOR_ARRAY;
|
||||
if (parent instanceof IASTSimpleDeclaration) {
|
||||
declarators = ((IASTSimpleDeclaration) parent).getDeclarators();
|
||||
} else if (parent instanceof IASTParameterDeclaration) {
|
||||
declarators = new IASTDeclarator[] { ((IASTParameterDeclaration) parent).getDeclarator() };
|
||||
} else if (parent instanceof ICPPASTTypeId) {
|
||||
declarators = new IASTDeclarator[] { ((ICPPASTTypeId) parent).getAbstractDeclarator() };
|
||||
}
|
||||
IType type = null;
|
||||
for (IASTDeclarator declarator : declarators) {
|
||||
IType t = CPPVisitor.createType(declarator);
|
||||
if (type == null) {
|
||||
type = t;
|
||||
} else if (!type.isSameType(t)) {
|
||||
// Type varies between declarators - don't display anything.
|
||||
type = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (type != null && !(type instanceof IProblemType))
|
||||
fSource = ASTTypeUtil.getType(type, false);
|
||||
}
|
||||
if (SemanticUtil.isAutoOrDecltype(fSelection)) {
|
||||
IASTNode node = nodeSelector.findEnclosingNode(fTextRegion.getOffset(),
|
||||
fTextRegion.getLength());
|
||||
IType type = CPPSemantics.resolveDecltypeOrAutoType(node);
|
||||
if (type != null && !(type instanceof IProblemType))
|
||||
fSource = ASTTypeUtil.getType(type, false);
|
||||
} else {
|
||||
IASTName name= nodeSelector.findEnclosingName(fTextRegion.getOffset(), fTextRegion.getLength());
|
||||
if (name != null) {
|
||||
|
@ -742,8 +721,8 @@ public class CSourceHover extends AbstractCEditorTextHover {
|
|||
return null;
|
||||
|
||||
// Before trying a search lets make sure that the user is not hovering
|
||||
// over a keyword other than 'auto'.
|
||||
if (selectionIsKeyword(expression) && !expression.equals(Keywords.AUTO))
|
||||
// over a keyword other than 'auto', 'decltype' or 'typeof'.
|
||||
if (selectionIsKeyword(expression) && !SemanticUtil.isAutoOrDecltype(expression))
|
||||
return null;
|
||||
|
||||
// Try with the indexer.
|
||||
|
|
Loading…
Add table
Reference in a new issue