1 11 package org.eclipse.jdt.internal.ui.text.java; 12 13 import org.eclipse.text.edits.TextEdit; 14 15 import org.eclipse.core.runtime.CoreException; 16 import org.eclipse.core.runtime.NullProgressMonitor; 17 18 import org.eclipse.jface.preference.IPreferenceStore; 19 20 import org.eclipse.jface.text.BadLocationException; 21 import org.eclipse.jface.text.IDocument; 22 import org.eclipse.jface.text.contentassist.IContextInformation; 23 24 import org.eclipse.jdt.core.CompletionProposal; 25 import org.eclipse.jdt.core.ICompilationUnit; 26 import org.eclipse.jdt.core.IJavaProject; 27 import org.eclipse.jdt.core.IType; 28 import org.eclipse.jdt.core.JavaCore; 29 import org.eclipse.jdt.core.JavaModelException; 30 import org.eclipse.jdt.core.Signature; 31 import org.eclipse.jdt.core.dom.CompilationUnit; 32 import org.eclipse.jdt.core.dom.rewrite.ImportRewrite; 33 34 import org.eclipse.jdt.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext; 35 import org.eclipse.jdt.internal.corext.codemanipulation.StubUtility; 36 import org.eclipse.jdt.internal.corext.util.JavaModelUtil; 37 import org.eclipse.jdt.internal.corext.util.QualifiedTypeNameHistory; 38 39 import org.eclipse.jdt.ui.PreferenceConstants; 40 import org.eclipse.jdt.ui.text.java.JavaContentAssistInvocationContext; 41 42 import org.eclipse.jdt.internal.ui.JavaPlugin; 43 import org.eclipse.jdt.internal.ui.javaeditor.ASTProvider; 44 45 48 public class LazyJavaTypeCompletionProposal extends LazyJavaCompletionProposal { 49 50 protected static final char[] TYPE_TRIGGERS= new char[] { '.', '\t', '[', '(', ' ' }; 51 52 protected static final char[] JDOC_TYPE_TRIGGERS= new char[] { '#', '}', ' ', '.' }; 53 54 55 protected final ICompilationUnit fCompilationUnit; 56 57 private String fQualifiedName; 58 private String fSimpleName; 59 private ImportRewrite fImportRewrite; 60 private ContextSensitiveImportRewriteContext fImportContext; 61 62 public LazyJavaTypeCompletionProposal(CompletionProposal proposal, JavaContentAssistInvocationContext context) { 63 super(proposal, context); 64 fCompilationUnit= context.getCompilationUnit(); 65 fQualifiedName= null; 66 } 67 68 public final String getQualifiedTypeName() { 69 if (fQualifiedName == null) 70 fQualifiedName= String.valueOf(Signature.toCharArray(Signature.getTypeErasure(fProposal.getSignature()))); 71 return fQualifiedName; 72 } 73 74 protected final String getSimpleTypeName() { 75 if (fSimpleName == null) 76 fSimpleName= Signature.getSimpleName(getQualifiedTypeName()); 77 return fSimpleName; 78 } 79 80 83 protected String computeReplacementString() { 84 String replacement= super.computeReplacementString(); 85 86 87 if (isImportCompletion()) 88 return replacement; 89 90 91 if (fProposal.getKind() == CompletionProposal.TYPE_REF && fInvocationContext.getCoreContext().isInJavadocText()) 93 return getSimpleTypeName(); 94 95 String qualifiedTypeName= getQualifiedTypeName(); 96 if (qualifiedTypeName.indexOf('.') == -1) 97 return qualifiedTypeName; 99 100 104 IDocument document= fInvocationContext.getDocument(); 105 if (document != null) { 106 String prefix= getPrefix(document, getReplacementOffset() + getReplacementLength()); 107 int dotIndex= prefix.lastIndexOf('.'); 108 if (dotIndex != -1 && qualifiedTypeName.toLowerCase().startsWith(prefix.substring(0, dotIndex + 1).toLowerCase())) 110 return qualifiedTypeName; 111 } 112 113 117 if (replacement.indexOf('.') == -1) { 118 if (isInJavadoc()) 119 return getSimpleTypeName(); return replacement; 121 } 122 123 124 fImportRewrite= createImportRewrite(); 125 if (fImportRewrite != null) { 126 return fImportRewrite.addImport(qualifiedTypeName, fImportContext); 127 } 128 129 131 132 if (fCompilationUnit != null && JavaModelUtil.isImplicitImport(Signature.getQualifier(qualifiedTypeName), fCompilationUnit)) { 133 return Signature.getSimpleName(qualifiedTypeName); 134 } 135 136 137 return qualifiedTypeName; 138 } 139 140 protected final boolean isImportCompletion() { 141 char[] completion= fProposal.getCompletion(); 142 if (completion.length == 0) 143 return false; 144 145 char last= completion[completion.length - 1]; 146 150 return last == ';' || last == '.'; 151 } 152 153 private ImportRewrite createImportRewrite() { 154 if (fCompilationUnit != null && allowAddingImports()) { 155 try { 156 CompilationUnit cu= getASTRoot(fCompilationUnit); 157 if (cu == null) { 158 ImportRewrite rewrite= StubUtility.createImportRewrite(fCompilationUnit, true); 159 fImportContext= null; 160 return rewrite; 161 } else { 162 ImportRewrite rewrite= StubUtility.createImportRewrite(cu, true); 163 fImportContext= new ContextSensitiveImportRewriteContext(cu, fInvocationContext.getInvocationOffset(), rewrite); 164 return rewrite; 165 } 166 } catch (CoreException x) { 167 JavaPlugin.log(x); 168 } 169 } 170 return null; 171 } 172 173 private CompilationUnit getASTRoot(ICompilationUnit compilationUnit) { 174 return JavaPlugin.getDefault().getASTProvider().getAST(compilationUnit, ASTProvider.WAIT_NO, new NullProgressMonitor()); 175 } 176 177 180 public void apply(IDocument document, char trigger, int offset) { 181 try { 182 boolean insertClosingParenthesis= trigger == '(' && autocloseBrackets(); 183 if (insertClosingParenthesis) { 184 StringBuffer replacement= new StringBuffer (getReplacementString()); 185 updateReplacementWithParentheses(replacement); 186 setReplacementString(replacement.toString()); 187 trigger= '\0'; 188 } 189 190 super.apply(document, trigger, offset); 191 192 if (fImportRewrite != null && fImportRewrite.hasRecordedChanges()) { 193 int oldLen= document.getLength(); 194 fImportRewrite.rewriteImports(new NullProgressMonitor()).apply(document, TextEdit.UPDATE_REGIONS); 195 setReplacementOffset(getReplacementOffset() + document.getLength() - oldLen); 196 } 197 198 if (insertClosingParenthesis) 199 setUpLinkedMode(document, ')'); 200 201 rememberSelection(); 202 } catch (CoreException e) { 203 JavaPlugin.log(e); 204 } catch (BadLocationException e) { 205 JavaPlugin.log(e); 206 } 207 } 208 209 protected void updateReplacementWithParentheses(StringBuffer replacement) { 210 FormatterPrefs prefs= getFormatterPrefs(); 211 212 if (prefs.beforeOpeningParen) 213 replacement.append(SPACE); 214 replacement.append(LPAREN); 215 216 217 if (prefs.afterOpeningParen) 218 replacement.append(SPACE); 219 220 setCursorPosition(replacement.length()); 221 222 if (prefs.afterOpeningParen) 223 replacement.append(SPACE); 224 225 replacement.append(RPAREN); 226 } 227 228 234 protected final void rememberSelection() throws JavaModelException { 235 IType lhs= fInvocationContext.getExpectedType(); 236 IType rhs= (IType) getJavaElement(); 237 if (lhs != null && rhs != null) 238 JavaPlugin.getDefault().getContentAssistHistory().remember(lhs, rhs); 239 240 QualifiedTypeNameHistory.remember(getQualifiedTypeName()); 241 } 242 243 266 protected boolean allowAddingImports() { 267 if (isInJavadoc()) { 268 if (fProposal.getKind() == CompletionProposal.TYPE_REF && fInvocationContext.getCoreContext().isInJavadocText()) 272 return false; 273 274 if (!isJavadocProcessingEnabled()) 275 return false; 276 } 277 278 IPreferenceStore preferenceStore= JavaPlugin.getDefault().getPreferenceStore(); 279 return preferenceStore.getBoolean(PreferenceConstants.CODEASSIST_ADDIMPORT); 280 } 281 282 private boolean isJavadocProcessingEnabled() { 283 IJavaProject project= fCompilationUnit.getJavaProject(); 284 boolean processJavadoc; 285 if (project == null) 286 processJavadoc= JavaCore.ENABLED.equals(JavaCore.getOption(JavaCore.COMPILER_DOC_COMMENT_SUPPORT)); 287 else 288 processJavadoc= JavaCore.ENABLED.equals(project.getOption(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, true)); 289 return processJavadoc; 290 } 291 292 295 protected boolean isValidPrefix(String prefix) { 296 return isPrefix(prefix, getSimpleTypeName()) || isPrefix(prefix, getQualifiedTypeName()); 297 } 298 299 302 public CharSequence getPrefixCompletionText(IDocument document, int completionOffset) { 303 String prefix= getPrefix(document, completionOffset); 304 305 String completion; 306 if (prefix.indexOf('.') != -1) 308 completion= getQualifiedTypeName(); 309 else 310 completion= getSimpleTypeName(); 311 312 if (isCamelCaseMatching()) 313 return getCamelCaseCompound(prefix, completion); 314 315 return completion; 316 } 317 318 321 protected char[] computeTriggerCharacters() { 322 return isInJavadoc() ? JDOC_TYPE_TRIGGERS : TYPE_TRIGGERS; 323 } 324 325 328 protected ProposalInfo computeProposalInfo() { 329 if (fCompilationUnit != null) { 330 IJavaProject project= fCompilationUnit.getJavaProject(); 331 if (project != null) 332 return new TypeProposalInfo(project, fProposal); 333 } 334 return super.computeProposalInfo(); 335 } 336 337 340 protected String computeSortString() { 341 return getSimpleTypeName() + Character.MIN_VALUE + getQualifiedTypeName(); 343 } 344 345 348 protected int computeRelevance() { 349 359 float rhsHistoryRank= fInvocationContext.getHistoryRelevance(getQualifiedTypeName()); 360 float typeHistoryRank= QualifiedTypeNameHistory.getDefault().getNormalizedPosition(getQualifiedTypeName()); 361 362 int recencyBoost= Math.round((rhsHistoryRank + typeHistoryRank) * 5); 363 int rhsBoost= rhsHistoryRank > 0.0f ? 50 : 0; 364 int baseRelevance= super.computeRelevance(); 365 366 return baseRelevance + rhsBoost + recencyBoost; 367 } 368 369 373 protected IContextInformation computeContextInformation() { 374 char[] signature= fProposal.getSignature(); 375 char[][] typeParameters= Signature.getTypeArguments(signature); 376 if (typeParameters.length == 0) 377 return super.computeContextInformation(); 378 379 ProposalContextInformation contextInformation= new ProposalContextInformation(fProposal); 380 if (fContextInformationPosition != 0 && fProposal.getCompletion().length == 0) 381 contextInformation.setContextInformationPosition(fContextInformationPosition); 382 return contextInformation; 383 384 } 385 } 386 | Popular Tags |