Skip to content

Commit

Permalink
Consider token to limit the chains that are searched (#2835)
Browse files Browse the repository at this point in the history
- Simplify code by reusing CompletionProposalRequestor to create items
- Add support for javadoc for chain completions
- Improve chain completion considered token so more relevant proposals are shown.
- Add subword match on edge and start
- Improve text computation and properly wait and timeout for chain completions
  • Loading branch information
gayanper committed Sep 3, 2024
1 parent e52c8dd commit 0949cc2
Show file tree
Hide file tree
Showing 143 changed files with 351 additions and 170 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.codeassist.CompletionEngine;
import org.eclipse.jdt.internal.corext.template.java.SignatureUtil;
import org.eclipse.jdt.ls.core.internal.JavaLanguageServerPlugin;
Expand Down Expand Up @@ -397,6 +398,13 @@ private void createMethodProposalLabel(CompletionProposal methodProposal, Comple
} catch (Exception e) {
JavaLanguageServerPlugin.logException(e.getMessage(), e);
}
} else {
// if this is a chain completion proposal, we need to set the filter text to the method name instead of the full completion text.
var chainName = methodProposal.getName();
var index = CharOperation.lastIndexOf('.', chainName);
if(index > -1) {
item.setFilterText(String.valueOf(CharOperation.subarray(chainName, index + 1, chainName.length)));
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ public class CompletionProposalReplacementProvider {
private static final char COMMA = ',';
private static final char LESS = '<';
private static final char GREATER = '>';
private static final char[] CHARS_DOT = new char[] { '.' };
private final ICompilationUnit compilationUnit;
private final int offset;
private final CompletionContext context;
Expand Down Expand Up @@ -148,7 +149,10 @@ public void updateReplacement(CompletionProposal proposal, CompletionItem item,
completionBuffer.append(edit.getNewText());
setInsertReplaceRange(requiredProposal, insertReplaceEdit);
} else {
additionalTextEdits.add(edit);
// skip if its chain completions since qualifier is already in completion.
if(!isChainCompletion(proposal)) {
additionalTextEdits.add(edit);
}
}
break;
default:
Expand Down Expand Up @@ -209,7 +213,6 @@ private String getTextEditText(CompletionProposal proposal, CompletionItem item,
if (!completionBuffer.isEmpty()) {
return completionBuffer.toString();
}

String defaultText = getDefaultTextEditText(item);
int start = proposal.getReplaceStart();
int end = proposal.getReplaceEnd();
Expand Down Expand Up @@ -615,7 +618,19 @@ private void appendMethodNameReplacement(StringBuilder buffer, CompletionProposa
if (proposal.getKind() != CompletionProposal.CONSTRUCTOR_INVOCATION) {
String str = new String(proposal.getName());
if (client.isCompletionSnippetsSupported()) {
str = CompletionUtils.sanitizeCompletion(str);
var coreCompletion = new String(proposal.getCompletion());
if(isChainCompletion(proposal)) {
// add support for chain completion's chain arguments such as array index's or method arguments
// so we add the completion's substring before the last '(' as the name replacement.
int lparenIndex = coreCompletion.lastIndexOf('(');
if(lparenIndex > -1) {
str = coreCompletion.substring(0, lparenIndex);
} else {
str = coreCompletion;
}
} else {
str = CompletionUtils.sanitizeCompletion(str);
}
}
buffer.append(str);
}
Expand Down Expand Up @@ -657,6 +672,7 @@ private void appendGuessingCompletion(StringBuilder buffer, CompletionProposal p
JavaLanguageServerPlugin.logException(e.getMessage(), e);
}
}
final var placeholderOffset = placeholderOffset(buffer);
for (int i= 0; i < count; i++) {
if (i != 0) {
buffer.append(COMMA);
Expand All @@ -674,13 +690,23 @@ private void appendGuessingCompletion(StringBuilder buffer, CompletionProposal p
argument = replace.toCharArray();
}
buffer.append("${");
buffer.append(Integer.toString(i+1));
buffer.append(Integer.toString(i + placeholderOffset));
buffer.append(":");
buffer.append(argument);
buffer.append("}");
}
}

private int placeholderOffset(StringBuilder buffer) {
int count = 1; // start with offset 1
int index = 0;
while ((index = buffer.indexOf("${", index)) != -1) {
count++;
index++;
}
return count;
}

private String[] guessParameters(char[][] parameterNames, CompletionProposal proposal) throws JavaModelException {
int count = parameterNames.length;
String[] result = new String[count];
Expand Down Expand Up @@ -1162,4 +1188,15 @@ private String computeJavaTypeReplacementString(CompletionProposal proposal) {
return qualifiedTypeName;
}

/**
* Return if the given proposal is an chain completion proposal. A chain completion proposal is a proposal that is
* either a METHOD_REF or FIELD_REF and contains a dot in the completion string.
*/
private boolean isChainCompletion(CompletionProposal proposal) {
if(proposal.getKind() == CompletionProposal.FIELD_REF || proposal.getKind() == CompletionProposal.METHOD_REF) {
char[] completion = proposal.getCompletion();
return CharOperation.contains(completion, CHARS_DOT);
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,10 @@ public List<CompletionProposal> getProposals() {
return proposals;
}

public void addAdditionalProposal(CompletionProposal proposals) {
this.proposals.add(proposals);
}

/**
* copied from
* org.eclipse.jdt.ui.text.java.CompletionProposalCollector.isFiltered(CompletionProposal)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,15 +288,16 @@ public boolean isCanceled() {
} else {
ModelBasedCompletionEngine.codeComplete(unit, offset, collector, DefaultWorkingCopyOwner.PRIMARY, subMonitor);
}
// chain completions are added into collector while computing, so we need me compute before adding completion items to proposals.
if (manager.getPreferences().isChainCompletionEnabled() && params.getContext().getTriggerKind() != CompletionTriggerKind.TriggerCharacter) {
ChainCompletionProposalComputer chain = new ChainCompletionProposalComputer(unit, collector, this.isSnippetStringSupported());
chain.computeCompletionProposals();
}
proposals.addAll(collector.getCompletionItems());
if (isSnippetStringSupported() && !UNSUPPORTED_RESOURCES.contains(unit.getResource().getName())) {
proposals.addAll(SnippetCompletionProposal.getSnippets(unit, collector, subMonitor));
}
proposals.addAll(new JavadocCompletionProposal().getProposals(unit, offset, collector, subMonitor));
if (manager.getPreferences().isChainCompletionEnabled() && params.getContext().getTriggerKind() != CompletionTriggerKind.TriggerCharacter) {
ChainCompletionProposalComputer chain = new ChainCompletionProposalComputer(unit, collector, this.isSnippetStringSupported());
proposals.addAll(chain.computeCompletionProposals());
}
} catch (OperationCanceledException e) {
monitor.setCanceled(true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ public CompletionItem resolve(CompletionItem param, IProgressMonitor monitor) {
try {
IType type = unit.getJavaProject().findType(typeName);
if (type != null && proposal.getName() != null) {
String name = String.valueOf(proposal.getName());
String[] paramSigs = CharOperation.NO_STRINGS;
if (proposal instanceof InternalCompletionProposal internalProposal) {
Binding binding = internalProposal.getBinding();
Expand All @@ -232,9 +233,22 @@ public CompletionItem resolve(CompletionItem param, IProgressMonitor monitor) {
parameters[i] = getLowerBound(parameters[i]);
}
paramSigs = parameters;
} else if(proposal.getKind() == CompletionProposal.METHOD_REF ||
proposal.getKind() == CompletionProposal.FIELD_REF) {
// this is mainly for chain completion handling
int dotIndex = name.lastIndexOf('.');
if(dotIndex > -1) {
name = name.substring(dotIndex + 1);
if(proposal.getKind() == CompletionProposal.METHOD_REF) {
String[] parameters = Signature.getParameterTypes(String.valueOf(fix83600(proposal.getSignature())));
for (int i = 0; i < parameters.length; i++) {
parameters[i] = getLowerBound(parameters[i]);
}
paramSigs = parameters;
}
}
}
}
String name = String.valueOf(proposal.getName());
IMethod method = type.getMethod(name, paramSigs);
IMethod[] methods = type.findMethods(method);
if (methods != null && methods.length > 0) {
Expand Down
2 changes: 2 additions & 0 deletions org.eclipse.jdt.ls.target/org.eclipse.jdt.ls.tp.target
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
<unit id="org.mockito.mockito-core" version="0.0.0"/>
<unit id="org.apache.commons.commons-io" version="0.0.0"/>
<unit id="org.eclipse.jdt.apt.pluggable.core" version="0.0.0"/>
<unit id="org.eclipse.pde.junit.runtime" version="0.0.0" />
<unit id="org.eclipse.jdt.junit4.runtime" version="0.0.0" />
<repository location="https://download.eclipse.org/eclipse/updates/4.33-I-builds/I20240820-1800/"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="false" includeMode="planner" includeSource="true" type="InstallableUnit">
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#Sun Aug 04 09:16:52 CEST 2024
gradle.version=7.3.3
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#Sun Aug 04 09:16:51 CEST 2024
gradle.version=7.3.3
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#Sun Aug 04 09:16:52 CEST 2024
gradle.version=7.3.3
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#Sun Aug 04 09:16:52 CEST 2024
gradle.version=7.3.3
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#Sun Aug 04 09:16:51 CEST 2024
gradle.version=7.3.3
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#Sun Aug 04 09:16:49 CEST 2024
gradle.version=7.3.3
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#Sun Aug 04 09:16:51 CEST 2024
gradle.version=7.3.3
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#Sun Aug 04 09:16:51 CEST 2024
gradle.version=7.3.3
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#Sun Aug 04 09:16:50 CEST 2024
gradle.version=7.3.3
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#Sun Aug 04 09:16:51 CEST 2024
gradle.version=7.3.3
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#Sun Aug 04 09:16:51 CEST 2024
gradle.version=7.3.3
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#Sun Aug 04 09:16:53 CEST 2024
gradle.version=7.3.3
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#Sun Aug 04 09:16:52 CEST 2024
gradle.version=7.3.3
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#Sun Aug 04 09:16:53 CEST 2024
gradle.version=7.3.3
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#Sun Aug 04 09:16:53 CEST 2024
gradle.version=7.3.3
Empty file.
Loading

0 comments on commit 0949cc2

Please sign in to comment.