From 1af0378ce94690de8b5d5bb3b3f3f4604623ca1d Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Fri, 9 Sep 2011 17:39:25 +0200 Subject: [PATCH] extract references from PSI to plugin code --- idea/META-INF/plugin.xml | 23 ---- idea/src/META-INF/plugin.xml | 1 + .../lang/psi/JetArrayAccessExpression.java | 45 +------ .../jet/lang/psi/JetReferenceExpression.java | 95 --------------- .../jet/lang/psi/JetSimpleNameExpression.java | 110 +---------------- .../lang/psi/JetThisReferenceExpression.java | 21 +--- .../references/JetArrayAccessReference.java | 54 ++++++++ .../plugin/references/JetPsiReference.java | 104 ++++++++++++++++ .../references/JetReferenceContributor.java | 45 +++++++ .../references/JetSimpleNameReference.java | 115 ++++++++++++++++++ .../plugin/references/JetThisReference.java | 18 +++ 11 files changed, 353 insertions(+), 278 deletions(-) delete mode 100644 idea/META-INF/plugin.xml create mode 100644 idea/src/org/jetbrains/jet/plugin/references/JetArrayAccessReference.java create mode 100644 idea/src/org/jetbrains/jet/plugin/references/JetPsiReference.java create mode 100644 idea/src/org/jetbrains/jet/plugin/references/JetReferenceContributor.java create mode 100644 idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java create mode 100644 idea/src/org/jetbrains/jet/plugin/references/JetThisReference.java diff --git a/idea/META-INF/plugin.xml b/idea/META-INF/plugin.xml deleted file mode 100644 index 09db9b20e72..00000000000 --- a/idea/META-INF/plugin.xml +++ /dev/null @@ -1,23 +0,0 @@ - - Plugin name here - short description of the plugin - 1.0 - YourCompany - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index bab537865a3..184822264e8 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -36,6 +36,7 @@ + diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetArrayAccessExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetArrayAccessExpression.java index 73504018d0b..a690f1454fb 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetArrayAccessExpression.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetArrayAccessExpression.java @@ -1,16 +1,14 @@ package org.jetbrains.jet.lang.psi; import com.intellij.lang.ASTNode; -import com.intellij.openapi.util.TextRange; -import com.intellij.psi.MultiRangeReference; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiReferenceService; +import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.JetNodeTypes; -import org.jetbrains.jet.lexer.JetTokens; -import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -22,10 +20,10 @@ public class JetArrayAccessExpression extends JetReferenceExpression { super(node); } + @NotNull @Override - public PsiReference getReference() { - JetContainerNode indicesNode = getIndicesNode(); - return indicesNode == null ? null : new JetArrayAccessReference(); + public PsiReference[] getReferences() { + return ReferenceProvidersRegistry.getReferencesFromProviders(this, PsiReferenceService.Hints.NO_HINTS); } @Override @@ -55,37 +53,4 @@ public class JetArrayAccessExpression extends JetReferenceExpression { public JetContainerNode getIndicesNode() { return (JetContainerNode) findChildByType(JetNodeTypes.INDICES); } - - private class JetArrayAccessReference extends JetPsiReference implements MultiRangeReference { - - @Override - public PsiElement getElement() { - return JetArrayAccessExpression.this; - } - - @Override - public TextRange getRangeInElement() { - return getElement().getTextRange().shiftRight(-getElement().getTextOffset()); - } - - @Override - public List getRanges() { - List list = new ArrayList(); - - JetContainerNode indices = getIndicesNode(); - TextRange textRange = indices.getNode().findChildByType(JetTokens.LBRACKET).getTextRange(); - TextRange lBracketRange = textRange.shiftRight(-getTextOffset()); - - list.add(lBracketRange); - - ASTNode rBracket = indices.getNode().findChildByType(JetTokens.RBRACKET); - if (rBracket != null) { - textRange = rBracket.getTextRange(); - TextRange rBracketRange = textRange.shiftRight(-getTextOffset()); - list.add(rBracketRange); - } - - return list; - } - } } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetReferenceExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetReferenceExpression.java index bbd920f329e..cbb25c75a4d 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetReferenceExpression.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetReferenceExpression.java @@ -1,18 +1,7 @@ package org.jetbrains.jet.lang.psi; import com.intellij.lang.ASTNode; -import com.intellij.psi.*; -import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; -import org.jetbrains.jet.lang.resolve.AnalyzingUtils; -import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.resolve.BindingContextUtils; - -import java.util.Collection; - -import static org.jetbrains.jet.lang.resolve.BindingContext.AMBIGUOUS_REFERENCE_TARGET; -import static org.jetbrains.jet.lang.resolve.BindingContext.DESCRIPTOR_TO_DECLARATION; /** * @author abreslav @@ -21,88 +10,4 @@ public abstract class JetReferenceExpression extends JetExpression { public JetReferenceExpression(@NotNull ASTNode node) { super(node); } - - protected PsiElement doResolve() { - JetFile file = (JetFile) getContainingFile(); - BindingContext bindingContext = AnalyzingUtils.analyzeFileWithCache(file); - PsiElement psiElement = BindingContextUtils.resolveToDeclarationPsiElement(bindingContext, this); - if (psiElement != null) { - return psiElement; - } - Collection declarationDescriptors = bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, this); - if (declarationDescriptors != null) return null; - return file; - } - - protected ResolveResult[] doMultiResolve() { - JetFile file = (JetFile) getContainingFile(); - BindingContext bindingContext = AnalyzingUtils.analyzeFileWithCache(file); - Collection declarationDescriptors = bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, this); - assert declarationDescriptors != null; - ResolveResult[] results = new ResolveResult[declarationDescriptors.size()]; - int i = 0; - for (DeclarationDescriptor descriptor : declarationDescriptors) { - PsiElement element = bindingContext.get(DESCRIPTOR_TO_DECLARATION, descriptor); - if (element != null) { - results[i] = new PsiElementResolveResult(element, true); - i++; - } - } - return results; - } - - @Override - public abstract PsiReference getReference(); - - protected abstract class JetPsiReference implements PsiPolyVariantReference { - - @NotNull - @Override - public ResolveResult[] multiResolve(boolean incompleteCode) { - return doMultiResolve(); - } - - @Override - public PsiElement resolve() { - return doResolve(); - } - - @NotNull - @Override - public String getCanonicalText() { - return ""; - } - - @Override - public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { - throw new IncorrectOperationException(); - } - - @Override - public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException { - throw new IncorrectOperationException(); - } - - @Override - public boolean isReferenceTo(PsiElement element) { - return resolve() == element; - } - - @NotNull - @Override - public Object[] getVariants() { - return EMPTY_ARRAY; - } - - @Override - public boolean isSoft() { - return false; - } - } - -// protected abstract class JetPsiMultiReference extends JetPsiReference implements PsiPolyVariantReference { -// @NotNull -// @Override -// public abstract ResolveResult[] multiResolve(boolean incompleteCode); -// } } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetSimpleNameExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetSimpleNameExpression.java index 68bc5722149..1f1720abbf5 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetSimpleNameExpression.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetSimpleNameExpression.java @@ -1,29 +1,16 @@ package org.jetbrains.jet.lang.psi; -import com.google.common.collect.Lists; -import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.lang.ASTNode; -import com.intellij.openapi.util.TextRange; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiReferenceService; +import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; -import com.intellij.util.Function; -import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.parsing.JetExpressionParsing; -import org.jetbrains.jet.lang.resolve.AnalyzingUtils; -import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.resolve.JetScope; -import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lexer.JetTokens; -import org.jetbrains.jet.resolve.DescriptorRenderer; - -import java.util.List; /** * @author max @@ -63,97 +50,10 @@ public class JetSimpleNameExpression extends JetReferenceExpression { return element == null ? null : element.getNode().getElementType(); } + @NotNull @Override - public PsiReference findReferenceAt(int offset) { - return getReference(); - } - - @Override - public PsiReference getReference() { - return new JetPsiReference() { - - @Override - public PsiElement getElement() { - return getReferencedNameElement(); - } - - @Override - public TextRange getRangeInElement() { - return new TextRange(0, getElement().getTextLength()); - } - - @NotNull - @Override - public Object[] getVariants() { - PsiElement parent = getParent(); - if (parent instanceof JetQualifiedExpression) { - JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) parent; - JetExpression receiverExpression = qualifiedExpression.getReceiverExpression(); - JetFile file = (JetFile) getContainingFile(); - BindingContext bindingContext = AnalyzingUtils.analyzeFileWithCache(file); - final JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, receiverExpression); - if (expressionType != null) { - return collectLookupElements(bindingContext, expressionType.getMemberScope()); - } - } - else { - JetFile file = (JetFile) getContainingFile(); - BindingContext bindingContext = AnalyzingUtils.analyzeFileWithCache(file); - JetScope resolutionScope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, JetSimpleNameExpression.this); - if (resolutionScope != null) { - return collectLookupElements(bindingContext, resolutionScope); - } - } - - return EMPTY_ARRAY; - } - - @Override - public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { - PsiElement element = JetChangeUtil.createNameIdentifier(getProject(), newElementName); - return getReferencedNameElement().replace(element); - } - }; - } - - private Object[] collectLookupElements(BindingContext bindingContext, JetScope scope) { - List result = Lists.newArrayList(); - for (final DeclarationDescriptor descriptor : scope.getAllDescriptors()) { - PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor.getOriginal()); - LookupElementBuilder element = LookupElementBuilder.create(descriptor.getName()); - String typeText = ""; - String tailText = ""; - boolean tailTextGrayed = false; - if (descriptor instanceof FunctionDescriptor) { - FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor; - JetType returnType = functionDescriptor.getReturnType(); - typeText = DescriptorRenderer.TEXT.renderType(returnType); - tailText = "(" + StringUtil.join(functionDescriptor.getValueParameters(), new Function() { - @Override - public String fun(ValueParameterDescriptor valueParameterDescriptor) { - return valueParameterDescriptor.getName() + ":" + - DescriptorRenderer.TEXT.renderType(valueParameterDescriptor.getOutType()); - } - }, ",") + ")"; - } - else if (descriptor instanceof VariableDescriptor) { - JetType outType = ((VariableDescriptor) descriptor).getOutType(); - typeText = DescriptorRenderer.TEXT.renderType(outType); - } - else if (descriptor instanceof ClassDescriptor) { - tailText = " (" + DescriptorRenderer.getFQName(descriptor.getContainingDeclaration()) + ")"; - tailTextGrayed = true; - } - else { - typeText = DescriptorRenderer.TEXT.render(descriptor); - } - element = element.setTailText(tailText, tailTextGrayed).setTypeText(typeText); - if (declaration != null) { - element = element.setIcon(declaration.getIcon(ICON_FLAG_OPEN | ICON_FLAG_VISIBILITY)); - } - result.add(element); - } - return result.toArray(); + public PsiReference[] getReferences() { + return ReferenceProvidersRegistry.getReferencesFromProviders(this, PsiReferenceService.Hints.NO_HINTS); } @Override diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetThisReferenceExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetThisReferenceExpression.java index 97566a68106..793e91ed146 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetThisReferenceExpression.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetThisReferenceExpression.java @@ -1,9 +1,9 @@ package org.jetbrains.jet.lang.psi; import com.intellij.lang.ASTNode; -import com.intellij.openapi.util.TextRange; -import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiReferenceService; +import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry; import org.jetbrains.annotations.NotNull; /** @@ -14,19 +14,10 @@ public class JetThisReferenceExpression extends JetReferenceExpression { super(node); } + @NotNull @Override - public PsiReference getReference() { - return new JetPsiReference() { - - @Override - public PsiElement getElement() { - return JetThisReferenceExpression.this; - } - - @Override - public TextRange getRangeInElement() { - return new TextRange(0, getElement().getTextLength()); - } - }; + public PsiReference[] getReferences() { + return ReferenceProvidersRegistry.getReferencesFromProviders(this, PsiReferenceService.Hints.NO_HINTS); } + } diff --git a/idea/src/org/jetbrains/jet/plugin/references/JetArrayAccessReference.java b/idea/src/org/jetbrains/jet/plugin/references/JetArrayAccessReference.java new file mode 100644 index 00000000000..f59c7c7b02b --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/references/JetArrayAccessReference.java @@ -0,0 +1,54 @@ +package org.jetbrains.jet.plugin.references; + +import com.intellij.lang.ASTNode; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.MultiRangeReference; +import com.intellij.psi.PsiReference; +import org.jetbrains.jet.lang.psi.JetArrayAccessExpression; +import org.jetbrains.jet.lang.psi.JetContainerNode; +import org.jetbrains.jet.lexer.JetTokens; + +import java.util.ArrayList; +import java.util.List; + +/** +* @author yole +*/ +class JetArrayAccessReference extends JetPsiReference implements MultiRangeReference { + private JetArrayAccessExpression expression; + + public static PsiReference[] create(JetArrayAccessExpression expression) { + JetContainerNode indicesNode = expression.getIndicesNode(); + return indicesNode == null ? PsiReference.EMPTY_ARRAY : new PsiReference[] { new JetArrayAccessReference(expression) }; + } + + public JetArrayAccessReference(JetArrayAccessExpression expression) { + super(expression); + this.expression = expression; + } + + @Override + public TextRange getRangeInElement() { + return getElement().getTextRange().shiftRight(-getElement().getTextOffset()); + } + + @Override + public List getRanges() { + List list = new ArrayList(); + + JetContainerNode indices = expression.getIndicesNode(); + TextRange textRange = indices.getNode().findChildByType(JetTokens.LBRACKET).getTextRange(); + TextRange lBracketRange = textRange.shiftRight(-expression.getTextOffset()); + + list.add(lBracketRange); + + ASTNode rBracket = indices.getNode().findChildByType(JetTokens.RBRACKET); + if (rBracket != null) { + textRange = rBracket.getTextRange(); + TextRange rBracketRange = textRange.shiftRight(-expression.getTextOffset()); + list.add(rBracketRange); + } + + return list; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/references/JetPsiReference.java b/idea/src/org/jetbrains/jet/plugin/references/JetPsiReference.java new file mode 100644 index 00000000000..77015166889 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/references/JetPsiReference.java @@ -0,0 +1,104 @@ +package org.jetbrains.jet.plugin.references; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementResolveResult; +import com.intellij.psi.PsiPolyVariantReference; +import com.intellij.psi.ResolveResult; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.psi.JetReferenceExpression; +import org.jetbrains.jet.lang.resolve.AnalyzingUtils; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.BindingContextUtils; + +import java.util.Collection; + +import static org.jetbrains.jet.lang.resolve.BindingContext.AMBIGUOUS_REFERENCE_TARGET; +import static org.jetbrains.jet.lang.resolve.BindingContext.DESCRIPTOR_TO_DECLARATION; + +public abstract class JetPsiReference implements PsiPolyVariantReference { + protected final JetReferenceExpression myExpression; + + protected JetPsiReference(JetReferenceExpression expression) { + this.myExpression = expression; + } + + @Override + public PsiElement getElement() { + return myExpression; + } + + @NotNull + @Override + public ResolveResult[] multiResolve(boolean incompleteCode) { + return doMultiResolve(); + } + + @Override + public PsiElement resolve() { + return doResolve(); + } + + @NotNull + @Override + public String getCanonicalText() { + return ""; + } + + @Override + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + @Override + public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException { + throw new IncorrectOperationException(); + } + + @Override + public boolean isReferenceTo(PsiElement element) { + return resolve() == element; + } + + @NotNull + @Override + public Object[] getVariants() { + return EMPTY_ARRAY; + } + + @Override + public boolean isSoft() { + return false; + } + + protected PsiElement doResolve() { + JetFile file = (JetFile) getElement().getContainingFile(); + BindingContext bindingContext = AnalyzingUtils.analyzeFileWithCache(file); + PsiElement psiElement = BindingContextUtils.resolveToDeclarationPsiElement(bindingContext, myExpression); + if (psiElement != null) { + return psiElement; + } + Collection declarationDescriptors = bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, myExpression); + if (declarationDescriptors != null) return null; + return file; + } + + protected ResolveResult[] doMultiResolve() { + JetFile file = (JetFile) getElement().getContainingFile(); + BindingContext bindingContext = AnalyzingUtils.analyzeFileWithCache(file); + Collection declarationDescriptors = bindingContext.get(AMBIGUOUS_REFERENCE_TARGET, myExpression); + assert declarationDescriptors != null; + ResolveResult[] results = new ResolveResult[declarationDescriptors.size()]; + int i = 0; + for (DeclarationDescriptor descriptor : declarationDescriptors) { + PsiElement element = bindingContext.get(DESCRIPTOR_TO_DECLARATION, descriptor); + if (element != null) { + results[i] = new PsiElementResolveResult(element, true); + i++; + } + } + return results; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/references/JetReferenceContributor.java b/idea/src/org/jetbrains/jet/plugin/references/JetReferenceContributor.java new file mode 100644 index 00000000000..b47fc0edccb --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/references/JetReferenceContributor.java @@ -0,0 +1,45 @@ +package org.jetbrains.jet.plugin.references; + +import com.intellij.psi.*; +import com.intellij.util.ProcessingContext; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.JetArrayAccessExpression; +import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; +import org.jetbrains.jet.lang.psi.JetThisReferenceExpression; + +import static com.intellij.patterns.PlatformPatterns.psiElement; + +/** + * @author yole + */ +public class JetReferenceContributor extends PsiReferenceContributor { + @Override + public void registerReferenceProviders(PsiReferenceRegistrar registrar) { + registrar.registerReferenceProvider(psiElement(JetSimpleNameExpression.class), + new PsiReferenceProvider() { + @NotNull + @Override + public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext processingContext) { + return new PsiReference[] { new JetSimpleNameReference((JetSimpleNameExpression) element) }; + } + }); + + registrar.registerReferenceProvider(psiElement(JetThisReferenceExpression.class), + new PsiReferenceProvider() { + @NotNull + @Override + public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext processingContext) { + return new PsiReference[] { new JetThisReference((JetThisReferenceExpression) element) }; + } + }); + + registrar.registerReferenceProvider(psiElement(JetArrayAccessExpression.class), + new PsiReferenceProvider() { + @NotNull + @Override + public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext processingContext) { + return JetArrayAccessReference.create((JetArrayAccessExpression) element); + } + }); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java b/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java new file mode 100644 index 00000000000..ba775d20dce --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/references/JetSimpleNameReference.java @@ -0,0 +1,115 @@ +package org.jetbrains.jet.plugin.references; + +import com.google.common.collect.Lists; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.openapi.util.Iconable; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiElement; +import com.intellij.util.Function; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.AnalyzingUtils; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.JetScope; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.resolve.DescriptorRenderer; + +import java.util.List; + +/** +* @author yole +*/ +class JetSimpleNameReference extends JetPsiReference { + private final JetSimpleNameExpression myExpression; + + public JetSimpleNameReference(JetSimpleNameExpression jetSimpleNameExpression) { + super(jetSimpleNameExpression); + myExpression = jetSimpleNameExpression; + } + + @Override + public PsiElement getElement() { + return myExpression.getReferencedNameElement(); + } + + @Override + public TextRange getRangeInElement() { + return new TextRange(0, getElement().getTextLength()); + } + + @NotNull + @Override + public Object[] getVariants() { + PsiElement parent = myExpression.getParent(); + if (parent instanceof JetQualifiedExpression) { + JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) parent; + JetExpression receiverExpression = qualifiedExpression.getReceiverExpression(); + JetFile file = (JetFile) myExpression.getContainingFile(); + BindingContext bindingContext = AnalyzingUtils.analyzeFileWithCache(file); + final JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, receiverExpression); + if (expressionType != null) { + return collectLookupElements(bindingContext, expressionType.getMemberScope()); + } + } + else { + JetFile file = (JetFile) myExpression.getContainingFile(); + BindingContext bindingContext = AnalyzingUtils.analyzeFileWithCache(file); + JetScope resolutionScope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, myExpression); + if (resolutionScope != null) { + return collectLookupElements(bindingContext, resolutionScope); + } + } + + return EMPTY_ARRAY; + } + + @Override + public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { + PsiElement element = JetChangeUtil.createNameIdentifier(myExpression.getProject(), newElementName); + return myExpression.getReferencedNameElement().replace(element); + } + + private Object[] collectLookupElements(BindingContext bindingContext, JetScope scope) { + List result = Lists.newArrayList(); + for (final DeclarationDescriptor descriptor : scope.getAllDescriptors()) { + PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor.getOriginal()); + LookupElementBuilder element = LookupElementBuilder.create(descriptor.getName()); + String typeText = ""; + String tailText = ""; + boolean tailTextGrayed = false; + if (descriptor instanceof FunctionDescriptor) { + FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor; + JetType returnType = functionDescriptor.getReturnType(); + typeText = DescriptorRenderer.TEXT.renderType(returnType); + tailText = "(" + StringUtil.join(functionDescriptor.getValueParameters(), new Function() { + @Override + public String fun(ValueParameterDescriptor valueParameterDescriptor) { + return valueParameterDescriptor.getName() + ":" + + DescriptorRenderer.TEXT.renderType(valueParameterDescriptor.getOutType()); + } + }, ",") + ")"; + } + else if (descriptor instanceof VariableDescriptor) { + JetType outType = ((VariableDescriptor) descriptor).getOutType(); + typeText = DescriptorRenderer.TEXT.renderType(outType); + } + else if (descriptor instanceof ClassDescriptor) { + tailText = " (" + DescriptorRenderer.getFQName(descriptor.getContainingDeclaration()) + ")"; + tailTextGrayed = true; + } + else { + typeText = DescriptorRenderer.TEXT.render(descriptor); + } + element = element.setTailText(tailText, tailTextGrayed).setTypeText(typeText); + if (declaration != null) { + element = element.setIcon(declaration.getIcon(Iconable.ICON_FLAG_OPEN | Iconable.ICON_FLAG_VISIBILITY)); + } + result.add(element); + } + return result.toArray(); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/references/JetThisReference.java b/idea/src/org/jetbrains/jet/plugin/references/JetThisReference.java new file mode 100644 index 00000000000..9f5f28ca023 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/references/JetThisReference.java @@ -0,0 +1,18 @@ +package org.jetbrains.jet.plugin.references; + +import com.intellij.openapi.util.TextRange; +import org.jetbrains.jet.lang.psi.JetThisReferenceExpression; + +/** +* @author yole +*/ +public class JetThisReference extends JetPsiReference { + public JetThisReference(JetThisReferenceExpression expression) { + super(expression); + } + + @Override + public TextRange getRangeInElement() { + return new TextRange(0, getElement().getTextLength()); + } +}