1 11 package org.eclipse.jdt.internal.ui.text.java; 12 13 import java.util.ArrayList ; 14 import java.util.List ; 15 16 import org.eclipse.text.edits.MalformedTreeException; 17 import org.eclipse.text.edits.TextEdit; 18 19 import org.eclipse.core.runtime.Assert; 20 import org.eclipse.core.runtime.CoreException; 21 import org.eclipse.core.runtime.IProgressMonitor; 22 import org.eclipse.core.runtime.NullProgressMonitor; 23 24 import org.eclipse.swt.graphics.Image; 25 26 import org.eclipse.jface.window.Window; 27 28 import org.eclipse.jface.text.BadLocationException; 29 import org.eclipse.jface.text.Document; 30 import org.eclipse.jface.text.IDocument; 31 import org.eclipse.jface.text.IRegion; 32 import org.eclipse.jface.text.TextUtilities; 33 import org.eclipse.jface.text.contentassist.ICompletionProposalExtension4; 34 35 import org.eclipse.jdt.core.ICompilationUnit; 36 import org.eclipse.jdt.core.IJavaProject; 37 import org.eclipse.jdt.core.ISourceRange; 38 import org.eclipse.jdt.core.IType; 39 import org.eclipse.jdt.core.JavaModelException; 40 import org.eclipse.jdt.core.Signature; 41 import org.eclipse.jdt.core.dom.AST; 42 import org.eclipse.jdt.core.dom.ASTParser; 43 import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; 44 import org.eclipse.jdt.core.dom.CompilationUnit; 45 import org.eclipse.jdt.core.dom.IBinding; 46 import org.eclipse.jdt.core.dom.IMethodBinding; 47 import org.eclipse.jdt.core.dom.ITypeBinding; 48 import org.eclipse.jdt.core.dom.MethodDeclaration; 49 import org.eclipse.jdt.core.dom.Modifier; 50 import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; 51 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; 52 import org.eclipse.jdt.core.dom.rewrite.ListRewrite; 53 import org.eclipse.jdt.core.formatter.CodeFormatter; 54 55 import org.eclipse.jdt.internal.corext.codemanipulation.CodeGenerationSettings; 56 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility2; 57 import org.eclipse.jdt.internal.corext.dom.ASTNodes; 58 import org.eclipse.jdt.internal.corext.dom.NodeFinder; 59 import org.eclipse.jdt.internal.corext.template.java.SignatureUtil; 60 import org.eclipse.jdt.internal.corext.util.CodeFormatterUtil; 61 import org.eclipse.jdt.internal.corext.util.JavaModelUtil; 62 import org.eclipse.jdt.internal.corext.util.Strings; 63 64 import org.eclipse.jdt.internal.ui.JavaPlugin; 65 import org.eclipse.jdt.internal.ui.JavaPluginImages; 66 import org.eclipse.jdt.internal.ui.dialogs.OverrideMethodDialog; 67 import org.eclipse.jdt.internal.ui.preferences.JavaPreferencesSettings; 68 69 public class AnonymousTypeCompletionProposal extends JavaTypeCompletionProposal implements ICompletionProposalExtension4 { 70 71 private String fDeclarationSignature; 72 private IType fSuperType; 73 74 public AnonymousTypeCompletionProposal(IJavaProject jproject, ICompilationUnit cu, int start, int length, String constructorCompletion, String displayName, String declarationSignature, int relevance) { 75 super(constructorCompletion, cu, start, length, null, displayName, relevance); 76 Assert.isNotNull(declarationSignature); 77 Assert.isNotNull(jproject); 78 Assert.isNotNull(cu); 79 80 fDeclarationSignature= declarationSignature; 81 fSuperType= getDeclaringType(jproject, SignatureUtil.stripSignatureToFQN(String.valueOf(declarationSignature))); 82 83 setImage(getImageForType(fSuperType)); 84 setCursorPosition(constructorCompletion.indexOf('(') + 1); 85 } 86 87 private int createDummy(String name, StringBuffer buffer) throws JavaModelException { 88 String lineDelim= "\n"; buffer.append("class "); buffer.append(name); 91 if (fSuperType.isInterface()) 92 buffer.append(" implements "); else 94 buffer.append(" extends "); if (fDeclarationSignature != null) 96 buffer.append(Signature.toString(fDeclarationSignature)); 97 else 98 buffer.append(fSuperType.getFullyQualifiedParameterizedName()); 99 int start= buffer.length(); 100 buffer.append("{"); buffer.append(lineDelim); 102 buffer.append(lineDelim); 103 buffer.append("}"); return start; 105 } 106 107 private boolean createStubs(StringBuffer buffer, ImportRewrite importRewrite) throws CoreException { 108 if (importRewrite == null) 109 return false; 110 if (fSuperType == null) 111 return true; 112 ICompilationUnit copy= null; 113 try { 114 final String name= "Type" + System.currentTimeMillis(); copy= fCompilationUnit.getPrimary().getWorkingCopy(null); 116 final StringBuffer contents= new StringBuffer (); 117 int start= 0; 118 int end= 0; 119 ISourceRange range= fSuperType.getSourceRange(); 120 final boolean sameUnit= range != null && fCompilationUnit.equals(fSuperType.getCompilationUnit()); 121 final StringBuffer dummy= new StringBuffer (); 122 final int length= createDummy(name, dummy); 123 contents.append(fCompilationUnit.getBuffer().getContents()); 124 if (sameUnit) { 125 final int size= range.getOffset() + range.getLength(); 126 start= size + length; 127 end= contents.length() - size; 128 contents.insert(size, dummy.toString()); 129 } else { 130 range= fCompilationUnit.getTypes()[0].getSourceRange(); 131 start= range.getOffset() + length; 132 end= contents.length() - range.getOffset(); 133 contents.insert(range.getOffset(), dummy.toString()); 134 } 135 copy.getBuffer().setContents(contents.toString()); 136 JavaModelUtil.reconcile(copy); 137 final ASTParser parser= ASTParser.newParser(AST.JLS3); 138 parser.setResolveBindings(true); 139 parser.setSource(copy); 140 final CompilationUnit unit= (CompilationUnit) parser.createAST(new NullProgressMonitor()); 141 IType type= null; 142 IType[] types= copy.getAllTypes(); 143 for (int index= 0; index < types.length; index++) { 144 IType result= types[index]; 145 if (result.getElementName().equals(name)) { 146 type= result; 147 break; 148 } 149 } 150 if (type != null && type.exists()) { 151 ITypeBinding binding= null; 152 final AbstractTypeDeclaration declaration= (AbstractTypeDeclaration) ASTNodes.getParent(NodeFinder.perform(unit, type.getNameRange()), AbstractTypeDeclaration.class); 153 if (declaration != null) { 154 binding= declaration.resolveBinding(); 155 if (binding != null) { 156 IMethodBinding[] bindings= StubUtility2.getOverridableMethods(unit.getAST(), binding, true); 157 CodeGenerationSettings settings= JavaPreferencesSettings.getCodeGenerationSettings(fSuperType.getJavaProject()); 158 String [] keys= null; 159 if (!fSuperType.isInterface() && !fSuperType.isAnnotation()) { 160 OverrideMethodDialog dialog= new OverrideMethodDialog(JavaPlugin.getActiveWorkbenchShell(), null, type, true); 161 dialog.setGenerateComment(false); 162 dialog.setElementPositionEnabled(false); 163 if (dialog.open() == Window.OK) { 164 Object [] selection= dialog.getResult(); 165 if (selection != null) { 166 ArrayList result= new ArrayList (selection.length); 167 for (int index= 0; index < selection.length; index++) { 168 if (selection[index] instanceof IMethodBinding) 169 result.add(((IBinding) selection[index]).getKey()); 170 } 171 keys= (String []) result.toArray(new String [result.size()]); 172 settings.createComments= dialog.getGenerateComment(); 173 } 174 } 175 } else { 176 settings.createComments= false; 177 List list= new ArrayList (); 178 for (int index= 0; index < bindings.length; index++) { 179 if (Modifier.isAbstract(bindings[index].getModifiers())) 180 list.add(bindings[index].getKey()); 181 } 182 keys= (String []) list.toArray(new String [list.size()]); 183 } 184 if (keys == null) { 185 setReplacementString(""); setReplacementLength(0); 187 return false; 188 } 189 ASTRewrite rewrite= ASTRewrite.create(unit.getAST()); 190 ListRewrite rewriter= rewrite.getListRewrite(declaration, declaration.getBodyDeclarationsProperty()); 191 String key= null; 192 MethodDeclaration stub= null; 193 for (int index= 0; index < keys.length; index++) { 194 key= keys[index]; 195 for (int offset= 0; offset < bindings.length; offset++) { 196 if (key.equals(bindings[offset].getKey())) { 197 stub= StubUtility2.createImplementationStub(copy, rewrite, importRewrite, bindings[offset], binding.getName(), binding.isInterface(), settings); 198 if (stub != null) 199 rewriter.insertFirst(stub, null); 200 break; 201 } 202 } 203 } 204 IDocument document= new Document(copy.getBuffer().getContents()); 205 try { 206 rewrite.rewriteAST(document, fCompilationUnit.getJavaProject().getOptions(true)).apply(document, TextEdit.UPDATE_REGIONS); 207 buffer.append(document.get(start, document.getLength() - start - end)); 208 } catch (MalformedTreeException exception) { 209 JavaPlugin.log(exception); 210 } catch (BadLocationException exception) { 211 JavaPlugin.log(exception); 212 } 213 } 214 } 215 } 216 return true; 217 } finally { 218 if (copy != null) 219 copy.discardWorkingCopy(); 220 } 221 } 222 223 private IType getDeclaringType(IJavaProject project, String typeName) { 224 try { 225 return project.findType(typeName, (IProgressMonitor) null); 226 } catch (JavaModelException e) { 227 JavaPlugin.log(e); 228 } 229 return null; 230 } 231 232 private Image getImageForType(IType type) { 233 String imageName= JavaPluginImages.IMG_OBJS_CLASS; if (type != null) { 235 try { 236 if (type.isAnnotation()) { 237 imageName= JavaPluginImages.IMG_OBJS_ANNOTATION; 238 } else if (type.isInterface()) { 239 imageName= JavaPluginImages.IMG_OBJS_INTERFACE; 240 } 241 } catch (JavaModelException e) { 242 JavaPlugin.log(e); 243 } 244 } 245 return JavaPluginImages.get(imageName); 246 } 247 248 251 public boolean isAutoInsertable() { 252 return false; 253 } 254 255 protected boolean updateReplacementString(IDocument document, char trigger, int offset, ImportRewrite impRewrite) throws CoreException, BadLocationException { 256 String replacementString= getReplacementString(); 257 258 StringBuffer buf= new StringBuffer ("new A("); buf.append(replacementString); 261 262 if (!replacementString.endsWith(")")) { buf.append(')'); 264 } 265 266 if (!createStubs(buf, impRewrite)) { 267 return false; 268 } 269 if (document.getChar(offset) != ')') 270 buf.append(';'); 271 272 String lineDelim= TextUtilities.getDefaultLineDelimiter(document); 274 final IJavaProject project= fCompilationUnit.getJavaProject(); 275 IRegion region= document.getLineInformationOfOffset(getReplacementOffset()); 276 int indent= Strings.computeIndentUnits(document.get(region.getOffset(), region.getLength()), project); 277 278 String replacement= CodeFormatterUtil.format(CodeFormatter.K_EXPRESSION, buf.toString(), 0, null, lineDelim, project); 279 replacement= Strings.changeIndent(replacement, 0, project, CodeFormatterUtil.createIndentString(indent, project), lineDelim); 280 setReplacementString(replacement.substring(replacement.indexOf('(') + 1)); 281 282 int pos= offset; 283 while (pos < document.getLength() && Character.isWhitespace(document.getChar(pos))) { 284 pos++; 285 } 286 287 if (pos < document.getLength() && document.getChar(pos) == ')') { 288 setReplacementLength(pos - offset + 1); 289 } 290 return true; 291 } 292 } 293 | Popular Tags |