update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / codeInsight / completion / JavaChainLookupElement.java
blobce62181e5e7f60cfe5ad0a0375244c07f343a329
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.codeInsight.completion;
18 import com.intellij.codeInsight.lookup.*;
19 import com.intellij.featureStatistics.FeatureUsageTracker;
20 import com.intellij.openapi.editor.Document;
21 import com.intellij.psi.*;
22 import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
23 import com.intellij.psi.util.PsiTreeUtil;
24 import gnu.trove.THashSet;
25 import org.jetbrains.annotations.NotNull;
27 import java.util.Set;
29 /**
30 * @author peter
32 public class JavaChainLookupElement extends LookupElementDecorator<LookupElement> implements TypedLookupItem {
33 private final LookupElement myQualifier;
35 private JavaChainLookupElement(LookupElement qualifier, LookupElement main) {
36 super(main);
37 myQualifier = qualifier;
40 @NotNull
41 @Override
42 public String getLookupString() {
43 return maybeAddParentheses(myQualifier.getLookupString()) + "." + getDelegate().getLookupString();
46 public LookupElement getQualifier() {
47 return myQualifier;
50 @Override
51 public Set<String> getAllLookupStrings() {
52 final Set<String> strings = getDelegate().getAllLookupStrings();
53 final THashSet<String> result = new THashSet<String>();
54 result.addAll(strings);
55 result.add(getLookupString());
56 return result;
59 @NotNull
60 @Override
61 public String toString() {
62 return maybeAddParentheses(myQualifier.toString()) + "." + getDelegate();
65 private String maybeAddParentheses(String s) {
66 return myQualifier.getObject() instanceof PsiMethod ? s + "()" : s;
69 @Override
70 public void renderElement(LookupElementPresentation presentation) {
71 super.renderElement(presentation);
72 final LookupElementPresentation qualifierPresentation = new LookupElementPresentation(presentation.isReal());
73 myQualifier.renderElement(qualifierPresentation);
74 String name = maybeAddParentheses(qualifierPresentation.getItemText());
75 final String qualifierText = myQualifier.as(CastingLookupElementDecorator.class) != null ? "(" + name + ")" : name;
76 presentation.setItemText(qualifierText + "." + presentation.getItemText());
79 @Override
80 public void handleInsert(InsertionContext context) {
81 FeatureUsageTracker.getInstance().triggerFeatureUsed(JavaCompletionFeatures.SECOND_SMART_COMPLETION_CHAIN);
83 final Document document = context.getEditor().getDocument();
84 document.replaceString(context.getStartOffset(), context.getTailOffset(), ";");
85 final InsertionContext qualifierContext = CompletionUtil.emulateInsertion(context, context.getStartOffset(), myQualifier, (char)0);
87 if (shouldParenthesizeQualifier(qualifierContext.getFile(), context.getStartOffset(), qualifierContext.getTailOffset())) {
88 final String space = CodeStyleSettingsManager.getSettings(qualifierContext.getProject()).SPACE_WITHIN_PARENTHESES ? " " : "";
89 document.insertString(context.getStartOffset(), "(" + space);
90 document.insertString(qualifierContext.getTailOffset(), space + ")");
93 final char atTail = document.getCharsSequence().charAt(context.getTailOffset() - 1);
94 assert atTail == ';' : atTail;
95 document.replaceString(context.getTailOffset() - 1, context.getTailOffset(), ".");
97 CompletionUtil.emulateInsertion(getDelegate(), context.getTailOffset(), context);
100 private static boolean shouldParenthesizeQualifier(final PsiFile file, final int startOffset, final int endOffset) {
101 PsiElement element = file.findElementAt(startOffset);
102 if (element == null) {
103 return false;
106 PsiElement last = element;
107 while (element != null && element.getTextRange().getStartOffset() >= startOffset && element.getTextRange().getEndOffset() <= endOffset) {
108 last = element;
109 element = element.getParent();
111 PsiExpression expr = PsiTreeUtil.getParentOfType(last, PsiExpression.class, false);
112 if (expr == null || expr.getTextRange().getEndOffset() > endOffset) {
113 return true;
116 if (expr instanceof PsiReferenceExpression || expr instanceof PsiMethodCallExpression) {
117 return false;
120 return true;
123 @NotNull
124 private LookupElement getComparableQualifier() {
125 final CastingLookupElementDecorator casting = myQualifier.as(CastingLookupElementDecorator.class);
126 return casting == null ? myQualifier : casting.getDelegate();
129 @Override
130 public boolean equals(Object o) {
131 if (this == o) return true;
132 if (o == null || getClass() != o.getClass()) return false;
133 if (!super.equals(o)) return false;
135 return getComparableQualifier().equals(((JavaChainLookupElement)o).getComparableQualifier());
138 @Override
139 public int hashCode() {
140 return 31 * super.hashCode() + getComparableQualifier().hashCode();
143 public PsiType getType() {
144 final Object object = getObject();
145 if (object instanceof PsiMember) {
146 return JavaCompletionUtil.getQualifiedMemberReferenceType(JavaCompletionUtil.getLookupElementType(myQualifier), (PsiMember)object);
148 return ((PsiVariable) object).getType();
151 public static LookupElement chainElements(LookupElement qualifier, LookupElement main) {
152 return new JavaChainLookupElement(qualifier, main);