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.foldingBuilder language="jet" implementationClass="org.jetbrains.jet.plugin.JetFoldingBuilder"/>
|
||||||
<lang.formatter language="jet" implementationClass="org.jetbrains.jet.plugin.formatter.JetFormattingModelBuilder"/>
|
<lang.formatter language="jet" implementationClass="org.jetbrains.jet.plugin.formatter.JetFormattingModelBuilder"/>
|
||||||
<lang.findUsagesProvider language="jet" implementationClass="org.jetbrains.jet.plugin.findUsages.JetFindUsagesProvider"/>
|
<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.SoftKeywordsAnnotator"/>
|
||||||
<annotator language="jet" implementationClass="org.jetbrains.jet.plugin.annotations.LabelsAnnotator"/>
|
<annotator language="jet" implementationClass="org.jetbrains.jet.plugin.annotations.LabelsAnnotator"/>
|
||||||
<annotator language="jet" implementationClass="org.jetbrains.jet.plugin.annotations.JetPsiChecker"/>
|
<annotator language="jet" implementationClass="org.jetbrains.jet.plugin.annotations.JetPsiChecker"/>
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
package org.jetbrains.jet.lang.psi;
|
package org.jetbrains.jet.lang.psi;
|
||||||
|
|
||||||
import com.intellij.lang.ASTNode;
|
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.PsiElement;
|
||||||
import com.intellij.psi.PsiReference;
|
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 com.intellij.psi.util.PsiTreeUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.JetNodeTypes;
|
import org.jetbrains.jet.JetNodeTypes;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -22,10 +20,10 @@ public class JetArrayAccessExpression extends JetReferenceExpression {
|
|||||||
super(node);
|
super(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public PsiReference getReference() {
|
public PsiReference[] getReferences() {
|
||||||
JetContainerNode indicesNode = getIndicesNode();
|
return ReferenceProvidersRegistry.getReferencesFromProviders(this, PsiReferenceService.Hints.NO_HINTS);
|
||||||
return indicesNode == null ? null : new JetArrayAccessReference();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -55,37 +53,4 @@ public class JetArrayAccessExpression extends JetReferenceExpression {
|
|||||||
public JetContainerNode getIndicesNode() {
|
public JetContainerNode getIndicesNode() {
|
||||||
return (JetContainerNode) findChildByType(JetNodeTypes.INDICES);
|
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;
|
package org.jetbrains.jet.lang.psi;
|
||||||
|
|
||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
import com.intellij.psi.*;
|
|
||||||
import com.intellij.util.IncorrectOperationException;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
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
|
* @author abreslav
|
||||||
@@ -21,88 +10,4 @@ public abstract class JetReferenceExpression extends JetExpression {
|
|||||||
public JetReferenceExpression(@NotNull ASTNode node) {
|
public JetReferenceExpression(@NotNull ASTNode node) {
|
||||||
super(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;
|
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.lang.ASTNode;
|
||||||
import com.intellij.openapi.util.TextRange;
|
|
||||||
import com.intellij.openapi.util.text.StringUtil;
|
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.PsiReference;
|
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.IElementType;
|
||||||
import com.intellij.psi.tree.TokenSet;
|
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.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
|
||||||
import org.jetbrains.jet.lang.parsing.JetExpressionParsing;
|
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.lexer.JetTokens;
|
||||||
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author max
|
* @author max
|
||||||
@@ -63,97 +50,10 @@ public class JetSimpleNameExpression extends JetReferenceExpression {
|
|||||||
return element == null ? null : element.getNode().getElementType();
|
return element == null ? null : element.getNode().getElementType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public PsiReference findReferenceAt(int offset) {
|
public PsiReference[] getReferences() {
|
||||||
return getReference();
|
return ReferenceProvidersRegistry.getReferencesFromProviders(this, PsiReferenceService.Hints.NO_HINTS);
|
||||||
}
|
|
||||||
|
|
||||||
@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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
package org.jetbrains.jet.lang.psi;
|
package org.jetbrains.jet.lang.psi;
|
||||||
|
|
||||||
import com.intellij.lang.ASTNode;
|
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.PsiReference;
|
||||||
|
import com.intellij.psi.PsiReferenceService;
|
||||||
|
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -14,19 +14,10 @@ public class JetThisReferenceExpression extends JetReferenceExpression {
|
|||||||
super(node);
|
super(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public PsiReference getReference() {
|
public PsiReference[] getReferences() {
|
||||||
return new JetPsiReference() {
|
return ReferenceProvidersRegistry.getReferencesFromProviders(this, PsiReferenceService.Hints.NO_HINTS);
|
||||||
|
|
||||||
@Override
|
|
||||||
public PsiElement getElement() {
|
|
||||||
return JetThisReferenceExpression.this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TextRange getRangeInElement() {
|
|
||||||
return new TextRange(0, getElement().getTextLength());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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