blob: a0d520f732abafbe976fc096018d27ea5666beb1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2017 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
* http://www.eclipse.org/legal/epl-v10.html
*
*******************************************************************************/
package org.eclipse.dltk.core.tests.model;
import java.util.Arrays;
import org.eclipse.dltk.compiler.problem.IProblem;
import org.eclipse.dltk.core.CompletionContext;
import org.eclipse.dltk.core.CompletionProposal;
import org.eclipse.dltk.core.CompletionRequestor;
public class CompletionTestsRequestor2 extends CompletionRequestor {
private final char[] NULL_LITERAL = "null".toCharArray();//$NON-NLS-1$
private CompletionContext context;
public int proposalsPtr = -1;
private final static int PROPOSALS_INCREMENT = 10;
private CompletionProposal[] proposals = new CompletionProposal[PROPOSALS_INCREMENT];
private IProblem problem;
private boolean showParameterNames;
private boolean showUniqueKeys;
private boolean showPositions;
private boolean shortContext;
public boolean fDebug = false;
public CompletionTestsRequestor2() {
this(false, false);
}
public CompletionTestsRequestor2(boolean showParamNames) {
this(showParamNames, false, false);
}
public CompletionTestsRequestor2(boolean showParamNames, boolean showUniqueKeys) {
this(showParamNames, showUniqueKeys, false);
}
public CompletionTestsRequestor2(boolean showParamNames, boolean showUniqueKeys, boolean showPositions) {
this(showParamNames, showUniqueKeys, showPositions, true);
}
public CompletionTestsRequestor2(boolean showParamNames, boolean showUniqueKeys, boolean showPositions, boolean shortContext) {
this.showParameterNames = showParamNames;
this.showUniqueKeys = showUniqueKeys;
this.showPositions = showPositions;
this.shortContext = shortContext;
}
@Override
public void acceptContext(CompletionContext cc) {
this.context = cc;
}
@Override
public void accept(CompletionProposal proposal) {
int length = this.proposals.length;
if (++this.proposalsPtr== length) {
System.arraycopy(this.proposals, 0, this.proposals = new CompletionProposal[length+PROPOSALS_INCREMENT], 0, length);
}
this.proposals[this.proposalsPtr] = proposal;
}
@Override
public void completionFailure(IProblem p) {
this.problem = p;
}
public String getContext() {
if(this.context == null) return "";
StringBuffer buffer = new StringBuffer();
if(!this.shortContext) {
buffer.append("completion offset=");
buffer.append(context.getOffset());
buffer.append('\n');
buffer.append("completion range=[");
buffer.append(context.getTokenStart());
buffer.append(", ");
buffer.append(context.getTokenEnd());
buffer.append("]\n");
char[] token = context.getToken();
buffer.append("completion token=");
if(token == null) {
buffer.append("null");
} else {
buffer.append('\"');
buffer.append(token);
buffer.append('\"');
}
buffer.append('\n');
buffer.append("completion token kind=");
int tokenKind = context.getTokenKind();
if(tokenKind == CompletionContext.TOKEN_KIND_STRING_LITERAL) {
buffer.append("TOKEN_KIND_STRING_LITERAL");
} else if(tokenKind == CompletionContext.TOKEN_KIND_NAME) {
buffer.append("TOKEN_KIND_NAME");
} else {
buffer.append("TOKEN_KIND_UNKNOWN");
}
buffer.append('\n');
}
// char[][] expectedTypesSignatures = this.context.getExpectedTypesSignatures();
// buffer.append("expectedTypesSignatures=");
// if(expectedTypesSignatures == null) {
// buffer.append(NULL_LITERAL);
// } else {
// buffer.append('{');
// for (int i = 0; i < expectedTypesSignatures.length; i++) {
// if(i > 0) buffer.append(',');
// buffer.append(expectedTypesSignatures[i]);
//
// }
// buffer.append('}');
// }
// buffer.append('\n');
//
// char[][] expectedTypesKeys = this.context.getExpectedTypesKeys();
// buffer.append("expectedTypesKeys=");
// if(expectedTypesSignatures == null) {
// buffer.append(NULL_LITERAL);
// } else {
// buffer.append('{');
// for (int i = 0; i < expectedTypesKeys.length; i++) {
// if(i > 0) buffer.append(',');
// buffer.append(expectedTypesKeys[i]);
//
// }
// buffer.append('}');
// }
//buffer.append('\n');
return buffer.toString();
}
public String getProblem() {
return this.problem == null ? "" : this.problem.getMessage();
}
/*
* Get sorted results in ascending order
*/
public String getResults() {
if(this.proposalsPtr < 0) return "";
quickSort(this.proposals, 0, this.proposalsPtr);
return getResultsWithoutSorting();
}
/*
* Get sorted results in ascending order
*/
public String getReversedResults() {
if(this.proposalsPtr < 0) return "";
Arrays.sort(this.proposals, (p1, p2) -> {
int relDif = p2.getRelevance() - p1.getRelevance();
if(relDif != 0) return relDif;
String name1 = getElementName(p1);
String name2 = getElementName(p2);
return name1.compareTo(name2);
});
return getResultsWithoutSorting();
}
/*
* Get unsorted results (ie. same order as they were accepted by requestor)
*/
public String getResultsWithoutSorting() {
if(this.proposalsPtr < 0) return "";
StringBuffer buffer = printProposal(this.proposals[0]);
for(int i = 1; i <=this.proposalsPtr; i++) {
if(i > 0) buffer.append('\n');
buffer.append(printProposal(this.proposals[i]));
}
return buffer.toString();
}
public String[] getStringsResult() {
if(this.proposalsPtr < 0) {
return new String[0];
}
String[] strings = new String[this.proposalsPtr+1];
for (int i=0; i<=this.proposalsPtr; i++) {
strings[i] = printProposal(this.proposals[i]).toString();
}
return strings;
}
protected StringBuffer printProposal(CompletionProposal proposal) {
StringBuffer buffer = new StringBuffer(getElementName(proposal));
buffer.append('[');
switch(proposal.getKind()) {
case CompletionProposal.FIELD_REF :
buffer.append("FIELD_REF"); //$NON-NLS-1$
break;
case CompletionProposal.KEYWORD :
buffer.append("KEYWORD"); //$NON-NLS-1$
break;
case CompletionProposal.LABEL_REF :
buffer.append("LABEL_REF"); //$NON-NLS-1$
break;
case CompletionProposal.LOCAL_VARIABLE_REF :
buffer.append("LOCAL_VARIABLE_REF"); //$NON-NLS-1$
break;
case CompletionProposal.METHOD_DECLARATION :
buffer.append("METHOD_DECLARATION"); //$NON-NLS-1$
if(proposal.isConstructor()) {
buffer.append("<CONSTRUCTOR>"); //$NON-NLS-1$
}
break;
case CompletionProposal.METHOD_REF :
buffer.append("METHOD_REF"); //$NON-NLS-1$
if(proposal.isConstructor()) {
buffer.append("<CONSTRUCTOR>"); //$NON-NLS-1$
}
break;
case CompletionProposal.TYPE_REF :
buffer.append("TYPE_REF"); //$NON-NLS-1$
break;
case CompletionProposal.VARIABLE_DECLARATION :
buffer.append("VARIABLE_DECLARATION"); //$NON-NLS-1$
break;
case CompletionProposal.POTENTIAL_METHOD_DECLARATION :
buffer.append("POTENTIAL_METHOD_DECLARATION"); //$NON-NLS-1$
break;
case CompletionProposal.METHOD_NAME_REFERENCE :
buffer.append("METHOD_IMPORT"); //$NON-NLS-1$
break;
default :
buffer.append("PROPOSAL"); //$NON-NLS-1$
break;
}
buffer.append("]{");
buffer.append(proposal.getCompletion() == null ? NULL_LITERAL : proposal.getCompletion());
buffer.append(", ");
if(this.showUniqueKeys) {
buffer.append(", ");
buffer.append(proposal.getDeclarationKey() == null ? NULL_LITERAL : proposal.getDeclarationKey());
buffer.append(", ");
buffer.append(proposal.getKey() == null ? NULL_LITERAL : proposal.getKey());
}
buffer.append(", ");
buffer.append(proposal.getName() == null ? NULL_LITERAL : proposal.getName());
if(this.showParameterNames) {
String[] parameterNames = proposal.findParameterNames(null);
buffer.append(", ");
if(parameterNames == null || parameterNames.length <= 0) {
buffer.append(NULL_LITERAL);
} else {
buffer.append("(");
for (int i = 0; i < parameterNames.length; i++) {
if(i > 0) buffer.append(", ");
buffer.append(parameterNames[i]);
}
buffer.append(")");
}
}
if(this.showPositions) {
buffer.append(", [");
buffer.append(proposal.getReplaceStart());
buffer.append(", ");
buffer.append(proposal.getReplaceEnd());
buffer.append("]");
}
buffer.append(", ");
buffer.append(proposal.getRelevance());
buffer.append('}');
return buffer;
}
protected CompletionProposal[] quickSort(CompletionProposal[] collection, int left, int right) {
int original_left = left;
int original_right = right;
CompletionProposal mid = collection[ (left + right) / 2];
do {
while (compare(mid, collection[left]) > 0)
// s[left] >= mid
left++;
while (compare(mid, collection[right]) < 0)
// s[right] <= mid
right--;
if (left <= right) {
CompletionProposal tmp = collection[left];
collection[left] = collection[right];
collection[right] = tmp;
left++;
right--;
}
} while (left <= right);
if (original_left < right)
collection = quickSort(collection, original_left, right);
if (left < original_right)
collection = quickSort(collection, left, original_right);
return collection;
}
protected int compare(CompletionProposal proposal1, CompletionProposal proposal2) {
int relDif = proposal1.getRelevance() - proposal2.getRelevance();
if(relDif != 0) {
return relDif;
} else {
String name1 = getElementName(proposal1);
String name2 = getElementName(proposal2);
int nameDif = name1.compareTo(name2);
if(nameDif != 0) {
return nameDif;
} else {
int kindDif = proposal1.getKind() - proposal2.getKind();
if(kindDif != 0) {
return kindDif;
} else {
String completion1 = proposal1.getCompletion();
String completion2 = proposal2.getCompletion();
return completion1.compareTo(completion2);
}
}
}
}
protected String getElementName(CompletionProposal proposal) {
switch(proposal.getKind()) {
case CompletionProposal.TYPE_REF :
case CompletionProposal.FIELD_REF :
case CompletionProposal.KEYWORD:
case CompletionProposal.LABEL_REF:
case CompletionProposal.LOCAL_VARIABLE_REF:
case CompletionProposal.METHOD_REF:
case CompletionProposal.METHOD_DECLARATION:
case CompletionProposal.VARIABLE_DECLARATION:
case CompletionProposal.POTENTIAL_METHOD_DECLARATION:
case CompletionProposal.METHOD_NAME_REFERENCE:
return proposal.getName();
}
return "";
}
@Override
public String toString() {
return getResults();
}
}