mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-09-03 05:33:33 +02:00
Fix for Bug 172158 - [Content Assist] Macro proposals missing in preprocessor directives
This commit is contained in:
parent
3ae81bb32f
commit
058ee238ee
4 changed files with 73 additions and 26 deletions
|
@ -9,6 +9,7 @@
|
||||||
* IBM Corporation - initial implementation
|
* IBM Corporation - initial implementation
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
* Bryan Wilkinson (QNX) - https://bugs.eclipse.org/bugs/show_bug.cgi?id=151207
|
* Bryan Wilkinson (QNX) - https://bugs.eclipse.org/bugs/show_bug.cgi?id=151207
|
||||||
|
* Anton Leherbauer (Wind River Systems)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.parser.scanner2;
|
package org.eclipse.cdt.internal.core.parser.scanner2;
|
||||||
|
|
||||||
|
@ -1613,6 +1614,17 @@ abstract class BaseScanner implements IScanner {
|
||||||
IToken result= null;
|
IToken result= null;
|
||||||
try {
|
try {
|
||||||
result = fetchToken();
|
result = fetchToken();
|
||||||
|
} catch (OffsetLimitReachedException olre) {
|
||||||
|
if (contentAssistMode) {
|
||||||
|
IASTCompletionNode node= olre.getCompletionNode();
|
||||||
|
if (node != null) {
|
||||||
|
result= newToken(IToken.tCOMPLETION, node.getCompletionPrefix().toCharArray());
|
||||||
|
} else {
|
||||||
|
result= newToken(IToken.tCOMPLETION);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw olre;
|
||||||
|
}
|
||||||
} catch (ArrayIndexOutOfBoundsException e) {
|
} catch (ArrayIndexOutOfBoundsException e) {
|
||||||
if (isCancelled) {
|
if (isCancelled) {
|
||||||
throw new ParseError(ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
|
throw new ParseError(ParseError.ParseErrorKind.TIMEOUT_OR_CANCELLED);
|
||||||
|
@ -2037,7 +2049,10 @@ abstract class BaseScanner implements IScanner {
|
||||||
}
|
}
|
||||||
|
|
||||||
// We've run out of contexts, our work is done here
|
// We've run out of contexts, our work is done here
|
||||||
return contentAssistMode ? new SimpleToken(IToken.tCOMPLETION, Integer.MAX_VALUE, null, Integer.MAX_VALUE) : null;
|
if (contentAssistMode) {
|
||||||
|
return new SimpleToken(IToken.tCOMPLETION, Integer.MAX_VALUE, null, Integer.MAX_VALUE);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected CharTable ident = new CharTable(1024);
|
protected CharTable ident = new CharTable(1024);
|
||||||
|
@ -4702,7 +4717,7 @@ abstract class BaseScanner implements IScanner {
|
||||||
* @see org.eclipse.cdt.core.parser.IScanner#setContentAssistMode(int)
|
* @see org.eclipse.cdt.core.parser.IScanner#setContentAssistMode(int)
|
||||||
*/
|
*/
|
||||||
public void setContentAssistMode(int offset) {
|
public void setContentAssistMode(int offset) {
|
||||||
bufferLimit[0] = offset;
|
setOffsetBoundary(offset);
|
||||||
contentAssistMode = true;
|
contentAssistMode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2004 IBM Corporation and others.
|
* Copyright (c) 2007 IBM Corporation and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -38,8 +38,6 @@ public class CompletionTest_MacroRef_NoPrefix extends CompletionProposalsBaseTe
|
||||||
|
|
||||||
public CompletionTest_MacroRef_NoPrefix(String name) {
|
public CompletionTest_MacroRef_NoPrefix(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=172158
|
|
||||||
setExpectFailure(172158);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Test suite() {
|
public static Test suite() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2004 IBM Corporation and others.
|
* Copyright (c) 2004, 2007 IBM Corporation and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -27,14 +27,11 @@ public class CompletionTest_MacroRef_Prefix extends CompletionProposalsBaseTest
|
||||||
private final String headerFileFullPath ="resources/contentassist/" + headerFileName;
|
private final String headerFileFullPath ="resources/contentassist/" + headerFileName;
|
||||||
private final String expectedPrefix = "D";
|
private final String expectedPrefix = "D";
|
||||||
private final String[] expectedResults = {
|
private final String[] expectedResults = {
|
||||||
// missing result:
|
|
||||||
"DEBUG"
|
"DEBUG"
|
||||||
};
|
};
|
||||||
|
|
||||||
public CompletionTest_MacroRef_Prefix(String name) {
|
public CompletionTest_MacroRef_Prefix(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=172158
|
|
||||||
setExpectFailure(172158);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Test suite() {
|
public static Test suite() {
|
||||||
|
|
|
@ -18,7 +18,10 @@ import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.jface.resource.ImageDescriptor;
|
import org.eclipse.jface.resource.ImageDescriptor;
|
||||||
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
import org.eclipse.jface.text.ITextViewer;
|
import org.eclipse.jface.text.ITextViewer;
|
||||||
|
import org.eclipse.jface.text.TextUtilities;
|
||||||
import org.eclipse.swt.graphics.Image;
|
import org.eclipse.swt.graphics.Image;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTCompletionNode;
|
import org.eclipse.cdt.core.dom.ast.ASTCompletionNode;
|
||||||
|
@ -53,6 +56,7 @@ import org.eclipse.cdt.core.model.IWorkingCopy;
|
||||||
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
|
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||||
import org.eclipse.cdt.ui.text.contentassist.ICompletionContributor;
|
import org.eclipse.cdt.ui.text.contentassist.ICompletionContributor;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.viewsupport.CElementImageProvider;
|
import org.eclipse.cdt.internal.ui.viewsupport.CElementImageProvider;
|
||||||
|
@ -66,8 +70,14 @@ public class DOMCompletionContributor implements ICompletionContributor {
|
||||||
String prefix,
|
String prefix,
|
||||||
List proposals) {
|
List proposals) {
|
||||||
|
|
||||||
if (completionNode != null) {
|
if (completionNode == null) {
|
||||||
boolean handleMacros = false;
|
return;
|
||||||
|
}
|
||||||
|
if(inPreprocessorDirective(viewer.getDocument(), offset)) {
|
||||||
|
// add only macros
|
||||||
|
addMacroProposals(viewer, offset, completionNode, prefix, proposals);
|
||||||
|
} else {
|
||||||
|
boolean handleMacros= false;
|
||||||
IASTName[] names = completionNode.getNames();
|
IASTName[] names = completionNode.getNames();
|
||||||
if (names == null || names.length == 0)
|
if (names == null || names.length == 0)
|
||||||
// No names, not much we can do here
|
// No names, not much we can do here
|
||||||
|
@ -80,7 +90,10 @@ public class DOMCompletionContributor implements ICompletionContributor {
|
||||||
// The node isn't properly hooked up, must have backtracked out of this node
|
// The node isn't properly hooked up, must have backtracked out of this node
|
||||||
continue;
|
continue;
|
||||||
IBinding[] bindings = names[i].resolvePrefix();
|
IBinding[] bindings = names[i].resolvePrefix();
|
||||||
if (names[i].getParent() instanceof IASTIdExpression) handleMacros = true;
|
if (names[i].getParent() instanceof IASTIdExpression) {
|
||||||
|
// handle macros only if there is a prefix
|
||||||
|
handleMacros = prefix.length() > 0;
|
||||||
|
}
|
||||||
if (bindings != null)
|
if (bindings != null)
|
||||||
for (int j = 0; j < bindings.length; ++j) {
|
for (int j = 0; j < bindings.length; ++j) {
|
||||||
IBinding binding = bindings[j];
|
IBinding binding = bindings[j];
|
||||||
|
@ -96,21 +109,45 @@ public class DOMCompletionContributor implements ICompletionContributor {
|
||||||
IBinding binding = (IBinding)iBinding.next();
|
IBinding binding = (IBinding)iBinding.next();
|
||||||
handleBinding(binding, completionNode, offset, viewer, proposals);
|
handleBinding(binding, completionNode, offset, viewer, proposals);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find all macros if there is a prefix
|
if (handleMacros) {
|
||||||
if (prefix.length() > 0 && handleMacros) {
|
addMacroProposals(viewer, offset, completionNode, prefix, proposals);
|
||||||
IASTPreprocessorMacroDefinition[] macros = completionNode.getTranslationUnit().getMacroDefinitions();
|
|
||||||
if (macros != null)
|
|
||||||
for (int i = 0; i < macros.length; ++i)
|
|
||||||
if (CharArrayUtils.equals(macros[i].getName().toCharArray(), 0, prefix.length(), prefix.toCharArray(), false))
|
|
||||||
handleMacro(macros[i], completionNode, offset, viewer, proposals);
|
|
||||||
macros = completionNode.getTranslationUnit().getBuiltinMacroDefinitions();
|
|
||||||
if (macros != null)
|
|
||||||
for (int i = 0; i < macros.length; ++i)
|
|
||||||
if (CharArrayUtils.equals(macros[i].getName().toCharArray(), 0, prefix.length(), prefix.toCharArray(), false))
|
|
||||||
handleMacro(macros[i], completionNode, offset, viewer, proposals);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addMacroProposals(ITextViewer viewer, int offset,
|
||||||
|
ASTCompletionNode completionNode, String prefix, List proposals) {
|
||||||
|
char[] prefixChars= prefix.toCharArray();
|
||||||
|
IASTPreprocessorMacroDefinition[] macros = completionNode.getTranslationUnit().getMacroDefinitions();
|
||||||
|
if (macros != null)
|
||||||
|
for (int i = 0; i < macros.length; ++i)
|
||||||
|
if (CharArrayUtils.equals(macros[i].getName().toCharArray(), 0, prefixChars.length, prefixChars, false))
|
||||||
|
handleMacro(macros[i], completionNode, offset, viewer, proposals);
|
||||||
|
macros = completionNode.getTranslationUnit().getBuiltinMacroDefinitions();
|
||||||
|
if (macros != null)
|
||||||
|
for (int i = 0; i < macros.length; ++i)
|
||||||
|
if (CharArrayUtils.equals(macros[i].getName().toCharArray(), 0, prefixChars.length, prefixChars, false))
|
||||||
|
handleMacro(macros[i], completionNode, offset, viewer, proposals);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if given offset is inside a preprocessor directive.
|
||||||
|
*
|
||||||
|
* @param doc the document
|
||||||
|
* @param offset the offset to check
|
||||||
|
* @return <code>true</code> if offset is inside a preprocessor directive
|
||||||
|
*/
|
||||||
|
private boolean inPreprocessorDirective(IDocument doc, int offset) {
|
||||||
|
if (offset > 0 && offset == doc.getLength()) {
|
||||||
|
--offset;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return ICPartitions.C_PREPROCESSOR
|
||||||
|
.equals(TextUtilities.getContentType(doc, ICPartitions.C_PARTITIONING, offset, false));
|
||||||
|
} catch (BadLocationException exc) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void handleBinding(IBinding binding, ASTCompletionNode completionNode, int offset, ITextViewer viewer, List proposals) {
|
protected void handleBinding(IBinding binding, ASTCompletionNode completionNode, int offset, ITextViewer viewer, List proposals) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue