mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
bug 229482, keyword completion proposals based on ILanguage
This commit is contained in:
parent
77b47297cf
commit
f3ee65691f
4 changed files with 79 additions and 142 deletions
|
@ -225,36 +225,50 @@ public abstract class AbstractCLikeLanguage extends AbstractLanguage implements
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String[] getKeywords() {
|
private String[] keywords = null;
|
||||||
Set<String> keywords = new HashSet<String>(KeywordSets.getKeywords(KeywordSetKey.KEYWORDS, getParserLanguage()));
|
private String[] builtinTypes = null;
|
||||||
|
private String[] preprocessorKeywords = null;
|
||||||
|
|
||||||
CharArrayIntMap additionalKeywords = getScannerExtensionConfiguration().getAdditionalKeywords();
|
|
||||||
if (additionalKeywords != null) {
|
public String[] getKeywords() {
|
||||||
for (Iterator<char[]> iterator = additionalKeywords.toList().iterator(); iterator.hasNext(); ) {
|
if(keywords == null) {
|
||||||
char[] name = iterator.next();
|
Set<String> keywordSet = new HashSet<String>(KeywordSets.getKeywords(KeywordSetKey.KEYWORDS, getParserLanguage()));
|
||||||
keywords.add(new String(name));
|
|
||||||
|
CharArrayIntMap additionalKeywords = getScannerExtensionConfiguration().getAdditionalKeywords();
|
||||||
|
if (additionalKeywords != null) {
|
||||||
|
for (Iterator<char[]> iterator = additionalKeywords.toList().iterator(); iterator.hasNext(); ) {
|
||||||
|
char[] name = iterator.next();
|
||||||
|
keywordSet.add(new String(name));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
keywords = keywordSet.toArray(new String[keywordSet.size()]);
|
||||||
}
|
}
|
||||||
return keywords.toArray(new String[keywords.size()]);
|
return keywords;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String[] getBuiltinTypes() {
|
public String[] getBuiltinTypes() {
|
||||||
Set<String> types = KeywordSets.getKeywords(KeywordSetKey.TYPES, getParserLanguage());
|
if(builtinTypes == null) {
|
||||||
return types.toArray(new String[types.size()]);
|
Set<String> types = KeywordSets.getKeywords(KeywordSetKey.TYPES, getParserLanguage());
|
||||||
|
builtinTypes = types.toArray(new String[types.size()]);
|
||||||
|
}
|
||||||
|
return builtinTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String[] getPreprocessorKeywords() {
|
public String[] getPreprocessorKeywords() {
|
||||||
Set<String> keywords = new HashSet<String>(KeywordSets.getKeywords(KeywordSetKey.PP_DIRECTIVE, getParserLanguage()));
|
if(preprocessorKeywords == null) {
|
||||||
CharArrayIntMap additionalKeywords= getScannerExtensionConfiguration().getAdditionalPreprocessorKeywords();
|
Set<String> keywords = new HashSet<String>(KeywordSets.getKeywords(KeywordSetKey.PP_DIRECTIVE, getParserLanguage()));
|
||||||
if (additionalKeywords != null) {
|
CharArrayIntMap additionalKeywords= getScannerExtensionConfiguration().getAdditionalPreprocessorKeywords();
|
||||||
for (Iterator<char[]> iterator = additionalKeywords.toList().iterator(); iterator.hasNext(); ) {
|
if (additionalKeywords != null) {
|
||||||
char[] name = iterator.next();
|
for (Iterator<char[]> iterator = additionalKeywords.toList().iterator(); iterator.hasNext(); ) {
|
||||||
keywords.add(new String(name));
|
char[] name = iterator.next();
|
||||||
|
keywords.add(new String(name));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
preprocessorKeywords = keywords.toArray(new String[keywords.size()]);
|
||||||
}
|
}
|
||||||
return keywords.toArray(new String[keywords.size()]);
|
return preprocessorKeywords;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,21 +13,25 @@ package org.eclipse.cdt.core.parser;
|
||||||
/**
|
/**
|
||||||
* @author jcamelon
|
* @author jcamelon
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@SuppressWarnings("nls")
|
||||||
public class Directives {
|
public class Directives {
|
||||||
|
|
||||||
public static final String POUND_DEFINE = "#define"; //$NON-NLS-1$
|
public static final String
|
||||||
public static final String POUND_UNDEF = "#undef"; //$NON-NLS-1$
|
POUND_DEFINE = "#define",
|
||||||
public static final String POUND_IF = "#if"; //$NON-NLS-1$
|
POUND_UNDEF = "#undef",
|
||||||
public static final String POUND_IFDEF = "#ifdef"; //$NON-NLS-1$
|
POUND_IF = "#if",
|
||||||
public static final String POUND_IFNDEF = "#ifndef"; //$NON-NLS-1$
|
POUND_IFDEF = "#ifdef",
|
||||||
public static final String POUND_ELSE = "#else"; //$NON-NLS-1$
|
POUND_IFNDEF = "#ifndef",
|
||||||
public static final String POUND_ENDIF = "#endif"; //$NON-NLS-1$
|
POUND_ELSE = "#else",
|
||||||
public static final String POUND_INCLUDE = "#include"; //$NON-NLS-1$
|
POUND_ENDIF = "#endif",
|
||||||
public static final String POUND_LINE = "#line"; //$NON-NLS-1$
|
POUND_INCLUDE = "#include",
|
||||||
public static final String POUND_ERROR = "#error"; //$NON-NLS-1$
|
POUND_LINE = "#line",
|
||||||
public static final String POUND_PRAGMA = "#pragma"; //$NON-NLS-1$
|
POUND_ERROR = "#error",
|
||||||
public static final String POUND_ELIF = "#elif"; //$NON-NLS-1$
|
POUND_PRAGMA = "#pragma",
|
||||||
public static final String POUND_BLANK = "#"; //$NON-NLS-1$
|
POUND_ELIF = "#elif",
|
||||||
public static final String _PRAGMA = "_Pragma"; //$NON-NLS-1$
|
POUND_BLANK = "#",
|
||||||
|
_PRAGMA = "_Pragma",
|
||||||
|
DEFINED = "defined";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -327,7 +327,8 @@ public class KeywordSets {
|
||||||
PP_DIRECTIVES_C.add(Directives.POUND_ERROR);
|
PP_DIRECTIVES_C.add(Directives.POUND_ERROR);
|
||||||
PP_DIRECTIVES_C.add(Directives.POUND_PRAGMA);
|
PP_DIRECTIVES_C.add(Directives.POUND_PRAGMA);
|
||||||
PP_DIRECTIVES_C.add(Directives.POUND_ELIF);
|
PP_DIRECTIVES_C.add(Directives.POUND_ELIF);
|
||||||
PP_DIRECTIVES_C.add(Directives._PRAGMA );
|
PP_DIRECTIVES_C.add(Directives._PRAGMA);
|
||||||
|
PP_DIRECTIVES_C.add(Directives.DEFINED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -348,6 +349,7 @@ public class KeywordSets {
|
||||||
PP_DIRECTIVES_CPP.add(Directives.POUND_ERROR);
|
PP_DIRECTIVES_CPP.add(Directives.POUND_ERROR);
|
||||||
PP_DIRECTIVES_CPP.add(Directives.POUND_PRAGMA);
|
PP_DIRECTIVES_CPP.add(Directives.POUND_PRAGMA);
|
||||||
PP_DIRECTIVES_CPP.add(Directives.POUND_ELIF);
|
PP_DIRECTIVES_CPP.add(Directives.POUND_ELIF);
|
||||||
|
PP_DIRECTIVES_CPP.add(Directives.DEFINED);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Set<String> ALL_C;
|
private static final Set<String> ALL_C;
|
||||||
|
|
|
@ -27,9 +27,9 @@ import org.eclipse.swt.graphics.Image;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTCompletionNode;
|
import org.eclipse.cdt.core.dom.ast.IASTCompletionNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
|
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
|
import org.eclipse.cdt.core.model.ICLanguageKeywords;
|
||||||
|
import org.eclipse.cdt.core.model.ILanguage;
|
||||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
import org.eclipse.cdt.core.parser.Directives;
|
|
||||||
import org.eclipse.cdt.core.parser.Keywords;
|
|
||||||
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.ICPartitions;
|
||||||
|
|
||||||
|
@ -37,6 +37,8 @@ import org.eclipse.cdt.internal.ui.viewsupport.CElementImageProvider;
|
||||||
|
|
||||||
public class KeywordCompletionProposalComputer extends ParsingBasedProposalComputer {
|
public class KeywordCompletionProposalComputer extends ParsingBasedProposalComputer {
|
||||||
|
|
||||||
|
private static final int MIN_KEYWORD_LENGTH = 5;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected List<ICompletionProposal> computeCompletionProposals(
|
protected List<ICompletionProposal> computeCompletionProposals(
|
||||||
CContentAssistInvocationContext context,
|
CContentAssistInvocationContext context,
|
||||||
|
@ -60,17 +62,30 @@ public class KeywordCompletionProposalComputer extends ParsingBasedProposalCompu
|
||||||
|
|
||||||
List<ICompletionProposal> proposals = new ArrayList<ICompletionProposal>();
|
List<ICompletionProposal> proposals = new ArrayList<ICompletionProposal>();
|
||||||
|
|
||||||
|
ICLanguageKeywords languageKeywords = null;
|
||||||
|
ITranslationUnit tu = context.getTranslationUnit();
|
||||||
|
if(tu != null) {
|
||||||
|
ILanguage language = tu.getLanguage();
|
||||||
|
if(language instanceof ICLanguageKeywords)
|
||||||
|
languageKeywords = (ICLanguageKeywords)language;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(languageKeywords == null)
|
||||||
|
return Collections.emptyList();
|
||||||
|
|
||||||
|
|
||||||
if (inPreprocessorDirective(context)) {
|
if (inPreprocessorDirective(context)) {
|
||||||
// TODO split this into a separate proposal computer?
|
// TODO split this into a separate proposal computer?
|
||||||
boolean needDirectiveKeyword= inPreprocessorKeyword(context);
|
boolean needDirectiveKeyword= inPreprocessorKeyword(context);
|
||||||
String[] keywords= preprocessorKeywords;
|
|
||||||
|
|
||||||
// add matching preprocessor keyword proposals
|
// add matching preprocessor keyword proposals
|
||||||
ImageDescriptor imagedesc = CElementImageProvider.getKeywordImageDescriptor();
|
ImageDescriptor imagedesc = CElementImageProvider.getKeywordImageDescriptor();
|
||||||
Image image = imagedesc != null ? CUIPlugin.getImageDescriptorRegistry().get(imagedesc) : null;
|
Image image = imagedesc != null ? CUIPlugin.getImageDescriptorRegistry().get(imagedesc) : null;
|
||||||
for (int i = 0; i < keywords.length; ++i) {
|
|
||||||
String repString= keywords[i];
|
for(String keyword : languageKeywords.getPreprocessorKeywords()) {
|
||||||
if (repString.startsWith(prefix) && keywords[i].length() > prefixLength) {
|
keyword = keyword + ' ';
|
||||||
|
String repString = keyword;
|
||||||
|
if (repString.startsWith(prefix) && keyword.length() > prefixLength) {
|
||||||
int repLength = prefixLength;
|
int repLength = prefixLength;
|
||||||
int repOffset = context.getInvocationOffset() - repLength;
|
int repOffset = context.getInvocationOffset() - repLength;
|
||||||
if (prefix.charAt(0) == '#') {
|
if (prefix.charAt(0) == '#') {
|
||||||
|
@ -82,28 +97,23 @@ public class KeywordCompletionProposalComputer extends ParsingBasedProposalCompu
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
proposals.add(new CCompletionProposal(repString, repOffset,
|
proposals.add(new CCompletionProposal(repString, repOffset,
|
||||||
repLength, image, keywords[i], relevance, context.getViewer()));
|
repLength, image, keyword, relevance, context.getViewer()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!isValidContext(completionNode))
|
if (!isValidContext(completionNode))
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
|
|
||||||
ITranslationUnit tu = context.getTranslationUnit();
|
|
||||||
|
|
||||||
String[] keywords = cppkeywords; // default to C++
|
|
||||||
if (tu != null && tu.isCLanguage())
|
|
||||||
keywords = ckeywords;
|
|
||||||
|
|
||||||
// add matching keyword proposals
|
// add matching keyword proposals
|
||||||
ImageDescriptor imagedesc = CElementImageProvider.getKeywordImageDescriptor();
|
ImageDescriptor imagedesc = CElementImageProvider.getKeywordImageDescriptor();
|
||||||
Image image = imagedesc != null ? CUIPlugin.getImageDescriptorRegistry().get(imagedesc) : null;
|
Image image = imagedesc != null ? CUIPlugin.getImageDescriptorRegistry().get(imagedesc) : null;
|
||||||
for (int i = 0; i < keywords.length; ++i) {
|
|
||||||
if (keywords[i].startsWith(prefix) && keywords[i].length() > prefixLength) {
|
for(String keyword : languageKeywords.getKeywords()) {
|
||||||
|
if (keyword.startsWith(prefix) && keyword.length() > prefixLength && keyword.length() >= MIN_KEYWORD_LENGTH) {
|
||||||
int repLength = prefixLength;
|
int repLength = prefixLength;
|
||||||
int repOffset = context.getInvocationOffset() - repLength;
|
int repOffset = context.getInvocationOffset() - repLength;
|
||||||
proposals.add(new CCompletionProposal(keywords[i], repOffset,
|
proposals.add(new CCompletionProposal(keyword, repOffset,
|
||||||
repLength, image, keywords[i], relevance, context.getViewer()));
|
repLength, image, keyword, relevance, context.getViewer()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,97 +191,4 @@ public class KeywordCompletionProposalComputer extends ParsingBasedProposalCompu
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// These are the keywords we complete
|
|
||||||
// We only do the ones that are >= 5 characters long
|
|
||||||
private static String [] ckeywords = {
|
|
||||||
Keywords.BREAK,
|
|
||||||
Keywords.CONST,
|
|
||||||
Keywords.CONTINUE,
|
|
||||||
Keywords.DEFAULT,
|
|
||||||
Keywords.DOUBLE,
|
|
||||||
Keywords.EXTERN,
|
|
||||||
Keywords.FLOAT,
|
|
||||||
Keywords.INLINE,
|
|
||||||
Keywords.REGISTER,
|
|
||||||
Keywords.RESTRICT,
|
|
||||||
Keywords.RETURN,
|
|
||||||
Keywords.SHORT,
|
|
||||||
Keywords.SIGNED,
|
|
||||||
Keywords.SIZEOF,
|
|
||||||
Keywords.STATIC,
|
|
||||||
Keywords.STRUCT,
|
|
||||||
Keywords.SWITCH,
|
|
||||||
Keywords.TYPEDEF,
|
|
||||||
Keywords.UNION,
|
|
||||||
Keywords.UNSIGNED,
|
|
||||||
Keywords.VOLATILE,
|
|
||||||
Keywords.WHILE,
|
|
||||||
Keywords._BOOL,
|
|
||||||
Keywords._COMPLEX,
|
|
||||||
Keywords._IMAGINARY
|
|
||||||
};
|
|
||||||
|
|
||||||
private static String [] cppkeywords = {
|
|
||||||
Keywords.BREAK,
|
|
||||||
Keywords.CATCH,
|
|
||||||
Keywords.CLASS,
|
|
||||||
Keywords.CONST,
|
|
||||||
Keywords.CONST_CAST,
|
|
||||||
Keywords.CONTINUE,
|
|
||||||
Keywords.DEFAULT,
|
|
||||||
Keywords.DELETE,
|
|
||||||
Keywords.DOUBLE,
|
|
||||||
Keywords.DYNAMIC_CAST,
|
|
||||||
Keywords.EXPLICIT,
|
|
||||||
Keywords.EXPORT,
|
|
||||||
Keywords.EXTERN,
|
|
||||||
Keywords.FALSE,
|
|
||||||
Keywords.FLOAT,
|
|
||||||
Keywords.FRIEND,
|
|
||||||
Keywords.INLINE,
|
|
||||||
Keywords.MUTABLE,
|
|
||||||
Keywords.NAMESPACE,
|
|
||||||
Keywords.OPERATOR,
|
|
||||||
Keywords.PRIVATE,
|
|
||||||
Keywords.PROTECTED,
|
|
||||||
Keywords.PUBLIC,
|
|
||||||
Keywords.REGISTER,
|
|
||||||
Keywords.REINTERPRET_CAST,
|
|
||||||
Keywords.RETURN,
|
|
||||||
Keywords.SHORT,
|
|
||||||
Keywords.SIGNED,
|
|
||||||
Keywords.SIZEOF,
|
|
||||||
Keywords.STATIC,
|
|
||||||
Keywords.STATIC_CAST,
|
|
||||||
Keywords.STRUCT,
|
|
||||||
Keywords.SWITCH,
|
|
||||||
Keywords.TEMPLATE,
|
|
||||||
Keywords.THROW,
|
|
||||||
Keywords.TYPEDEF,
|
|
||||||
Keywords.TYPEID,
|
|
||||||
Keywords.TYPENAME,
|
|
||||||
Keywords.UNION,
|
|
||||||
Keywords.UNSIGNED,
|
|
||||||
Keywords.USING,
|
|
||||||
Keywords.VIRTUAL,
|
|
||||||
Keywords.VOLATILE,
|
|
||||||
Keywords.WCHAR_T,
|
|
||||||
Keywords.WHILE
|
|
||||||
};
|
|
||||||
|
|
||||||
private static String [] preprocessorKeywords = {
|
|
||||||
Directives.POUND_DEFINE + ' ',
|
|
||||||
Directives.POUND_ELIF + ' ',
|
|
||||||
Directives.POUND_ELSE,
|
|
||||||
Directives.POUND_ENDIF,
|
|
||||||
Directives.POUND_ERROR + ' ',
|
|
||||||
Directives.POUND_IF + ' ',
|
|
||||||
Directives.POUND_IFDEF + ' ',
|
|
||||||
Directives.POUND_IFNDEF + ' ',
|
|
||||||
Directives.POUND_INCLUDE + ' ',
|
|
||||||
Directives.POUND_PRAGMA + ' ',
|
|
||||||
Directives.POUND_UNDEF + ' ',
|
|
||||||
"defined" //$NON-NLS-1$
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue