/*******************************************************************************
* Copyright (c) 2000, 2011 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
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.che.ide.ext.java.jdt.internal.corext.codemanipulation;
import org.eclipse.che.ide.ext.java.jdt.compiler.batch.CompilationUnit;
import org.eclipse.che.ide.ext.java.jdt.core.CompletionProposal;
import org.eclipse.che.ide.ext.java.jdt.core.CompletionRequestor;
import org.eclipse.che.ide.ext.java.jdt.core.Flags;
import org.eclipse.che.ide.ext.java.jdt.core.JavaCore;
import org.eclipse.che.ide.ext.java.jdt.core.Signature;
import org.eclipse.che.ide.ext.java.jdt.core.dom.ASTNode;
import org.eclipse.che.ide.ext.java.jdt.core.dom.Javadoc;
import org.eclipse.che.ide.ext.java.jdt.core.dom.Name;
import org.eclipse.che.ide.ext.java.jdt.core.dom.QualifiedName;
import org.eclipse.che.ide.ext.java.jdt.internal.codeassist.CompletionEngine;
import org.eclipse.che.ide.ext.java.jdt.internal.corext.dom.ASTNodes;
import org.eclipse.che.ide.ext.java.jdt.internal.text.correction.NameMatcher;
import org.eclipse.che.ide.ext.java.worker.WorkerMessageHandler;
import org.eclipse.che.ide.ext.java.jdt.text.Document;
import java.util.HashSet;
public class SimilarElementsRequestor extends CompletionRequestor {
public static final int CLASSES = 1 << 1;
public static final int INTERFACES = 1 << 2;
public static final int ANNOTATIONS = 1 << 3;
public static final int ENUMS = 1 << 4;
public static final int VARIABLES = 1 << 5;
public static final int PRIMITIVETYPES = 1 << 6;
public static final int VOIDTYPE = 1 << 7;
public static final int REF_TYPES = CLASSES | INTERFACES | ENUMS | ANNOTATIONS;
public static final int REF_TYPES_AND_VAR = REF_TYPES | VARIABLES;
public static final int ALL_TYPES = PRIMITIVETYPES | REF_TYPES_AND_VAR;
private static final String[] PRIM_TYPES = {"boolean", "byte", "char", "short", "int", "long", "float", "double"};
//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
private int fKind;
private String fName;
private HashSet<SimilarElement> fResult;
public static SimilarElement[] findSimilarElement(Document document,
org.eclipse.che.ide.ext.java.jdt.core.dom.CompilationUnit compilationUnit, Name name,
int kind) {
int pos = name.getStartPosition();
int nArguments = -1;
String identifier = ASTNodes.getSimpleNameIdentifier(name);
String returnType = null;
try {
if (name.isQualifiedName()) {
pos = ((QualifiedName)name).getName().getStartPosition();
} else {
pos = name.getStartPosition() + 1; // first letter must be included, other
if (name.getLength() >= 2)
pos++;
}
Javadoc javadoc = (Javadoc)ASTNodes.getParent(name, ASTNode.JAVADOC);
if (javadoc != null) {
// preparedCU = createPreparedCU(cu, javadoc, name.getStartPosition());
// cu = preparedCU;
}
SimilarElementsRequestor requestor = new SimilarElementsRequestor(identifier, kind, nArguments, returnType);
requestor.setIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, true);
requestor.setIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, true);
requestor.setIgnored(CompletionProposal.KEYWORD, true);
requestor.setIgnored(CompletionProposal.LABEL_REF, true);
requestor.setIgnored(CompletionProposal.METHOD_DECLARATION, true);
requestor.setIgnored(CompletionProposal.PACKAGE_REF, true);
requestor.setIgnored(CompletionProposal.VARIABLE_DECLARATION, true);
requestor.setIgnored(CompletionProposal.METHOD_REF, true);
requestor.setIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, true);
requestor.setIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, true);
requestor.setIgnored(CompletionProposal.FIELD_REF, true);
requestor.setIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, true);
requestor.setIgnored(CompletionProposal.LOCAL_VARIABLE_REF, true);
requestor.setIgnored(CompletionProposal.VARIABLE_DECLARATION, true);
requestor.setIgnored(CompletionProposal.VARIABLE_DECLARATION, true);
requestor.setIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION, true);
requestor.setIgnored(CompletionProposal.METHOD_NAME_REFERENCE, true);
return requestor.process(pos, document, compilationUnit);
} finally {
// if (preparedCU != null)
// {
// preparedCU.discardWorkingCopy();
// }
}
}
// private static ICompilationUnit createPreparedCU(ICompilationUnit cu, Javadoc comment, int wordStart)
// throws JavaModelException
// {
// int startpos = comment.getStartPosition();
// boolean isTopLevel = comment.getParent().getParent() instanceof CompilationUnit;
// char[] content = cu.getBuffer().getCharacters().clone();
// if (isTopLevel && (wordStart + 6 < content.length))
// {
// content[startpos++] = 'i';
// content[startpos++] = 'm';
// content[startpos++] = 'p';
// content[startpos++] = 'o';
// content[startpos++] = 'r';
// content[startpos++] = 't';
// }
// if (wordStart < content.length)
// {
// for (int i = startpos; i < wordStart; i++)
// {
// content[i] = ' ';
// }
// }
//
// /*
// * Explicitly create a new non-shared working copy.
// */
// ICompilationUnit newCU = cu.getWorkingCopy(null);
// newCU.getBuffer().setContents(content);
// return newCU;
// }
//
/**
* Constructor for SimilarElementsRequestor.
*
* @param name
* the name
* @param kind
* the type kind
* @param nArguments
* the number of arguments
* @param preferredType
* the preferred type
*/
private SimilarElementsRequestor(String name, int kind, int nArguments, String preferredType) {
super();
fName = name;
fKind = kind;
fResult = new HashSet<SimilarElement>();
// nArguments and preferredType not yet used
}
private void addResult(SimilarElement elem) {
fResult.add(elem);
}
private SimilarElement[] process(int pos, Document document,
org.eclipse.che.ide.ext.java.jdt.core.dom.CompilationUnit compilationUnit) {
try {
CompletionEngine e =
new CompletionEngine(WorkerMessageHandler.get().getNameEnvironment(), this, JavaCore.getOptions());
e.complete(new CompilationUnit(document.get().toCharArray(), "", "UTF-8"), pos, 0);
processKeywords();
return fResult.toArray(new SimilarElement[fResult.size()]);
} finally {
fResult.clear();
}
}
private boolean isKind(int kind) {
return (fKind & kind) != 0;
}
/** Method addPrimitiveTypes. */
private void processKeywords() {
if (isKind(PRIMITIVETYPES)) {
for (int i = 0; i < PRIM_TYPES.length; i++) {
if (NameMatcher.isSimilarName(fName, PRIM_TYPES[i])) {
addResult(new SimilarElement(PRIMITIVETYPES, PRIM_TYPES[i], 50));
}
}
}
if (isKind(VOIDTYPE)) {
String voidType = "void"; //$NON-NLS-1$
if (NameMatcher.isSimilarName(fName, voidType)) {
addResult(new SimilarElement(PRIMITIVETYPES, voidType, 50));
}
}
}
private static final int getKind(int flags, char[] typeNameSig) {
if (Signature.getTypeSignatureKind(typeNameSig) == Signature.TYPE_VARIABLE_SIGNATURE) {
return VARIABLES;
}
if (Flags.isAnnotation(flags)) {
return ANNOTATIONS;
}
if (Flags.isInterface(flags)) {
return INTERFACES;
}
if (Flags.isEnum(flags)) {
return ENUMS;
}
return CLASSES;
}
private void addType(char[] typeNameSig, int flags, int relevance) {
int kind = getKind(flags, typeNameSig);
if (!isKind(kind)) {
return;
}
String fullName = new String(Signature.toCharArray(Signature.getTypeErasure(typeNameSig)));
//TODO
// if (TypeFilter.isFiltered(fullName))
// {
// return;
// }
if (NameMatcher.isSimilarName(fName, Signature.getSimpleName(fullName))) {
addResult(new SimilarElement(kind, fullName, relevance));
}
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.CompletionRequestor#accept(org.eclipse.jdt.core.CompletionProposal)
*/
@Override
public void accept(CompletionProposal proposal) {
if (proposal.getKind() == CompletionProposal.TYPE_REF) {
addType(proposal.getSignature(), proposal.getFlags(), proposal.getRelevance());
}
}
}