1 /*******************************************************************************
2 * Copyright (c) 2005, 2009 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.ui.text.java;
13 import java.util.ArrayList;
15 import org.eclipse.core.runtime.Assert;
17 import org.eclipse.jface.text.BadLocationException;
18 import org.eclipse.jface.text.IDocument;
19 import org.eclipse.jface.text.ITextViewer;
20 import org.eclipse.jface.text.TextUtilities;
21 import org.eclipse.jface.text.contentassist.IContextInformation;
23 import org.eclipse.ui.IEditorPart;
25 import org.eclipse.jdt.core.CompletionContext;
26 import org.eclipse.jdt.core.CompletionProposal;
27 import org.eclipse.jdt.core.ICodeAssist;
28 import org.eclipse.jdt.core.ICompilationUnit;
29 import org.eclipse.jdt.core.IJavaElement;
30 import org.eclipse.jdt.core.IJavaProject;
31 import org.eclipse.jdt.core.IType;
32 import org.eclipse.jdt.core.JavaModelException;
33 import org.eclipse.jdt.core.Signature;
35 import org.eclipse.jdt.internal.corext.template.java.SignatureUtil;
37 import org.eclipse.jdt.ui.PreferenceConstants;
38 import org.eclipse.jdt.ui.text.IJavaPartitions;
40 import org.eclipse.jdt.internal.ui.JavaPlugin;
41 import org.eclipse.jdt.internal.ui.javaeditor.EditorUtility;
42 import org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal;
43 import org.eclipse.jdt.internal.ui.text.java.ContentAssistHistory.RHSHistory;
44 import org.eclipse.jdt.internal.ui.text.java.FillArgumentNamesCompletionProposalCollector;
45 import org.eclipse.jdt.internal.ui.text.java.ImportCompletionProposal;
46 import org.eclipse.jdt.internal.ui.text.java.JavaTypeCompletionProposalComputer;
47 import org.eclipse.jdt.internal.ui.text.java.LazyGenericTypeProposal;
48 import org.eclipse.jdt.internal.ui.text.java.LazyJavaTypeCompletionProposal;
49 import org.eclipse.jdt.internal.ui.text.java.SWTTemplateCompletionProposalComputer;
50 import org.eclipse.jdt.internal.ui.text.java.TemplateCompletionProposalComputer;
51 import org.eclipse.jdt.internal.ui.text.javadoc.LegacyJavadocCompletionProposalComputer;
52 import org.eclipse.jdt.internal.ui.text.template.contentassist.TemplateEngine;
55 * Describes the context of a content assist invocation in a Java editor.
57 * Clients may use but not subclass this class.
62 * @noextend This class is not intended to be subclassed by clients.
64 public class JavaContentAssistInvocationContext extends ContentAssistInvocationContext {
65 private final IEditorPart fEditor;
67 private ICompilationUnit fCU= null;
68 private boolean fCUComputed= false;
70 CompletionProposalLabelProvider fLabelProvider;
71 private CompletionProposalCollector fCollector;
72 private RHSHistory fRHSHistory;
75 IJavaCompletionProposal[] fKeywordProposals= null;
76 CompletionContext fCoreContext= null;
79 * Creates a new context.
81 * @param viewer the viewer used by the editor
82 * @param offset the invocation offset
83 * @param editor the editor that content assist is invoked in
85 public JavaContentAssistInvocationContext(ITextViewer viewer, int offset, IEditorPart editor) {
86 super(viewer, offset);
87 Assert.isNotNull(editor);
92 * Creates a new context.
94 * @param unit the compilation unit in <code>document</code>
96 public JavaContentAssistInvocationContext(ICompilationUnit unit) {
104 * Returns the compilation unit that content assist is invoked in, <code>null</code> if there
107 * @return the compilation unit that content assist is invoked in, possibly <code>null</code>
109 public ICompilationUnit getCompilationUnit() {
112 if (fCollector != null)
113 fCU= fCollector.getCompilationUnit();
115 IJavaElement je= EditorUtility.getEditorInputJavaElement(fEditor, false);
116 if (je instanceof ICompilationUnit)
117 fCU= (ICompilationUnit)je;
124 * Returns the project of the compilation unit that content assist is invoked in,
125 * <code>null</code> if none.
127 * @return the current java project, possibly <code>null</code>
129 public IJavaProject getProject() {
130 ICompilationUnit unit= getCompilationUnit();
131 return unit == null ? null : unit.getJavaProject();
135 * Returns the keyword proposals that are available in this context, possibly none.
137 * <strong>Note:</strong> This method may run
138 * {@linkplain ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor) codeComplete}
139 * on the compilation unit.
142 * @return the available keyword proposals
144 public IJavaCompletionProposal[] getKeywordProposals() {
145 if (fKeywordProposals == null) {
146 if (fCollector != null && !fCollector.isIgnored(CompletionProposal.KEYWORD) && fCollector.getContext() != null) {
147 // use the existing collector if it exists, collects keywords, and has already been invoked
148 fKeywordProposals= fCollector.getKeywordCompletionProposals();
150 // otherwise, retrieve keywords ourselves
151 computeKeywordsAndContext();
155 return fKeywordProposals;
159 * Returns the {@link CompletionContext core completion context} if available, <code>null</code>
162 * <strong>Note:</strong> This method may run
163 * {@linkplain ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor) codeComplete}
164 * on the compilation unit.
167 * @return the core completion context if available, <code>null</code> otherwise
169 public CompletionContext getCoreContext() {
170 if (fCollector != null) {
171 CompletionContext context= fCollector.getContext();
172 if (context != null) {
173 if (fCoreContext == null)
174 fCoreContext= context;
179 if (fCoreContext == null)
180 computeKeywordsAndContext(); // Retrieve the context ourselves
186 * Returns an float in [0.0, 1.0] based on whether the type has been recently used as a
187 * right hand side for the type expected in the current context. 0 signals that the
188 * <code>qualifiedTypeName</code> does not match the expected type, while 1.0 signals that
189 * <code>qualifiedTypeName</code> has most recently been used in a similar context.
191 * <strong>Note:</strong> This method may run
192 * {@linkplain ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor) codeComplete}
193 * on the compilation unit.
196 * @param qualifiedTypeName the type name of the type of interest
197 * @return a relevance in [0.0, 1.0] based on previous content assist invocations
199 public float getHistoryRelevance(String qualifiedTypeName) {
200 return getRHSHistory().getRank(qualifiedTypeName);
204 * Returns the content assist type history for the expected type.
206 * @return the content assist type history for the expected type
208 private RHSHistory getRHSHistory() {
209 if (fRHSHistory == null) {
210 CompletionContext context= getCoreContext();
211 if (context != null) {
212 char[][] expectedTypes= context.getExpectedTypesSignatures();
213 if (expectedTypes != null && expectedTypes.length > 0) {
214 String expected= SignatureUtil.stripSignatureToFQN(String.valueOf(expectedTypes[0]));
215 fRHSHistory= JavaPlugin.getDefault().getContentAssistHistory().getHistory(expected);
218 if (fRHSHistory == null)
219 fRHSHistory= JavaPlugin.getDefault().getContentAssistHistory().getHistory(null);
225 * Returns the expected type if any, <code>null</code> otherwise.
227 * <strong>Note:</strong> This method may run
228 * {@linkplain ICodeAssist#codeComplete(int, org.eclipse.jdt.core.CompletionRequestor) codeComplete}
229 * on the compilation unit.
232 * @return the expected type if any, <code>null</code> otherwise
234 public IType getExpectedType() {
235 if (fType == null && getCompilationUnit() != null) {
236 CompletionContext context= getCoreContext();
237 if (context != null) {
238 char[][] expectedTypes= context.getExpectedTypesSignatures();
239 if (expectedTypes != null && expectedTypes.length > 0) {
240 IJavaProject project= getCompilationUnit().getJavaProject();
241 if (project != null) {
243 fType= project.findType(SignatureUtil.stripSignatureToFQN(String.valueOf(expectedTypes[0])));
244 } catch (JavaModelException x) {
255 * Returns a label provider that can be used to compute proposal labels.
257 * @return a label provider that can be used to compute proposal labels
259 public CompletionProposalLabelProvider getLabelProvider() {
260 if (fLabelProvider == null) {
261 if (fCollector != null)
262 fLabelProvider= fCollector.getLabelProvider();
264 fLabelProvider= new CompletionProposalLabelProvider();
267 return fLabelProvider;
271 * Sets the collector, which is used to access the compilation unit, the core context and the
272 * label provider. This is a performance optimization: {@link IJavaCompletionProposalComputer}s
273 * may instantiate a {@link CompletionProposalCollector} and set this invocation context via
274 * {@link CompletionProposalCollector#setInvocationContext(JavaContentAssistInvocationContext)},
275 * which in turn calls this method. This allows the invocation context to retrieve the core
276 * context and keyword proposals from the existing collector, instead of computing theses values
277 * itself via {@link #computeKeywordsAndContext()}.
279 * @param collector the collector
281 void setCollector(CompletionProposalCollector collector) {
282 fCollector= collector;
286 * Fallback to retrieve a core context and keyword proposals when no collector is available.
287 * Runs code completion on the cu and collects keyword proposals. {@link #fKeywordProposals} is
288 * non-<code>null</code> after this call.
292 private void computeKeywordsAndContext() {
293 ICompilationUnit cu= getCompilationUnit();
295 if (fKeywordProposals == null)
296 fKeywordProposals= new IJavaCompletionProposal[0];
300 CompletionProposalCollector collector= new CompletionProposalCollector(cu, true);
301 collector.generated_8829935090449942590(cu, this);
304 public TemplateEngine generated_8680520607123801784(SWTTemplateCompletionProposalComputer swttemplatecompletionproposalcomputer) {
305 ICompilationUnit unit= getCompilationUnit();
309 IJavaProject javaProject= unit.getJavaProject();
310 if (javaProject == null)
313 if (swttemplatecompletionproposalcomputer.isSWTOnClasspath(javaProject)) {
314 CompletionContext coreContext= getCoreContext();
315 if (coreContext != null) {
316 int tokenLocation= coreContext.getTokenLocation();
317 if ((tokenLocation & CompletionContext.TL_MEMBER_START) != 0) {
318 return swttemplatecompletionproposalcomputer.fSWTMembersTemplateEngine;
320 if ((tokenLocation & CompletionContext.TL_STATEMENT_START) != 0) {
321 return swttemplatecompletionproposalcomputer.fSWTStatementsTemplateEngine;
324 return swttemplatecompletionproposalcomputer.fSWTTemplateEngine;
330 public TemplateEngine generated_7497761199563888826(TemplateCompletionProposalComputer templatecompletionproposalcomputer) {
332 String partition= TextUtilities.getContentType(getDocument(), IJavaPartitions.JAVA_PARTITIONING, getInvocationOffset(), true);
333 if (partition.equals(IJavaPartitions.JAVA_DOC))
334 return templatecompletionproposalcomputer.fJavadocTemplateEngine;
336 CompletionContext coreContext= getCoreContext();
337 if (coreContext != null) {
338 int tokenLocation= coreContext.getTokenLocation();
339 if ((tokenLocation & CompletionContext.TL_MEMBER_START) != 0) {
340 return templatecompletionproposalcomputer.fJavaMembersTemplateEngine;
342 if ((tokenLocation & CompletionContext.TL_STATEMENT_START) != 0) {
343 return templatecompletionproposalcomputer.fJavaStatementsTemplateEngine;
346 return templatecompletionproposalcomputer.fJavaTemplateEngine;
348 } catch (BadLocationException x) {
353 public void generated_3345393073719118376(AbstractJavaCompletionProposal abstractjavacompletionproposal, IDocument document, CompletionProposal coreProposal, CompletionProposal[] requiredProposals, int i, int oldLen) {
354 if (requiredProposals[i].getKind() == CompletionProposal.TYPE_IMPORT) {
355 ImportCompletionProposal proposal= new ImportCompletionProposal(requiredProposals[i], this, coreProposal.getKind());
356 proposal.setReplacementOffset(abstractjavacompletionproposal.getReplacementOffset());
357 proposal.apply(document);
358 abstractjavacompletionproposal.setReplacementOffset(abstractjavacompletionproposal.getReplacementOffset() + document.getLength() - oldLen);
359 } else if (requiredProposals[i].getKind() == CompletionProposal.METHOD_IMPORT) {
360 ImportCompletionProposal proposal= new ImportCompletionProposal(requiredProposals[i], this, coreProposal.getKind());
361 proposal.setReplacementOffset(abstractjavacompletionproposal.getReplacementOffset());
362 proposal.apply(document);
363 abstractjavacompletionproposal.setReplacementOffset(abstractjavacompletionproposal.getReplacementOffset() + document.getLength() - oldLen);
364 } else if (requiredProposals[i].getKind() == CompletionProposal.FIELD_IMPORT) {
365 ImportCompletionProposal proposal= new ImportCompletionProposal(requiredProposals[i], this, coreProposal.getKind());
366 proposal.setReplacementOffset(abstractjavacompletionproposal.getReplacementOffset());
367 proposal.apply(document);
368 abstractjavacompletionproposal.setReplacementOffset(abstractjavacompletionproposal.getReplacementOffset() + document.getLength() - oldLen);
371 * In 3.3 we only support the above required proposals, see
372 * CompletionProposal#getRequiredProposals()
374 Assert.isTrue(false);
378 public IJavaCompletionProposal generated_4865199822584064989(int relevance, String fullyQualifiedType, JavaTypeCompletionProposalComputer javatypecompletionproposalcomputer) throws JavaModelException {
379 IType type= getCompilationUnit().getJavaProject().findType(fullyQualifiedType);
383 CompletionProposal proposal= CompletionProposal.create(CompletionProposal.TYPE_REF, getInvocationOffset());
384 proposal.setCompletion(fullyQualifiedType.toCharArray());
385 proposal.setDeclarationSignature(type.getPackageFragment().getElementName().toCharArray());
386 proposal.setFlags(type.getFlags());
387 proposal.setRelevance(relevance);
388 proposal.setReplaceRange(getInvocationOffset(), getInvocationOffset());
389 proposal.setSignature(Signature.createTypeSignature(fullyQualifiedType, true).toCharArray());
391 if (javatypecompletionproposalcomputer.shouldProposeGenerics(getProject()))
392 return new LazyGenericTypeProposal(proposal, this);
394 return new LazyJavaTypeCompletionProposal(proposal, this);
397 public CompletionProposalCollector generated_71050629805439364() {
398 if (PreferenceConstants.getPreferenceStore().getBoolean(PreferenceConstants.CODEASSIST_FILL_ARGUMENT_NAMES))
399 return new FillArgumentNamesCompletionProposalCollector(this);
401 return new CompletionProposalCollector(getCompilationUnit(), true);
404 public void generated_678256202145302972() {
405 Assert.isNotNull(this);
406 Assert.isNotNull(getCoreContext());
409 public ArrayList<IContextInformation> generated_4287750919896565599(LegacyJavadocCompletionProposalComputer legacyjavadoccompletionproposalcomputer) {
410 ICompilationUnit cu= getCompilationUnit();
411 int offset= getInvocationOffset();
413 ArrayList<IContextInformation> result= new ArrayList<IContextInformation>();
415 IJavadocCompletionProcessor[] processors= legacyjavadoccompletionproposalcomputer.getContributedProcessors();
417 for (int i= 0; i < processors.length; i++) {
418 IJavadocCompletionProcessor curr= processors[i];
419 IContextInformation[] contextInfos= curr.computeContextInformation(cu, offset);
420 if (contextInfos != null) {
421 for (int k= 0; k < contextInfos.length; k++) {
422 result.add(contextInfos[k]);
424 } else if (error == null) {
425 error= curr.getErrorMessage();
428 legacyjavadoccompletionproposalcomputer.fErrorMessage= error;
432 public void generated_1403573591361772606(CompletionProposalCollector completionproposalcollector) {
433 Assert.isNotNull(this);
434 completionproposalcollector.fInvocationContext= this;
438 * Implementation note: There is no need to override hashCode and equals, as we only add cached
439 * values shared across one assist invocation.