Skip to main content
aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorSergey Prigogin2012-06-01 02:10:12 +0000
committerSergey Prigogin2012-06-01 02:12:33 +0000
commit2db77fef98934ec325c214cd39b863629b4ab686 (patch)
tree7590c7289996dd05921b1c80675cceb5fd3669f0 /core
parent31e3729d82024b8564621cae3950030aa5587446 (diff)
downloadorg.eclipse.cdt-2db77fef98934ec325c214cd39b863629b4ab686.tar.gz
org.eclipse.cdt-2db77fef98934ec325c214cd39b863629b4ab686.tar.xz
org.eclipse.cdt-2db77fef98934ec325c214cd39b863629b4ab686.zip
Bug 374155 - Source hover should display deduced type of "auto"
variables
Diffstat (limited to 'core')
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/c/hover/CSourceHover.java171
1 files changed, 125 insertions, 46 deletions
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/c/hover/CSourceHover.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/c/hover/CSourceHover.java
index 29d2d9ef515..abcc4421aa3 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/c/hover/CSourceHover.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/c/hover/CSourceHover.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2002, 2011 QNX Software Systems and others.
+ * Copyright (c) 2002, 2012 QNX Software Systems 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
@@ -8,6 +8,7 @@
* Contributors:
* QNX Software Systems - Initial API and implementation
* Anton Leherbauer (Wind River Systems)
+ * Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.text.c.hover;
@@ -47,12 +48,20 @@ import org.eclipse.ui.part.IWorkbenchPartOrientation;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.IPositionConverter;
import org.eclipse.cdt.core.dom.IName;
+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;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
+import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
+import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
@@ -62,9 +71,14 @@ import org.eclipse.cdt.core.dom.ast.IFunction;
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
+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.ICPPASTTypeId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
@@ -77,12 +91,14 @@ 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;
import org.eclipse.cdt.ui.IWorkingCopyManager;
import org.eclipse.cdt.ui.text.ICPartitions;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
import org.eclipse.cdt.internal.corext.util.Strings;
@@ -117,16 +133,19 @@ public class CSourceHover extends AbstractCEditorTextHover {
protected static class ComputeSourceRunnable implements ASTRunnable {
private final ITranslationUnit fTU;
private final IRegion fTextRegion;
+ private final String fSelection;
private final IProgressMonitor fMonitor;
private String fSource;
/**
- * @param tUnit
- * @param textRegion
+ * @param tUnit the translation unit
+ * @param textRegion the selected region
+ * @param selection the text of the selected region without
*/
- public ComputeSourceRunnable(ITranslationUnit tUnit, IRegion textRegion) {
+ public ComputeSourceRunnable(ITranslationUnit tUnit, IRegion textRegion, String selection) {
fTU= tUnit;
fTextRegion= textRegion;
+ fSelection = selection;
fMonitor= new NullProgressMonitor();
fSource= null;
}
@@ -138,40 +157,70 @@ public class CSourceHover extends AbstractCEditorTextHover {
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) {
if (ast != null) {
try {
- IASTName name= ast.getNodeSelector(null).findEnclosingName(fTextRegion.getOffset(), fTextRegion.getLength());
- if (name != null) {
- IBinding binding= name.resolveBinding();
- if (binding != null) {
- // Check for implicit names first, could be an implicit constructor call
- if (name.getParent() instanceof IASTImplicitNameOwner) {
- IASTImplicitNameOwner iastImplicitNameOwner = (IASTImplicitNameOwner) name.getParent();
- IASTName [] implicitNames = iastImplicitNameOwner.getImplicitNames();
- if (implicitNames.length == 1) {
- IBinding implicitNameBinding = implicitNames[0].resolveBinding();
- if (implicitNameBinding instanceof ICPPConstructor) {
- binding = implicitNameBinding;
- }
- }
+ 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() };
}
-
- if (binding instanceof IProblemBinding) {
- // Report problem as source comment
- if (DEBUG) {
- IProblemBinding problem= (IProblemBinding) binding;
- fSource= "/* Indexer Problem!\n" + //$NON-NLS-1$
- " * " + problem.getMessage() + //$NON-NLS-1$
- "\n */"; //$NON-NLS-1$
+ 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;
}
- } else if (binding instanceof IMacroBinding) {
- fSource= computeSourceForMacro(ast, name, binding);
- } else {
- fSource= computeSourceForBinding(ast, binding);
}
- if (fSource != null) {
- return Status.OK_STATUS;
+ if (type != null && !(type instanceof IProblemType))
+ fSource = ASTTypeUtil.getType(type, false);
+ }
+ } else {
+ IASTName name= nodeSelector.findEnclosingName(fTextRegion.getOffset(), fTextRegion.getLength());
+ if (name != null) {
+ IBinding binding= name.resolveBinding();
+ if (binding != null) {
+ // Check for implicit names first, could be an implicit constructor call.
+ if (name.getParent() instanceof IASTImplicitNameOwner) {
+ IASTImplicitNameOwner implicitNameOwner = (IASTImplicitNameOwner) name.getParent();
+ IASTName[] implicitNames = implicitNameOwner.getImplicitNames();
+ if (implicitNames.length == 1) {
+ IBinding implicitNameBinding = implicitNames[0].resolveBinding();
+ if (implicitNameBinding instanceof ICPPConstructor) {
+ binding = implicitNameBinding;
+ }
+ }
+ }
+
+ if (binding instanceof IProblemBinding) {
+ // Report problem as source comment.
+ if (DEBUG) {
+ IProblemBinding problem= (IProblemBinding) binding;
+ fSource= "/* Problem:\n" + //$NON-NLS-1$
+ " * " + problem.getMessage() + //$NON-NLS-1$
+ "\n */"; //$NON-NLS-1$
+ }
+ } else if (binding instanceof IMacroBinding) {
+ fSource= computeSourceForMacro(ast, name, binding);
+ } else {
+ fSource= computeSourceForBinding(ast, binding);
+ }
}
}
}
+ if (fSource != null) {
+ return Status.OK_STATUS;
+ }
} catch (CoreException e) {
return e.getStatus();
} catch (DOMException e) {
@@ -269,13 +318,13 @@ public class CSourceHover extends AbstractCEditorTextHover {
IPath location= Path.fromOSString(fileName);
LocationKind locationKind= LocationKind.LOCATION;
if (name instanceof IASTName && !name.isReference()) {
- IASTName astName= (IASTName)name;
+ IASTName astName= (IASTName) name;
if (astName.getTranslationUnit().getFilePath().equals(fileName)) {
int hoverOffset = fTextRegion.getOffset();
if (hoverOffset <= nodeOffset && nodeOffset < hoverOffset + fTextRegion.getLength() ||
hoverOffset >= nodeOffset && hoverOffset < nodeOffset + nodeLength) {
// Bug 359352 - don't show source if its the same we are hovering on.
- return null;
+ return computeHoverForDeclaration(astName);
}
if (fTU.getResource() != null) {
// Reuse editor buffer for names local to the translation unit
@@ -351,6 +400,37 @@ public class CSourceHover extends AbstractCEditorTextHover {
}
/**
+ * Computes the hover containing the deduced type for a declaration based on {@code auto}
+ * keyword.
+ *
+ * @param name the name of the declarator
+ * @return the hover text, if the declaration is based on {@code auto} keyword,
+ * otherwise {@code null}.
+ */
+ private String computeHoverForDeclaration(IASTName name) {
+ ICPPASTDeclarator declarator =
+ CPPVisitor.findAncestorWithType(name, ICPPASTDeclarator.class);
+ if (declarator == null)
+ return null;
+ IASTDeclaration declaration =
+ CPPVisitor.findAncestorWithType(declarator, IASTDeclaration.class);
+ IASTDeclSpecifier declSpec = null;
+ if (declaration instanceof IASTSimpleDeclaration) {
+ declSpec = ((IASTSimpleDeclaration) declaration).getDeclSpecifier();
+ } else if (declaration instanceof IASTParameterDeclaration) {
+ declSpec = ((IASTParameterDeclaration) declaration).getDeclSpecifier();
+ }
+ if (!(declSpec instanceof ICPPASTSimpleDeclSpecifier) ||
+ ((ICPPASTSimpleDeclSpecifier) declSpec).getType() != IASTSimpleDeclSpecifier.t_auto) {
+ return null;
+ }
+ IType type = CPPVisitor.createType(declarator);
+ if (type instanceof IProblemType)
+ return null;
+ return ASTTypeUtil.getType(type, false) + " " + name.getRawSignature(); //$NON-NLS-1$
+ }
+
+ /**
* Determine if the name is part of a KnR function definition.
* @param name
* @return <code>true</code> if the name is part of a KnR function
@@ -601,12 +681,12 @@ public class CSourceHover extends AbstractCEditorTextHover {
if (editor != null) {
IEditorInput input= editor.getEditorInput();
IWorkingCopyManager manager= CUIPlugin.getDefault().getWorkingCopyManager();
- IWorkingCopy copy = manager.getWorkingCopy(input);
+ IWorkingCopy workingCopy = manager.getWorkingCopy(input);
try {
- if (copy == null || !copy.isConsistent()) {
+ if (workingCopy == null || !workingCopy.isConsistent()) {
return null;
}
- } catch (CModelException exc) {
+ } catch (CModelException e) {
return null;
}
@@ -617,14 +697,13 @@ public class CSourceHover extends AbstractCEditorTextHover {
if (expression.isEmpty())
return null;
- // Before trying a search lets make sure that the user is not hovering over a keyword
- if (selectionIsKeyword(expression))
+ // 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))
return null;
- String source= null;
-
- // Try with the indexer
- source= searchInIndex(copy, hoverRegion);
+ // Try with the indexer.
+ String source= searchInIndex(workingCopy, hoverRegion, expression);
if (source == null || source.trim().isEmpty())
return null;
@@ -741,8 +820,8 @@ public class CSourceHover extends AbstractCEditorTextHover {
return source.substring(i);
}
- protected String searchInIndex(final ITranslationUnit tUnit, IRegion textRegion) {
- final ComputeSourceRunnable computer= new ComputeSourceRunnable(tUnit, textRegion);
+ protected String searchInIndex(final ITranslationUnit tUnit, IRegion textRegion, String selection) {
+ final ComputeSourceRunnable computer= new ComputeSourceRunnable(tUnit, textRegion, selection);
Job job= new Job(CHoverMessages.CSourceHover_jobTitle) {
@Override
protected IStatus run(IProgressMonitor monitor) {
@@ -764,7 +843,7 @@ public class CSourceHover extends AbstractCEditorTextHover {
job.schedule();
try {
job.join();
- } catch (InterruptedException exc) {
+ } catch (InterruptedException e) {
job.cancel();
return null;
}

Back to the top