1 /*******************************************************************************
2 * Copyright (c) 2000, 2012 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.jdt.internal.ui.text.correction;
13 import java.util.HashSet;
15 import org.eclipse.jdt.core.CompletionProposal;
16 import org.eclipse.jdt.core.CompletionRequestor;
17 import org.eclipse.jdt.core.Flags;
18 import org.eclipse.jdt.core.ICompilationUnit;
19 import org.eclipse.jdt.core.IType;
20 import org.eclipse.jdt.core.JavaModelException;
21 import org.eclipse.jdt.core.Signature;
22 import org.eclipse.jdt.core.dom.ASTNode;
23 import org.eclipse.jdt.core.dom.CompilationUnit;
24 import org.eclipse.jdt.core.dom.Javadoc;
25 import org.eclipse.jdt.core.dom.Name;
26 import org.eclipse.jdt.core.dom.QualifiedName;
28 import org.eclipse.jdt.internal.corext.dom.ASTNodes;
29 import org.eclipse.jdt.internal.corext.util.JavaModelUtil;
30 import org.eclipse.jdt.internal.corext.util.TypeFilter;
32 public class SimilarElementsRequestor extends CompletionRequestor {
34 public static final int CLASSES= 1 << 1;
35 public static final int INTERFACES= 1 << 2;
36 public static final int ANNOTATIONS= 1 << 3;
37 public static final int ENUMS= 1 << 4;
38 public static final int VARIABLES= 1 << 5;
39 public static final int PRIMITIVETYPES= 1 << 6;
40 public static final int VOIDTYPE= 1 << 7;
41 public static final int REF_TYPES= CLASSES | INTERFACES | ENUMS | ANNOTATIONS;
42 public static final int REF_TYPES_AND_VAR= REF_TYPES | VARIABLES;
43 public static final int ALL_TYPES= PRIMITIVETYPES | REF_TYPES_AND_VAR;
45 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$
50 private HashSet<SimilarElement> fResult;
52 public static SimilarElement[] findSimilarElement(ICompilationUnit cu, Name name, int kind) throws JavaModelException {
53 int pos= name.getStartPosition();
56 String identifier= ASTNodes.getSimpleNameIdentifier(name);
57 String returnType= null;
58 ICompilationUnit preparedCU= null;
61 if (name.isQualifiedName()) {
62 pos= ((QualifiedName) name).getName().getStartPosition();
64 pos= name.getStartPosition() + 1; // first letter must be included, other
66 Javadoc javadoc= (Javadoc) ASTNodes.getParent(name, ASTNode.JAVADOC);
67 if (javadoc != null) {
68 preparedCU= createPreparedCU(cu, javadoc, name.getStartPosition());
72 SimilarElementsRequestor requestor= new SimilarElementsRequestor(identifier, kind, nArguments, returnType);
73 requestor.setIgnored(CompletionProposal.ANONYMOUS_CLASS_DECLARATION, true);
74 requestor.setIgnored(CompletionProposal.ANONYMOUS_CLASS_CONSTRUCTOR_INVOCATION, true);
75 requestor.setIgnored(CompletionProposal.KEYWORD, true);
76 requestor.setIgnored(CompletionProposal.LABEL_REF, true);
77 requestor.setIgnored(CompletionProposal.METHOD_DECLARATION, true);
78 requestor.setIgnored(CompletionProposal.PACKAGE_REF, true);
79 requestor.setIgnored(CompletionProposal.VARIABLE_DECLARATION, true);
80 requestor.setIgnored(CompletionProposal.METHOD_REF, true);
81 requestor.setIgnored(CompletionProposal.CONSTRUCTOR_INVOCATION, true);
82 requestor.setIgnored(CompletionProposal.METHOD_REF_WITH_CASTED_RECEIVER, true);
83 requestor.setIgnored(CompletionProposal.FIELD_REF, true);
84 requestor.setIgnored(CompletionProposal.FIELD_REF_WITH_CASTED_RECEIVER, true);
85 requestor.setIgnored(CompletionProposal.LOCAL_VARIABLE_REF, true);
86 requestor.setIgnored(CompletionProposal.VARIABLE_DECLARATION, true);
87 requestor.setIgnored(CompletionProposal.VARIABLE_DECLARATION, true);
88 requestor.setIgnored(CompletionProposal.POTENTIAL_METHOD_DECLARATION, true);
89 requestor.setIgnored(CompletionProposal.METHOD_NAME_REFERENCE, true);
90 return requestor.process(cu, pos);
92 if (preparedCU != null) {
93 preparedCU.discardWorkingCopy();
98 private static ICompilationUnit createPreparedCU(ICompilationUnit cu, Javadoc comment, int wordStart) throws JavaModelException {
99 int startpos= comment.getStartPosition();
100 boolean isTopLevel= comment.getParent().getParent() instanceof CompilationUnit;
101 char[] content= cu.getBuffer().getCharacters().clone();
102 if (isTopLevel && (wordStart + 6 < content.length)) {
103 content[startpos++]= 'i'; content[startpos++]= 'm'; content[startpos++]= 'p';
104 content[startpos++]= 'o'; content[startpos++]= 'r'; content[startpos++]= 't';
106 if (wordStart < content.length) {
107 for (int i= startpos; i < wordStart; i++) {
113 * Explicitly create a new non-shared working copy.
115 ICompilationUnit newCU= cu.getWorkingCopy(null);
116 newCU.getBuffer().setContents(content);
122 * Constructor for SimilarElementsRequestor.
123 * @param name the name
124 * @param kind the type kind
125 * @param nArguments the number of arguments
126 * @param preferredType the preferred type
128 private SimilarElementsRequestor(String name, int kind, int nArguments, String preferredType) {
133 fResult= new HashSet<SimilarElement>();
134 // nArguments and preferredType not yet used
137 private void addResult(SimilarElement elem) {
141 private SimilarElement[] process(ICompilationUnit cu, int pos) throws JavaModelException {
143 cu.codeComplete(pos, this);
145 return fResult.toArray(new SimilarElement[fResult.size()]);
151 private boolean isKind(int kind) {
152 return (fKind & kind) != 0;
156 * Method addPrimitiveTypes.
158 private void processKeywords() {
159 if (isKind(PRIMITIVETYPES)) {
160 for (int i= 0; i < PRIM_TYPES.length; i++) {
161 if (NameMatcher.isSimilarName(fName, PRIM_TYPES[i])) {
162 addResult(new SimilarElement(PRIMITIVETYPES, PRIM_TYPES[i], 50));
166 if (isKind(VOIDTYPE)) {
167 String voidType= "void"; //$NON-NLS-1$
168 if (NameMatcher.isSimilarName(fName, voidType)) {
169 addResult(new SimilarElement(PRIMITIVETYPES, voidType, 50));
174 private static final int getKind(int flags, char[] typeNameSig) {
175 if (Signature.getTypeSignatureKind(typeNameSig) == Signature.TYPE_VARIABLE_SIGNATURE) {
178 if (Flags.isAnnotation(flags)) {
181 if (Flags.isInterface(flags)) {
184 if (Flags.isEnum(flags)) {
191 private void addType(char[] typeNameSig, int flags, int relevance) {
192 int kind= getKind(flags, typeNameSig);
196 String fullName= new String(Signature.toCharArray(Signature.getTypeErasure(typeNameSig)));
197 if (TypeFilter.isFiltered(fullName)) {
200 if (NameMatcher.isSimilarName(fName, Signature.getSimpleName(fullName))) {
201 addResult(new SimilarElement(kind, fullName, relevance));
207 * @see org.eclipse.jdt.core.CompletionRequestor#accept(org.eclipse.jdt.core.CompletionProposal)
210 public void accept(CompletionProposal proposal) {
211 if (proposal.getKind() == CompletionProposal.TYPE_REF) {
212 addType(proposal.getSignature(), proposal.getFlags(), proposal.getRelevance());
217 public static String[] getStaticImportFavorites(ICompilationUnit cu, final String elementName, boolean isMethod, String[] favorites) throws JavaModelException {
218 StringBuffer dummyCU= new StringBuffer();
219 String packName= cu.getParent().getElementName();
220 IType type= cu.findPrimaryType();
222 return new String[0];
224 if (packName.length() > 0) {
225 dummyCU.append("package ").append(packName).append(';'); //$NON-NLS-1$
227 dummyCU.append("public class ").append(type.getElementName()).append("{\n static {\n").append(elementName); // static initializer //$NON-NLS-1$//$NON-NLS-2$
228 int offset= dummyCU.length();
229 dummyCU.append("\n}\n }"); //$NON-NLS-1$
231 ICompilationUnit newCU= null;
233 newCU= cu.getWorkingCopy(null);
234 newCU.getBuffer().setContents(dummyCU.toString());
236 final HashSet<String> result= new HashSet<String>();
238 CompletionRequestor requestor= new CompletionRequestor(true) {
240 public void accept(CompletionProposal proposal) {
241 if (elementName.equals(new String(proposal.getName()))) {
242 CompletionProposal[] requiredProposals= proposal.getRequiredProposals();
243 for (int i= 0; i < requiredProposals.length; i++) {
244 CompletionProposal curr= requiredProposals[i];
245 if (curr.getKind() == CompletionProposal.METHOD_IMPORT || curr.getKind() == CompletionProposal.FIELD_IMPORT) {
246 result.add(JavaModelUtil.concatenateName(Signature.toCharArray(curr.getDeclarationSignature()), curr.getName()));
254 requestor.setIgnored(CompletionProposal.METHOD_REF, false);
255 requestor.setAllowsRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.METHOD_IMPORT, true);
257 requestor.setIgnored(CompletionProposal.FIELD_REF, false);
258 requestor.setAllowsRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.FIELD_IMPORT, true);
260 requestor.setFavoriteReferences(favorites);
262 newCU.codeComplete(offset, requestor);
264 return result.toArray(new String[result.size()]);
267 newCU.discardWorkingCopy();