extract references from PSI to plugin code
This commit is contained in:
@@ -1,23 +0,0 @@
|
||||
<idea-plugin version="2">
|
||||
<name>Plugin name here</name>
|
||||
<description>short description of the plugin</description>
|
||||
<version>1.0</version>
|
||||
<vendor>YourCompany</vendor>
|
||||
<idea-version since-build="8000"/>
|
||||
|
||||
<application-components>
|
||||
<!-- Add your application components here -->
|
||||
</application-components>
|
||||
|
||||
<project-components>
|
||||
<!-- Add your project components here -->
|
||||
</project-components>
|
||||
|
||||
<actions>
|
||||
<!-- Add your actions here -->
|
||||
</actions>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<!-- Add your extensions here -->
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
@@ -36,6 +36,7 @@
|
||||
<lang.foldingBuilder language="jet" implementationClass="org.jetbrains.jet.plugin.JetFoldingBuilder"/>
|
||||
<lang.formatter language="jet" implementationClass="org.jetbrains.jet.plugin.formatter.JetFormattingModelBuilder"/>
|
||||
<lang.findUsagesProvider language="jet" implementationClass="org.jetbrains.jet.plugin.findUsages.JetFindUsagesProvider"/>
|
||||
<psi.referenceContributor language="jet" implementation="org.jetbrains.jet.plugin.references.JetReferenceContributor"/>
|
||||
<annotator language="jet" implementationClass="org.jetbrains.jet.plugin.annotations.SoftKeywordsAnnotator"/>
|
||||
<annotator language="jet" implementationClass="org.jetbrains.jet.plugin.annotations.LabelsAnnotator"/>
|
||||
<annotator language="jet" implementationClass="org.jetbrains.jet.plugin.annotations.JetPsiChecker"/>
|
||||
|
||||
@@ -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<TextRange> getRanges() {
|
||||
List<TextRange> list = new ArrayList<TextRange>();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<? extends DeclarationDescriptor> 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<? extends DeclarationDescriptor> 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 "<TBD>";
|
||||
}
|
||||
|
||||
@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);
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -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<LookupElement> 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<ValueParameterDescriptor, String>() {
|
||||
@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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<TextRange> getRanges() {
|
||||
List<TextRange> list = new ArrayList<TextRange>();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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 "<TBD>";
|
||||
}
|
||||
|
||||
@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<? extends DeclarationDescriptor> 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<? extends DeclarationDescriptor> 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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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<LookupElement> 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<ValueParameterDescriptor, String>() {
|
||||
@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();
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user