1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

113568: [Content Assist] proposals for include directives

This commit is contained in:
Anton Leherbauer 2008-03-27 14:10:57 +00:00
parent 2d526547f2
commit bfd296013f
8 changed files with 508 additions and 41 deletions

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2007 IBM Corporation and others.
* Copyright (c) 2004, 2008 IBM Corporation 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
@ -15,14 +15,13 @@ package org.eclipse.cdt.ui.tests.text.contentassist2;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContextInformation;
@ -34,17 +33,16 @@ import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMManager;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.parser.KeywordSetKey;
import org.eclipse.cdt.core.parser.ParserFactory;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.ui.testplugin.CTestPlugin;
import org.eclipse.cdt.ui.tests.BaseUITestCase;
import org.eclipse.cdt.ui.tests.text.EditorTestHelper;
import org.eclipse.cdt.ui.text.ICCompletionProposal;
import org.eclipse.cdt.ui.text.ICPartitions;
import org.eclipse.cdt.internal.ui.text.contentassist.CCompletionProposal;
import org.eclipse.cdt.internal.ui.text.contentassist.CContentAssistProcessor;
import org.eclipse.cdt.internal.ui.text.contentassist.RelevanceConstants;
public abstract class AbstractContentAssistTest extends BaseUITestCase {
@ -57,14 +55,6 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase {
protected ITextEditor fEditor;
private boolean fIsCpp;
private final static Set fgAllKeywords= new HashSet();
static {
fgAllKeywords.addAll(ParserFactory.getKeywordSet(KeywordSetKey.KEYWORDS, ParserLanguage.C));
fgAllKeywords.addAll(ParserFactory.getKeywordSet(KeywordSetKey.TYPES, ParserLanguage.C));
fgAllKeywords.addAll(ParserFactory.getKeywordSet(KeywordSetKey.KEYWORDS, ParserLanguage.CPP));
fgAllKeywords.addAll(ParserFactory.getKeywordSet(KeywordSetKey.TYPES, ParserLanguage.CPP));
}
public AbstractContentAssistTest(String name, boolean isCpp) {
super(name);
fIsCpp= isCpp;
@ -111,7 +101,8 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase {
//Call the CContentAssistProcessor
ISourceViewer sourceViewer= EditorTestHelper.getSourceViewer((AbstractTextEditor)fEditor);
String contentType = sourceViewer.getDocument().getContentType(offset);
String contentType= TextUtilities.getContentType(sourceViewer.getDocument(), ICPartitions.C_PARTITIONING, offset, true);
boolean isCode= IDocument.DEFAULT_CONTENT_TYPE.equals(contentType);
ContentAssistant assistant = new ContentAssistant();
CContentAssistProcessor processor = new CContentAssistProcessor(fEditor, assistant, contentType);
long startTime= System.currentTimeMillis();
@ -121,7 +112,7 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase {
long endTime= System.currentTimeMillis();
assertTrue(results != null);
results= filterResults(results);
results= filterResults(results, isCode);
String[] resultStrings= toStringArray(results, compareType);
Arrays.sort(expected);
Arrays.sort(resultStrings);
@ -167,22 +158,31 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase {
/**
* Filter out template and keyword proposals.
* @param results
* @param isCodeCompletion completion is in code, not preprocessor, etc.
* @return filtered proposals
*/
private Object[] filterResults(Object[] results) {
List filtered= new ArrayList();
private Object[] filterResults(Object[] results, boolean isCodeCompletion) {
List<Object> filtered= new ArrayList<Object>();
for (int i = 0; i < results.length; i++) {
Object result = results[i];
if (result instanceof TemplateProposal) {
continue;
}
if (result instanceof ICCompletionProposal) {
// check for keywords proposal
if (fgAllKeywords.contains(((ICCompletionProposal)result).getDisplayString())) {
continue;
if (isCodeCompletion) {
// check for keywords proposal
int relevance = ((ICCompletionProposal)result).getRelevance();
if (relevance >= RelevanceConstants.CASE_MATCH_RELEVANCE) {
relevance -= RelevanceConstants.CASE_MATCH_RELEVANCE;
}
if (relevance <= RelevanceConstants.KEYWORD_TYPE_RELEVANCE) {
continue;
}
}
filtered.add(result);
} else if (result instanceof IContextInformation) {
filtered.add(result);
}
filtered.add(result);
}
return filtered.toArray();
}
@ -191,7 +191,7 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase {
String[] strings= new String[results.length];
for(int i=0; i< results.length; i++){
Object result = results[i];
if (result instanceof ICompletionProposal) {
if (result instanceof CCompletionProposal) {
if (compareType == COMPARE_ID_STRINGS) {
strings[i]= ((CCompletionProposal)result).getIdString();
} else if (compareType == COMPARE_DISP_STRINGS) {
@ -199,8 +199,20 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase {
} else {
strings[i]= ((CCompletionProposal)result).getReplacementString();
}
} else {
} else if (result instanceof ICCompletionProposal) {
if (compareType == COMPARE_ID_STRINGS) {
strings[i]= ((ICCompletionProposal)result).getIdString();
} else if (compareType == COMPARE_DISP_STRINGS) {
strings[i]= ((ICCompletionProposal)result).getDisplayString();
} else {
strings[i]= ((ICCompletionProposal)result).getDisplayString();
}
} else if (result instanceof ICompletionProposal) {
strings[i]= ((ICompletionProposal)result).getDisplayString();
} else if (result instanceof IContextInformation) {
strings[i]= ((IContextInformation)result).getContextDisplayString();
} else {
strings[i]= result.toString();
}
}
return strings;

View file

@ -13,6 +13,11 @@
*******************************************************************************/
package org.eclipse.cdt.ui.tests.text.contentassist2;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import junit.framework.Test;
import org.eclipse.core.resources.IFile;
@ -20,6 +25,7 @@ import org.eclipse.core.resources.IProject;
import org.eclipse.jface.text.IDocument;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.testplugin.TestScannerProvider;
import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
@ -951,4 +957,75 @@ public class CompletionTests extends AbstractContentAssistTest {
};
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS);
}
//#include "/*cursor*/
public void testInclusionProposals_bug113568() throws Exception {
File tempRoot= new File(System.getProperty("java.io.tmpdir"));
File tempDir= new File(tempRoot, "cdttest_113568");
tempDir.mkdir();
try {
createIncludeFiles(tempDir, new String[] {
"h1/inc1.h",
"h1/sub1/inc11.h",
"h2/inc2.h"
});
String[] expected= {
"\"inc1.h\"",
"\"sub1/\"",
"\"inc2.h\""
};
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS);
getDocument().replace(fCursorOffset++, 0, "i");
expected= new String[] {
"\"inc1.h\"",
"\"inc2.h\""
};
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS);
getDocument().replace(fCursorOffset, 0, "\"");
expected= new String[] {
"\"inc1.h",
"\"inc2.h"
};
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS);
getDocument().replace(fCursorOffset-1, 1, "sub1/");
expected= new String[] {
"\"sub1/inc11.h"
};
assertCompletionResults(fCursorOffset+=4, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS);
} finally {
deleteDir(tempDir);
}
}
public static void deleteDir(File dir) {
File[] files = dir.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
deleteDir(files[i]);
} else {
files[i].delete();
}
}
dir.delete();
}
private static void createIncludeFiles(File dir, String[] files) throws IOException {
Set<String> includeDirs= new HashSet<String>();
for (int i = 0; i < files.length; i++) {
File file = new File(dir, files[i]);
final File parentFile= file.getParentFile();
if (parentFile.getName().startsWith("sub")) {
if (!parentFile.exists()) {
parentFile.mkdirs();
}
} else if (includeDirs.add(parentFile.getAbsolutePath())) {
parentFile.mkdirs();
}
file.createNewFile();
}
TestScannerProvider.sIncludes= (String[]) includeDirs.toArray(new String[includeDirs.size()]);
}
}

View file

@ -2184,6 +2184,15 @@
<partition type="__c_preprocessor"/>
</completionProposalComputer>
</extension>
<extension
id="InclusionProposalComputer"
point="org.eclipse.cdt.ui.completionProposalComputer">
<completionProposalComputer
categoryId="org.eclipse.cdt.ui.parserProposalCategory"
class="org.eclipse.cdt.internal.ui.text.contentassist.InclusionProposalComputer">
<partition type="__c_preprocessor"/>
</completionProposalComputer>
</extension>
<extension
id="KeywordCompletionProposalComputer"

View file

@ -169,7 +169,7 @@ public class CCompletionProposal implements ICCompletionProposal, ICompletionPro
Assert.isTrue(cursorPosition >= 0);
fCursorPosition= cursorPosition;
fContextInformationPosition= (fContextInformation != null ? fCursorPosition : -1);
}
}
/*
* @see ICompletionProposalExtension#apply(IDocument, char, int)
@ -478,11 +478,7 @@ public class CCompletionProposal implements ICCompletionProposal, ICompletionPro
if (offset < fReplacementOffset)
return false;
/*
* See http://dev.eclipse.org/bugs/show_bug.cgi?id=17667
String word= fReplacementString;
*/
boolean validated= startsWith(document, offset, fDisplayString);
boolean validated= startsWith(document, offset, fReplacementString);
if (validated && event != null) {
// adapt replacement range to document change
@ -515,7 +511,7 @@ public class CCompletionProposal implements ICCompletionProposal, ICompletionPro
*/
protected boolean startsWith(IDocument document, int offset, String word) {
int wordLength= word == null ? 0 : word.length();
if (offset > fReplacementOffset + wordLength)
if (offset >= fReplacementOffset + wordLength)
return false;
try {

View file

@ -282,7 +282,7 @@ public class DOMCompletionProposalComputer extends ParsingBasedProposalComputer
} else if (binding instanceof IEnumerator) {
proposals.add(createProposal(name, name, getImage(binding), baseRelevance + RelevanceConstants.ENUMERATOR_TYPE_RELEVANCE, cContext));
} else {
proposals.add(createProposal(name, name, getImage(binding), baseRelevance, cContext));
proposals.add(createProposal(name, name, getImage(binding), baseRelevance + RelevanceConstants.DEFAULT_TYPE_RELEVANCE, cContext));
}
}
}

View file

@ -0,0 +1,373 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Anton Leherbauer (Wind River Systems) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.text.contentassist;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceProxy;
import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.swt.graphics.Image;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.IInclude;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.IExtendedScannerInfo;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.text.ICPartitions;
import org.eclipse.cdt.ui.text.contentassist.ContentAssistInvocationContext;
import org.eclipse.cdt.ui.text.contentassist.ICompletionProposalComputer;
import org.eclipse.cdt.internal.ui.viewsupport.CElementImageProvider;
/**
* A proposal computer for include directives.
*
* @since 5.0
*/
public class InclusionProposalComputer implements ICompletionProposalComputer {
private String fErrorMessage;
public List computeCompletionProposals(ContentAssistInvocationContext context, IProgressMonitor monitor) {
List<CCompletionProposal> proposals= Collections.emptyList();
fErrorMessage= null;
if (context instanceof CContentAssistInvocationContext) {
CContentAssistInvocationContext cContext= (CContentAssistInvocationContext) context;
if (inIncludeDirective(cContext)) {
// add include file proposals
proposals= new ArrayList<CCompletionProposal>();
try {
addInclusionProposals(cContext, proposals);
} catch (Exception exc) {
fErrorMessage= exc.getMessage();
CUIPlugin.log(exc);
}
}
}
return proposals;
}
public List computeContextInformation(ContentAssistInvocationContext context, IProgressMonitor monitor) {
return null;
}
public String getErrorMessage() {
return fErrorMessage;
}
public void sessionEnded() {
}
public void sessionStarted() {
}
/**
* Test whether the invocation offset is inside the file name part if an include directive.
*
* @param context the invocation context
* @return <code>true</code> if the invocation offset is inside or before the directive keyword
*/
private boolean inIncludeDirective(CContentAssistInvocationContext context) {
IDocument doc = context.getDocument();
int offset = context.getInvocationOffset();
try {
final ITypedRegion partition= TextUtilities.getPartition(doc, ICPartitions.C_PARTITIONING, offset, true);
if (ICPartitions.C_PREPROCESSOR.equals(partition.getType())) {
String ppPrefix= doc.get(partition.getOffset(), offset - partition.getOffset());
if (ppPrefix.matches("\\s*#\\s*include\\s*[\"<][^\">]*")) { //$NON-NLS-1$
// we are inside the file name part of the include directive
return true;
}
}
} catch (BadLocationException exc) {
}
return false;
}
private void addInclusionProposals(CContentAssistInvocationContext context, List<CCompletionProposal> proposals) throws Exception {
if (context.isContextInformationStyle()) {
return;
}
String prefix;
boolean angleBrackets= false;
prefix = computeIncludePrefix(context);
if (prefix.length() > 0) {
angleBrackets= prefix.charAt(0) == '<';
prefix= prefix.substring(1);
}
IPath prefixPath= new Path(prefix);
final ITranslationUnit tu= context.getTranslationUnit();
String[] potentialIncludes= collectIncludeFiles(tu, prefixPath, angleBrackets);
if (potentialIncludes.length > 0) {
IInclude[] includes= context.getTranslationUnit().getIncludes();
Set<String> alreadyIncluded= new HashSet<String>();
for (int i = 0; i < includes.length; i++) {
IInclude includeDirective= includes[i];
alreadyIncluded.add(includeDirective.getElementName());
}
Image image = getImage(CElementImageProvider.getIncludeImageDescriptor());
for (int i = 0; i < potentialIncludes.length; i++) {
String include= potentialIncludes[i];
if (alreadyIncluded.add(include)) {
final char openingBracket= angleBrackets ? '<' : '"';
final char closingBracket= angleBrackets ? '>' : '"';
String repString= openingBracket + include;
final String dispString= repString + closingBracket;
int repLength = prefix.length() + 1;
int repOffset= context.getInvocationOffset() - repLength;
final boolean needClosingBracket= context.getDocument().getChar(repOffset + repLength) != closingBracket;
if (needClosingBracket) {
repString += closingBracket;
}
final boolean isDir= include.endsWith("/"); //$NON-NLS-1$
final int relevance= computeRelevance(prefix, include) + (isDir ? 0 : 1);
final CCompletionProposal proposal= createProposal(repOffset, repLength, repString, dispString, image, relevance, context);
if (!isDir && !needClosingBracket) {
// put cursor behind closing bracket
proposal.setCursorPosition(repString.length() + 1);
}
proposals.add(proposal);
}
}
}
}
/**
* Collect potential include files for the given translation unit.
*
* @param tu the translation unit to include the file
* @param prefixPath the path part to match the sub-directory and file name
* @param angleBrackets whether angle brackets enclose the include file name
* @return an array of incude file names
* @throws CoreException
*/
private String[] collectIncludeFiles(final ITranslationUnit tu, IPath prefixPath, boolean angleBrackets) throws CoreException {
final List<String> includeFiles= new ArrayList<String>();
if (!angleBrackets) {
// search in current directory
IResource resource= tu.getResource();
if (resource != null) {
IContainer parent= resource.getParent();
collectIncludeFilesFromContainer(tu, parent, prefixPath, includeFiles);
} else {
IPath location= tu.getLocation();
if (location != null) {
collectIncludeFilesFromDirectory(tu, location.removeLastSegments(1), prefixPath, includeFiles);
}
}
}
IScannerInfo info= tu.getScannerInfo(true);
if (info != null) {
collectIncludeFilesFromScannerInfo(tu, info, prefixPath, angleBrackets, includeFiles);
}
return includeFiles.toArray(new String[includeFiles.size()]);
}
/**
* @param tu the translation unit to include the file
* @param info the scanner info for this translation unit
* @param prefixPath the path part to match the sub-directory and file name
* @param angleBrackets whether angle brackets enclose the include file name
* @param includeFiles the result list
*/
private void collectIncludeFilesFromScannerInfo(ITranslationUnit tu, IScannerInfo info, IPath prefixPath, boolean angleBrackets, List<String> includeFiles) {
if (!angleBrackets && info instanceof IExtendedScannerInfo) {
IExtendedScannerInfo extendedInfo= (IExtendedScannerInfo) info;
String[] quoteIncludes= extendedInfo.getLocalIncludePath();
if (quoteIncludes != null) {
for (int i = 0; i < quoteIncludes.length; i++) {
IPath includeDir= new Path(quoteIncludes[i]);
collectIncludeFilesFromDirectory(tu, includeDir, prefixPath, includeFiles);
}
}
}
String[] allIncludes= info.getIncludePaths();
for (int i = 0; i < allIncludes.length; i++) {
IPath includeDir= new Path(allIncludes[i]);
collectIncludeFilesFromDirectory(tu, includeDir, prefixPath, includeFiles);
}
}
/**
* Collect include files from the given file system directory.
*
* @param tu the translation unit to include the file
* @param directory the file system path of the directory
* @param prefixPath the path part to match the sub-directory and file name
* @param includeFiles the result list
*/
private void collectIncludeFilesFromDirectory(ITranslationUnit tu, IPath directory, IPath prefixPath, List<String> includeFiles) {
final boolean isCpp= tu.isCXXLanguage();
final String namePrefix;
if (prefixPath.segmentCount() == 0) {
namePrefix= ""; //$NON-NLS-1$
} else if (prefixPath.hasTrailingSeparator()) {
namePrefix= ""; //$NON-NLS-1$
prefixPath= prefixPath.removeTrailingSeparator();
directory= directory.append(prefixPath);
} else {
namePrefix= prefixPath.lastSegment();
prefixPath= prefixPath.removeLastSegments(1);
if (prefixPath.segmentCount() > 0) {
directory= directory.append(prefixPath);
}
}
final File fileDir = directory.toFile();
if (!fileDir.exists()) {
return;
}
final int prefixLength = namePrefix.length();
final IProject project= tu.getCProject().getProject();
File[] files= fileDir.listFiles();
for (int i = 0; i < files.length; i++) {
File file = files[i];
final String name= file.getName();
if (name.length() >= prefixLength && namePrefix.equalsIgnoreCase(name.substring(0, prefixLength))) {
if (file.isFile()) {
if (isCpp) {
if (CoreModel.isValidCXXHeaderUnitName(project, name)) {
includeFiles.add(prefixPath.append(name).toString());
}
} else {
if (CoreModel.isValidCHeaderUnitName(project, name)) {
includeFiles.add(prefixPath.append(name).toString());
}
}
} else if (file.isDirectory()) {
includeFiles.add(prefixPath.append(name).addTrailingSeparator().toString());
}
}
}
}
/**
* Collect include files from the given resource container.
*
* @param tu the translation unit to include the file
* @param parent the resource container
* @param prefixPath the path part to match the sub-directory and file name
* @param includeFiles the result list
* @throws CoreException
*/
private void collectIncludeFilesFromContainer(final ITranslationUnit tu, IContainer parent, IPath prefixPath, final List<String> includeFiles) throws CoreException {
final boolean isCpp= tu.isCXXLanguage();
final String namePrefix;
if (prefixPath.segmentCount() == 0) {
namePrefix= ""; //$NON-NLS-1$
} else if (prefixPath.hasTrailingSeparator()) {
namePrefix= ""; //$NON-NLS-1$
prefixPath= prefixPath.removeTrailingSeparator();
parent= parent.getFolder(prefixPath);
} else {
namePrefix= prefixPath.lastSegment();
prefixPath= prefixPath.removeLastSegments(1);
if (prefixPath.segmentCount() > 0) {
parent= parent.getFolder(prefixPath);
}
}
if (!parent.exists()) {
return;
}
final IPath cPrefixPath= prefixPath;
final int prefixLength = namePrefix.length();
final IProject project= tu.getCProject().getProject();
parent.accept(new IResourceProxyVisitor() {
public boolean visit(IResourceProxy proxy) throws CoreException {
final String name= proxy.getName();
if (name.length() < prefixLength && namePrefix.equalsIgnoreCase(name.substring(0, prefixLength))) {
if (proxy.getType() == IResource.FILE) {
if (isCpp) {
if (CoreModel.isValidCXXHeaderUnitName(project, name)) {
includeFiles.add(cPrefixPath.append(name).toString());
}
} else {
if (CoreModel.isValidCHeaderUnitName(project, name)) {
includeFiles.add(cPrefixPath.append(name).toString());
}
}
} else if (proxy.getType() == IResource.FOLDER) {
includeFiles.add(cPrefixPath.append(name).addTrailingSeparator().toString());
}
}
return false;
}}, 0);
}
/**
* Compute the file name portion in an incomplete include directive.
*
* @param context
* @return the file name portion including the opening bracket or quote
* @throws BadLocationException
*/
private String computeIncludePrefix(CContentAssistInvocationContext context) throws BadLocationException {
IDocument document= context.getDocument();
if (document == null)
return null;
int end= context.getInvocationOffset();
int start= end;
while (--start >= 0) {
final char ch= document.getChar(start);
if (ch == '"' || ch == '<')
break;
}
return document.get(start, end - start);
}
/**
* Compute base relevance depending on quality of name / prefix match.
*
* @param prefix the completion pefix
* @param match the matching identifier
* @return a relevance value inidicating the quality of the name match
*/
protected int computeRelevance(String prefix, String match) {
int baseRelevance= 0;
boolean caseMatch= prefix.length() > 0 && match.startsWith(prefix);
if (caseMatch) {
baseRelevance += RelevanceConstants.CASE_MATCH_RELEVANCE;
}
return baseRelevance;
}
private CCompletionProposal createProposal(int repOffset, int repLength, String repString, String dispString, Image image, int relevance, CContentAssistInvocationContext context) {
return new CCompletionProposal(repString, repOffset, repLength, image, dispString, dispString, relevance, context.getViewer());
}
private Image getImage(ImageDescriptor desc) {
return desc != null ? CUIPlugin.getImageDescriptorRegistry().get(desc) : null;
}
}

View file

@ -103,15 +103,15 @@ public abstract class ParsingBasedProposalComputer implements ICompletionProposa
* @return a relevance value inidicating the quality of the name match
*/
protected int computeBaseRelevance(String prefix, String match) {
int baseRelevance= RelevanceConstants.DEFAULT_TYPE_RELEVANCE;
boolean caseMatch= prefix.length() > 0 && match.startsWith(prefix);
if (caseMatch) {
baseRelevance += RelevanceConstants.CASE_MATCH_RELEVANCE;
return RelevanceConstants.CASE_MATCH_RELEVANCE;
} else {
boolean exactNameMatch= match.equalsIgnoreCase(prefix);
if (exactNameMatch) {
return RelevanceConstants.EXACT_NAME_MATCH_RELEVANCE;
}
}
boolean exactNameMatch= match.equalsIgnoreCase(prefix);
if (exactNameMatch) {
baseRelevance += RelevanceConstants.EXACT_NAME_MATCH_RELEVANCE;
}
return baseRelevance;
return 0;
}
}

View file

@ -34,7 +34,8 @@ public interface RelevanceConstants {
final int NAMESPACE_TYPE_RELEVANCE = 50;
final int ENUMERATOR_TYPE_RELEVANCE = 40;
final int ENUMERATION_TYPE_RELEVANCE = 30;
final int MACRO_TYPE_RELEVANCE = 20;
final int DEFAULT_TYPE_RELEVANCE = 20;
final int MACRO_TYPE_RELEVANCE = 15;
/** Relevance constant for (key-)word proposals */
final int KEYWORD_TYPE_RELEVANCE = 10;
@ -42,5 +43,4 @@ public interface RelevanceConstants {
/** Relevance constant for editor template proposals */
final int TEMPLATE_TYPE_RELEVANCE = 5;
final int DEFAULT_TYPE_RELEVANCE = 0;
}