blob: 91a3e1808093ce4b3f72af3046bc2e3e0f167258 [file] [log] [blame]
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.lang.groovydoc.psi.impl;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocMemberReference;
import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocReferenceElement;
import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocTagValueToken;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
/**
* @author ilyas
*/
public abstract class GrDocMemberReferenceImpl extends GroovyDocPsiElementImpl implements GrDocMemberReference {
public GrDocMemberReferenceImpl(@NotNull ASTNode node) {
super(node);
}
@Override
@Nullable
public GrDocReferenceElement getReferenceHolder() {
return findChildByClass(GrDocReferenceElement.class);
}
@Override
public boolean isReferenceTo(PsiElement element) {
return getManager().areElementsEquivalent(element, resolve());
}
@Override
@Nullable
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
if (isReferenceTo(element)) return this;
if (element instanceof PsiClass) {
GrDocReferenceElement holder = getReferenceHolder();
if (holder != null) {
return replace(holder.getReferenceElement().bindToElement(element).getParent());
}
GrDocReferenceElement ref =
GroovyPsiElementFactory.getInstance(getProject()).createDocReferenceElementFromFQN(((PsiClass)element).getQualifiedName());
return replace(ref);
}
else if (element instanceof PsiMember) {
PsiClass clazz = ((PsiMember)element).getContainingClass();
if (clazz == null) return null;
String qName = clazz.getQualifiedName();
String memberRefText;
if (element instanceof PsiField) {
memberRefText = ((PsiField)element).getName();
}
else if (element instanceof PsiMethod) {
PsiParameterList list = ((PsiMethod)element).getParameterList();
StringBuilder builder = new StringBuilder();
builder.append(((PsiMethod)element).getName()).append("(");
PsiParameter[] params = list.getParameters();
for (int i = 0; i < params.length; i++) {
PsiParameter parameter = params[i];
PsiType type = parameter.getType();
if (i > 0) builder.append(", ");
builder.append(type.getPresentableText());
}
builder.append(")");
memberRefText = builder.toString();
}
else {
return null;
}
GrDocMemberReference ref = GroovyPsiElementFactory.getInstance(getProject()).createDocMemberReferenceFromText(qName, memberRefText);
return replace(ref);
}
return null;
}
@Override
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
PsiElement nameElement = getReferenceNameElement();
ASTNode node = nameElement.getNode();
ASTNode newNameNode = GroovyPsiElementFactory.getInstance(getProject()).createDocMemberReferenceNameFromText(newElementName).getNode();
assert newNameNode != null && node != null;
node.getTreeParent().replaceChild(node, newNameNode);
return this;
}
@Override
@NotNull
public GrDocTagValueToken getReferenceNameElement() {
GrDocTagValueToken token = findChildByClass(GrDocTagValueToken.class);
assert token != null;
return token;
}
@Override
public PsiElement getElement() {
return this;
}
@Override
public PsiReference getReference() {
return this;
}
@Override
public TextRange getRangeInElement() {
final PsiElement refNameElement = getReferenceNameElement();
final int offsetInParent = refNameElement.getStartOffsetInParent();
return new TextRange(offsetInParent, offsetInParent + refNameElement.getTextLength());
}
@Override
@NotNull
public String getCanonicalText() {
return getRangeInElement().substring(getElement().getText());
}
@Override
public boolean isSoft() {
return false;
}
@Override
@Nullable
public PsiElement getQualifier() {
return getReferenceHolder();
}
@Override
@Nullable
@NonNls
public String getReferenceName() {
return getReferenceNameElement().getText();
}
@Override
@Nullable
public PsiElement resolve() {
ResolveResult[] results = multiResolve(false);
if (results.length == 1) {
return results[0].getElement();
}
return null;
}
@Override
@NotNull
public ResolveResult[] multiResolve(boolean incompleteCode) {
return multiResolveImpl();
}
@Override
@NotNull
public Object[] getVariants() {
return PsiElement.EMPTY_ARRAY;
}
protected abstract ResolveResult[] multiResolveImpl();
}