diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java index ccfb48c892e..91711bf6771 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java @@ -37,6 +37,7 @@ import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIfStatement; import org.eclipse.cdt.core.dom.ast.IASTLabelStatement; import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNullStatement; import org.eclipse.cdt.core.dom.ast.IASTProblem; @@ -64,7 +65,6 @@ import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.OffsetLimitReachedException; import org.eclipse.cdt.core.parser.ParseError; import org.eclipse.cdt.core.parser.ParserMode; -import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression; /** * @author jcamelon @@ -511,7 +511,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { IASTExpressionStatement exprStmt = createExpressionStatement(); exprStmt.setParent(result); exprStmt.setPropertyInParent(IASTCompoundStatement.NESTED_STATEMENT); - IASTIdExpression expr = new CPPASTIdExpression(); // Obviously need a factory + IASTIdExpression expr = createIdExpression(); exprStmt.setExpression(expr); expr.setParent(exprStmt); expr.setPropertyInParent(IASTExpressionStatement.EXPFRESSION); @@ -523,6 +523,24 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { if (completionNode == null) completionNode = new ASTCompletionNode(token); completionNode.addName(exprName); + + // Now the declaration statement + IASTDeclarationStatement declStmt = createDeclarationStatement(); + declStmt.setParent(result); + declStmt.setPropertyInParent(IASTCompoundStatement.NESTED_STATEMENT); + IASTSimpleDeclaration decl = createSimpleDeclaration(); + declStmt.setDeclaration(decl); + decl.setParent(declStmt); + decl.setPropertyInParent(IASTDeclarationStatement.DECLARATION); + IASTNamedTypeSpecifier declSpec = createNamedTypeSpecifier(); + decl.setDeclSpecifier(declSpec); + declSpec.setParent(decl); + declSpec.setPropertyInParent(IASTSimpleDeclaration.DECL_SPECIFIER); + IASTName declSpecName = createName(token); + declSpec.setName(declSpecName); + declSpecName.setParent(declSpec); + declSpecName.setPropertyInParent(IASTNamedTypeSpecifier.NAME); + completionNode.addName(declSpecName); } } @@ -1268,6 +1286,10 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { return !parsePassed; } + protected abstract IASTSimpleDeclaration createSimpleDeclaration(); + + protected abstract IASTNamedTypeSpecifier createNamedTypeSpecifier(); + /** * @return */ @@ -1333,6 +1355,11 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { */ protected abstract IASTIfStatement createIfStatement(); + /** + * @return + */ + protected abstract IASTIdExpression createIdExpression(); + /** * @return */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java index e27a06d68d8..39047e59ff3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java @@ -527,7 +527,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { /** * @return */ - protected CASTSimpleDeclaration createSimpleDeclaration() { + protected IASTSimpleDeclaration createSimpleDeclaration() { return new CASTSimpleDeclaration(); } @@ -1501,7 +1501,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { return elabSpec; } if (isIdentifier) { - ICASTTypedefNameSpecifier declSpec = createNamedTypeSpecifier(); + ICASTTypedefNameSpecifier declSpec = (ICASTTypedefNameSpecifier)createNamedTypeSpecifier(); declSpec.setConst(isConst); declSpec.setRestrict(isRestrict); declSpec.setVolatile(isVolatile); @@ -1545,7 +1545,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { /** * @return */ - protected ICASTTypedefNameSpecifier createNamedTypeSpecifier() { + protected IASTNamedTypeSpecifier createNamedTypeSpecifier() { return new CASTTypedefNameSpecifier(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index 09085f71f62..6e32b4e5e41 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -3233,7 +3233,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { return classSpec; } if (duple != null) { - ICPPASTNamedTypeSpecifier nameSpec = createNamedTypeSpecifier(); + ICPPASTNamedTypeSpecifier nameSpec = (ICPPASTNamedTypeSpecifier)createNamedTypeSpecifier(); nameSpec.setIsTypename(isTypename); IASTName name = createName(duple); nameSpec.setName(name); @@ -3307,7 +3307,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { /** * @return */ - protected ICPPASTNamedTypeSpecifier createNamedTypeSpecifier() { + protected IASTNamedTypeSpecifier createNamedTypeSpecifier() { return new CPPASTNamedTypeSpecifier(); } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/InternalASTServiceProvider.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/InternalASTServiceProvider.java index 2dd3967cb0a..3c68064b362 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/InternalASTServiceProvider.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/dom/InternalASTServiceProvider.java @@ -196,7 +196,7 @@ public class InternalASTServiceProvider implements IASTServiceProvider { else scannerExtensionConfiguration = C_GNU_SCANNER_EXTENSION; - IScanner scanner = new DOMScanner(reader, scanInfo, ParserMode.COMPLETE_PARSE, + IScanner scanner = new DOMScanner(reader, scanInfo, ParserMode.COMPLETION_PARSE, l, ParserFactory.createDefaultLogService(), scannerExtensionConfiguration, fileCreator); scanner.setContentAssistMode(offset); @@ -204,11 +204,11 @@ public class InternalASTServiceProvider implements IASTServiceProvider { // assume GCC ISourceCodeParser parser = null; if (l == ParserLanguage.C) - parser = new GNUCSourceParser(scanner, ParserMode.COMPLETE_PARSE, + parser = new GNUCSourceParser(scanner, ParserMode.COMPLETION_PARSE, ParserUtil.getParserLogService(), new GCCParserExtensionConfiguration()); else - parser = new GNUCPPSourceParser(scanner, ParserMode.COMPLETE_PARSE, + parser = new GNUCPPSourceParser(scanner, ParserMode.COMPLETION_PARSE, ParserUtil.getParserLogService(), new GPPParserExtensionConfiguration()); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/CCompletionProcessor2.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/CCompletionProcessor2.java index 15dedf0144c..5224772829a 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/CCompletionProcessor2.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/CCompletionProcessor2.java @@ -10,16 +10,21 @@ **********************************************************************/ package org.eclipse.cdt.internal.ui.text.contentassist; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import org.eclipse.cdt.core.dom.CDOM; import org.eclipse.cdt.core.dom.ICodeReaderFactory; import org.eclipse.cdt.core.dom.IASTServiceProvider.UnsupportedDialectException; import org.eclipse.cdt.core.dom.ast.ASTCompletionNode; +import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTName; -import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.model.IWorkingCopy; import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.ParserUtil; @@ -54,6 +59,7 @@ public class CCompletionProcessor2 implements IContentAssistProcessor { int offset) { errorMessage = null; try { + long startTime = System.currentTimeMillis(); IWorkingCopy workingCopy = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(editor.getEditorInput()); ASTCompletionNode completionNode = CDOM.getInstance().getCompletionNode( (IFile)workingCopy.getResource(), @@ -71,22 +77,30 @@ public class CCompletionProcessor2 implements IContentAssistProcessor { } } ); - IASTName[] names = completionNode.getNames(); - IASTTranslationUnit tu = names[0].getTranslationUnit(); - IBinding binding = names[0].resolveBinding(); + long stopTime = System.currentTimeMillis(); + System.out.println("Completion Parse: " + (stopTime - startTime) + "ms"); + int repLength = completionNode.getLength(); int repOffset = offset - repLength; + List proposals = new ArrayList(); - ICompletionProposal prop = createBindingCompletionProposal(binding, repOffset, repLength); - ICompletionProposal prop2 = createBindingCompletionProposal(binding, repOffset, repLength); + IASTName[] names = completionNode.getNames(); + for (int i = 0; i < names.length; ++i) { + IBinding binding = names[0].resolveBinding(); + + if (binding != null && !(binding instanceof IProblemBinding)) + proposals.add(createBindingCompletionProposal(binding, repOffset, repLength)); + } - return new ICompletionProposal[] { prop, prop2 }; + if (!proposals.isEmpty()) + return (ICompletionProposal[])proposals.toArray(new ICompletionProposal[proposals.size()]); } catch (UnsupportedDialectException e) { errorMessage = "Unsupported Dialect Exception"; } catch (Throwable e) { errorMessage = e.toString(); } + errorMessage = "No completions found"; return null; } @@ -132,8 +146,20 @@ public class CCompletionProcessor2 implements IContentAssistProcessor { private ICompletionProposal createBindingCompletionProposal(IBinding binding, int offset, int length) { ImageDescriptor imageDescriptor = null; - if (binding instanceof ITypedef) - imageDescriptor = CElementImageProvider.getTypedefImageDescriptor(); + + try { + if (binding instanceof ITypedef) + imageDescriptor = CElementImageProvider.getTypedefImageDescriptor(); + else if (binding instanceof ICompositeType) { + if (((ICompositeType)binding).getKey() == ICPPClassType.k_class) + imageDescriptor = CElementImageProvider.getClassImageDescriptor(); + else if (((ICompositeType)binding).getKey() == ICompositeType.k_struct) + imageDescriptor = CElementImageProvider.getStructImageDescriptor(); + else if (((ICompositeType)binding).getKey() == ICompositeType.k_union) + imageDescriptor = CElementImageProvider.getUnionImageDescriptor(); + } + } catch (DOMException e) { + } Image image = imageDescriptor != null ? CUIPlugin.getImageDescriptorRegistry().get( imageDescriptor )