diff options
author | Nathan Ridge | 2017-11-06 02:06:42 +0000 |
---|---|---|
committer | Nathan Ridge | 2017-11-13 18:22:26 +0000 |
commit | 301de3d40ea15dfc84a90c227db62514cd2dc578 (patch) | |
tree | 5f01ce1f4ffcee2282133ebf81f376f6afed36fc /core/org.eclipse.cdt.core | |
parent | b090f32e646527db07ab1b1b4f2374256ec43af9 (diff) | |
download | org.eclipse.cdt-301de3d40ea15dfc84a90c227db62514cd2dc578.tar.gz org.eclipse.cdt-301de3d40ea15dfc84a90c227db62514cd2dc578.tar.xz org.eclipse.cdt-301de3d40ea15dfc84a90c227db62514cd2dc578.zip |
Bug 522010 - Completion of non-type template parameter in ambiguous template argument
This works around the fact that the optimization introduced in bug 316704
inteferes with the mechanism for offering completions for both alternatives
in an ambiguous context.
Change-Id: Ibe14c1b4f2f9c9b3394d4635c87424a25fbd7a53
Diffstat (limited to 'core/org.eclipse.cdt.core')
3 files changed, 68 insertions, 3 deletions
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTCompletionNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTCompletionNode.java index 607379e3d8f..733ecf946bc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTCompletionNode.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTCompletionNode.java @@ -20,7 +20,7 @@ import org.eclipse.cdt.core.parser.IToken; */ public class ASTCompletionNode implements IASTCompletionNode { private final IToken completionToken; - private final List<IASTName> names = new ArrayList<>(); + private final List<CompletionNameEntry> entries = new ArrayList<>(); private final IASTTranslationUnit translationUnit; public ASTCompletionNode(IToken completionToken, IASTTranslationUnit translationUnit) { @@ -29,7 +29,7 @@ public class ASTCompletionNode implements IASTCompletionNode { } public void addName(IASTName name) { - names.add(name); + entries.add(new CompletionNameEntry(name, name.getParent())); } @Override @@ -43,8 +43,27 @@ public class ASTCompletionNode implements IASTCompletionNode { } @Override + public boolean containsName(IASTName name) { + for (CompletionNameEntry entry : entries) { + if (entry.fName == name) { + return true; + } + } + return false; + } + + @Override public IASTName[] getNames() { - return names.toArray(new IASTName[names.size()]); + IASTName[] names = new IASTName[entries.size()]; + for (int i = 0; i < entries.size(); ++i) { + names[i] = entries.get(i).fName; + } + return names; + } + + @Override + public CompletionNameEntry[] getEntries() { + return entries.toArray(new CompletionNameEntry[entries.size()]); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTCompletionNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTCompletionNode.java index 237b49d38ee..8c9d983ae32 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTCompletionNode.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTCompletionNode.java @@ -26,6 +26,25 @@ package org.eclipse.cdt.core.dom.ast; */ public interface IASTCompletionNode { /** + * Represents a name that fits in this context, and its parent. + * The parent is stored separately because two entries can have + * the same name but different parents. (This is due to the + * parser sometimes re-using nodes between alternatives in an + * ambiguous node.) + * + * @since 6.4 + */ + public class CompletionNameEntry { + public CompletionNameEntry(IASTName name, IASTNode parent) { + fName = name; + fParent = parent; + } + + public IASTName fName; + public IASTNode fParent; + } + + /** * If the point of completion was at the end of a potential identifier, this * string contains the text of that identifier. * @@ -39,9 +58,27 @@ public interface IASTCompletionNode { public int getLength(); /** + * Returns true if this completion node contains a {@link CompletionNameEntry} + * with the given name. + * + * @since 6.4 + */ + public boolean containsName(IASTName name); + + /** * Returns a list of names that fit in this context. + * If doing computations based on the name's parent, prefer calling getEntries() instead + * and obtaining the parent from there. */ public IASTName[] getNames(); + + /** + * Returns a list of names that fir in this context, along with their parents. + * See {@link CompletionNameEntry} for more details. + * + * @since 6.4 + */ + public CompletionNameEntry[] getEntries(); /** * Returns the translation unit for this completion. 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 a2b01fec885..2fc22a307cb 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 @@ -27,6 +27,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.eclipse.cdt.core.dom.ast.ASTCompletionNode; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTAlignmentSpecifier; @@ -785,6 +786,14 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { name = namedTypeSpec.getName(); if (name.contains(typeId)) { idExpression = setRange(getNodeFactory().newIdExpression(name), name); + + // If the name was one of the completion names, add it to the completion + // node again now that it has a new parent. This ensures that completion + // proposals are offered for both contexts that the name appears in. + ASTCompletionNode completionNode = (ASTCompletionNode) getCompletionNode(); + if (completionNode != null && completionNode.containsName(name)) { + completionNode.addName(name); + } } } |