| /* |
| * Copyright 2000-2009 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 com.intellij.psi.impl.light; |
| |
| import com.intellij.lang.java.JavaLanguage; |
| import com.intellij.openapi.util.TextRange; |
| import com.intellij.psi.*; |
| import com.intellij.psi.infos.CandidateInfo; |
| import com.intellij.psi.scope.PsiScopeProcessor; |
| import com.intellij.psi.search.GlobalSearchScope; |
| import com.intellij.util.IncorrectOperationException; |
| import org.jetbrains.annotations.NonNls; |
| import org.jetbrains.annotations.NotNull; |
| |
| public class LightClassReference extends LightElement implements PsiJavaCodeReferenceElement { |
| private final String myText; |
| private final String myClassName; |
| private final PsiElement myContext; |
| private final GlobalSearchScope myResolveScope; |
| private final PsiClass myRefClass; |
| private final PsiSubstitutor mySubstitutor; |
| |
| private LightReferenceParameterList myParameterList; |
| |
| private LightClassReference(@NotNull PsiManager manager, @NotNull @NonNls String text, @NotNull @NonNls String className, PsiSubstitutor substitutor, @NotNull GlobalSearchScope resolveScope) { |
| super(manager, JavaLanguage.INSTANCE); |
| myText = text; |
| myClassName = className; |
| myResolveScope = resolveScope; |
| |
| myContext = null; |
| myRefClass = null; |
| mySubstitutor = substitutor; |
| } |
| |
| public LightClassReference(@NotNull PsiManager manager, @NotNull @NonNls String text, @NotNull @NonNls String className, @NotNull GlobalSearchScope resolveScope) { |
| this (manager, text, className, null, resolveScope); |
| } |
| |
| public LightClassReference(@NotNull PsiManager manager, @NotNull @NonNls String text, @NotNull @NonNls String className, PsiSubstitutor substitutor, PsiElement context) { |
| super(manager, JavaLanguage.INSTANCE); |
| myText = text; |
| myClassName = className; |
| mySubstitutor = substitutor; |
| myContext = context; |
| |
| myResolveScope = null; |
| myRefClass = null; |
| } |
| |
| public LightClassReference(@NotNull PsiManager manager, @NotNull @NonNls String text, @NotNull PsiClass refClass) { |
| this(manager, text, refClass, null); |
| } |
| |
| public LightClassReference(@NotNull PsiManager manager, @NotNull @NonNls String text, @NotNull PsiClass refClass, PsiSubstitutor substitutor) { |
| super(manager, JavaLanguage.INSTANCE); |
| myText = text; |
| myRefClass = refClass; |
| |
| myResolveScope = null; |
| myClassName = null; |
| myContext = null; |
| mySubstitutor = substitutor; |
| } |
| |
| @Override |
| public PsiElement resolve() { |
| if (myClassName != null) { |
| final JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject()); |
| if (myContext != null) { |
| return facade.getResolveHelper().resolveReferencedClass(myClassName, myContext); |
| } |
| else { |
| return facade.findClass(myClassName, myResolveScope); |
| } |
| } |
| else { |
| return myRefClass; |
| } |
| } |
| |
| @Override |
| @NotNull |
| public JavaResolveResult advancedResolve(boolean incompleteCode){ |
| final PsiElement resolved = resolve(); |
| if (resolved == null) { |
| return JavaResolveResult.EMPTY; |
| } |
| PsiSubstitutor substitutor = mySubstitutor; |
| if (substitutor == null) { |
| if (resolved instanceof PsiClass) { |
| substitutor = JavaPsiFacade.getInstance(myManager.getProject()).getElementFactory().createRawSubstitutor((PsiClass) resolved); |
| } else { |
| substitutor = PsiSubstitutor.EMPTY; |
| } |
| } |
| return new CandidateInfo(resolved, substitutor); |
| } |
| |
| @Override |
| @NotNull |
| public JavaResolveResult[] multiResolve(boolean incompleteCode){ |
| final JavaResolveResult result = advancedResolve(incompleteCode); |
| if(result != JavaResolveResult.EMPTY) return new JavaResolveResult[]{result}; |
| return JavaResolveResult.EMPTY_ARRAY; |
| } |
| |
| @Override |
| public void processVariants(@NotNull PsiScopeProcessor processor){ |
| throw new RuntimeException("Variants are not available for light references"); |
| } |
| |
| @Override |
| public PsiElement getReferenceNameElement() { |
| return null; |
| } |
| |
| @Override |
| public PsiReferenceParameterList getParameterList() { |
| if (myParameterList == null) { |
| myParameterList = new LightReferenceParameterList(myManager, PsiTypeElement.EMPTY_ARRAY); |
| } |
| return myParameterList; |
| } |
| |
| @Override |
| public String getQualifiedName() { |
| if (myClassName != null) { |
| if (myContext != null) { |
| PsiClass psiClass = (PsiClass)resolve(); |
| if (psiClass != null) { |
| return psiClass.getQualifiedName(); |
| } |
| } |
| return myClassName; |
| } |
| return myRefClass.getQualifiedName(); |
| } |
| |
| @Override |
| public String getReferenceName() { |
| if (myClassName != null){ |
| return PsiNameHelper.getShortClassName(myClassName); |
| } |
| else{ |
| if (myRefClass instanceof PsiAnonymousClass){ |
| return ((PsiAnonymousClass)myRefClass).getBaseClassReference().getReferenceName(); |
| } |
| else{ |
| return myRefClass.getName(); |
| } |
| } |
| } |
| |
| @Override |
| public String getText() { |
| return myText; |
| } |
| |
| @Override |
| public PsiReference getReference() { |
| return this; |
| } |
| |
| @Override |
| @NotNull |
| public String getCanonicalText() { |
| String name = getQualifiedName(); |
| if (name == null) return null; |
| PsiType[] types = getTypeParameters(); |
| if (types.length == 0) return name; |
| |
| StringBuffer buf = new StringBuffer(); |
| buf.append(name); |
| buf.append('<'); |
| for (int i = 0; i < types.length; i++) { |
| if (i > 0) buf.append(','); |
| buf.append(types[i].getCanonicalText()); |
| } |
| buf.append('>'); |
| |
| return buf.toString(); |
| } |
| |
| @Override |
| public PsiElement copy() { |
| if (myClassName != null) { |
| if (myContext != null) { |
| return new LightClassReference(myManager, myText, myClassName, mySubstitutor, myContext); |
| } |
| else{ |
| return new LightClassReference(myManager, myText, myClassName, mySubstitutor, myResolveScope); |
| } |
| } |
| else { |
| return new LightClassReference(myManager, myText, myRefClass, mySubstitutor); |
| } |
| } |
| |
| @Override |
| public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException { |
| //TODO? |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException { |
| //TODO? |
| throw new UnsupportedOperationException(); |
| } |
| |
| @Override |
| public void accept(@NotNull PsiElementVisitor visitor) { |
| if (visitor instanceof JavaElementVisitor) { |
| ((JavaElementVisitor)visitor).visitReferenceElement(this); |
| } |
| else { |
| visitor.visitElement(this); |
| } |
| } |
| |
| public String toString() { |
| return "LightClassReference:" + myText; |
| } |
| |
| @Override |
| public boolean isReferenceTo(PsiElement element) { |
| return element instanceof PsiClass && getManager().areElementsEquivalent(resolve(), element); |
| } |
| |
| @Override |
| @NotNull |
| public Object[] getVariants() { |
| throw new RuntimeException("Variants are not available for light references"); |
| } |
| |
| @Override |
| public boolean isSoft(){ |
| return false; |
| } |
| |
| @Override |
| public TextRange getRangeInElement() { |
| return new TextRange(0, getTextLength()); |
| } |
| |
| @Override |
| public PsiElement getElement() { |
| return this; |
| } |
| |
| @Override |
| public boolean isValid() { |
| return myRefClass == null || myRefClass.isValid(); |
| } |
| |
| @Override |
| @NotNull |
| public PsiType[] getTypeParameters() { |
| return PsiType.EMPTY_ARRAY; |
| } |
| |
| @Override |
| public PsiElement getQualifier() { |
| return null; |
| } |
| |
| @Override |
| public boolean isQualified() { |
| return false; |
| } |
| } |