]> git.uio.no Git - ifi-stolz-refaktor.git/blob - case-study/jdt-before/ui/org/eclipse/jdt/internal/ui/text/correction/SimilarElementsRequestor.java
Case Study: adding data and statistics
[ifi-stolz-refaktor.git] / case-study / jdt-before / ui / org / eclipse / jdt / internal / ui / text / correction / SimilarElementsRequestor.java
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
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package org.eclipse.jdt.internal.ui.text.correction;
12
13 import java.util.HashSet;
14
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;
27
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;
31
32 public class SimilarElementsRequestor extends CompletionRequestor {
33
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;
44
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$
46
47         private int fKind;
48         private String fName;
49
50         private HashSet<SimilarElement> fResult;
51
52         public static SimilarElement[] findSimilarElement(ICompilationUnit cu, Name name, int kind) throws JavaModelException {
53                 int pos= name.getStartPosition();
54                 int nArguments= -1;
55
56                 String identifier= ASTNodes.getSimpleNameIdentifier(name);
57                 String returnType= null;
58                 ICompilationUnit preparedCU= null;
59
60                 try {
61                         if (name.isQualifiedName()) {
62                                 pos= ((QualifiedName) name).getName().getStartPosition();
63                         } else {
64                                 pos= name.getStartPosition() + 1; // first letter must be included, other
65                         }
66                         Javadoc javadoc=  (Javadoc) ASTNodes.getParent(name, ASTNode.JAVADOC);
67                         if (javadoc != null) {
68                                 preparedCU= createPreparedCU(cu, javadoc, name.getStartPosition());
69                                 cu= preparedCU;
70                         }
71
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);
91                 } finally {
92                         if (preparedCU != null) {
93                                 preparedCU.discardWorkingCopy();
94                         }
95                 }
96         }
97
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';
105                 }
106                 if (wordStart < content.length) {
107                         for (int i= startpos; i < wordStart; i++) {
108                                 content[i]= ' ';
109                         }
110                 }
111
112                 /*
113                  * Explicitly create a new non-shared working copy.
114                  */
115                 ICompilationUnit newCU= cu.getWorkingCopy(null);
116                 newCU.getBuffer().setContents(content);
117                 return newCU;
118         }
119
120
121         /**
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
127          */
128         private SimilarElementsRequestor(String name, int kind, int nArguments, String preferredType) {
129                 super();
130                 fName= name;
131                 fKind= kind;
132
133                 fResult= new HashSet<SimilarElement>();
134                 // nArguments and preferredType not yet used
135         }
136
137         private void addResult(SimilarElement elem) {
138                 fResult.add(elem);
139         }
140
141         private SimilarElement[] process(ICompilationUnit cu, int pos) throws JavaModelException {
142                 try {
143                         cu.codeComplete(pos, this);
144                         processKeywords();
145                         return fResult.toArray(new SimilarElement[fResult.size()]);
146                 } finally {
147                         fResult.clear();
148                 }
149         }
150
151         private boolean isKind(int kind) {
152                 return (fKind & kind) != 0;
153         }
154
155         /**
156          * Method addPrimitiveTypes.
157          */
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));
163                                 }
164                         }
165                 }
166                 if (isKind(VOIDTYPE)) {
167                         String voidType= "void"; //$NON-NLS-1$
168                         if (NameMatcher.isSimilarName(fName, voidType)) {
169                                 addResult(new SimilarElement(PRIMITIVETYPES, voidType, 50));
170                         }
171                 }
172         }
173
174         private static final int getKind(int flags, char[] typeNameSig) {
175                 if (Signature.getTypeSignatureKind(typeNameSig) == Signature.TYPE_VARIABLE_SIGNATURE) {
176                         return VARIABLES;
177                 }
178                 if (Flags.isAnnotation(flags)) {
179                         return ANNOTATIONS;
180                 }
181                 if (Flags.isInterface(flags)) {
182                         return INTERFACES;
183                 }
184                 if (Flags.isEnum(flags)) {
185                         return ENUMS;
186                 }
187                 return CLASSES;
188         }
189
190
191         private void addType(char[] typeNameSig, int flags, int relevance) {
192                 int kind= getKind(flags, typeNameSig);
193                 if (!isKind(kind)) {
194                         return;
195                 }
196                 String fullName= new String(Signature.toCharArray(Signature.getTypeErasure(typeNameSig)));
197                 if (TypeFilter.isFiltered(fullName)) {
198                         return;
199                 }
200                 if (NameMatcher.isSimilarName(fName, Signature.getSimpleName(fullName))) {
201                         addResult(new SimilarElement(kind, fullName, relevance));
202                 }
203         }
204
205
206         /* (non-Javadoc)
207          * @see org.eclipse.jdt.core.CompletionRequestor#accept(org.eclipse.jdt.core.CompletionProposal)
208          */
209         @Override
210         public void accept(CompletionProposal proposal) {
211                 if (proposal.getKind() == CompletionProposal.TYPE_REF) {
212                         addType(proposal.getSignature(), proposal.getFlags(), proposal.getRelevance());
213                 }
214         }
215         
216         
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();
221                 if (type == null)
222                         return new String[0];
223                 
224                 if (packName.length() > 0) {
225                         dummyCU.append("package ").append(packName).append(';'); //$NON-NLS-1$
226                 }               
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$
230                 
231                 ICompilationUnit newCU= null;
232                 try {
233                         newCU= cu.getWorkingCopy(null);
234                         newCU.getBuffer().setContents(dummyCU.toString());
235                         
236                         final HashSet<String> result= new HashSet<String>();
237                         
238                         CompletionRequestor requestor= new CompletionRequestor(true) {
239                                 @Override
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()));
247                                                         }
248                                                 }
249                                         }
250                                 }
251                         };
252                         
253                         if (isMethod) {
254                                 requestor.setIgnored(CompletionProposal.METHOD_REF, false);
255                                 requestor.setAllowsRequiredProposals(CompletionProposal.METHOD_REF, CompletionProposal.METHOD_IMPORT, true);
256                         } else {
257                                 requestor.setIgnored(CompletionProposal.FIELD_REF, false);
258                                 requestor.setAllowsRequiredProposals(CompletionProposal.FIELD_REF, CompletionProposal.FIELD_IMPORT, true);
259                         }
260                         requestor.setFavoriteReferences(favorites);
261                         
262                         newCU.codeComplete(offset, requestor);
263                         
264                         return result.toArray(new String[result.size()]);
265                 } finally {
266                         if (newCU != null) {
267                                 newCU.discardWorkingCopy();
268                         }       
269                 }       
270         }
271
272         
273 }