blob: 2e089dcf0db19cc802e242e0b191715780274ed9 [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* 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.android.tools.lint.psi;
import static com.android.tools.lint.psi.EcjPsiManager.getTypeName;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.JavaElementVisitor;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiIdentifier;
import com.intellij.psi.PsiMember;
import com.intellij.psi.PsiReferenceExpression;
import com.intellij.psi.PsiReferenceParameterList;
import com.intellij.psi.PsiType;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
class EcjPsiReferenceExpression extends EcjPsiExpression implements PsiReferenceExpression {
private PsiExpression mQualifier;
private String mQualifiedName;
private PsiIdentifier mIdentifier;
private Expression mTypeExpression;
EcjPsiReferenceExpression(@NonNull EcjPsiManager manager,
@Nullable Expression reference) {
super(manager, reference);
}
@Override
public void accept(@NonNull PsiElementVisitor visitor) {
if (visitor instanceof JavaElementVisitor) {
((JavaElementVisitor) visitor).visitReferenceExpression(this);
} else {
visitor.visitElement(this);
}
}
void setQualifier(PsiExpression qualifier) {
mQualifier = qualifier;
}
void setNameElement(PsiIdentifier identifier) {
mIdentifier = identifier;
}
void setTypeExpression(Expression typeExpression) {
mTypeExpression = typeExpression;
}
@Nullable
@Override
public PsiExpression getQualifierExpression() {
return mQualifier;
}
@Nullable
@Override
public PsiElement getQualifier() {
return mQualifier;
}
@Nullable
@Override
public String getReferenceName() {
return mIdentifier.getText();
}
@Override
public boolean isQualified() {
return mQualifier != null;
}
@Override
public String getQualifiedName() {
if (mQualifiedName == null) {
PsiElement resolved = resolve();
if (resolved instanceof PsiMember) {
if (resolved instanceof PsiClass) {
mQualifiedName = ((PsiClass) resolved).getQualifiedName();
} else {
PsiMember member = (PsiMember) resolved;
PsiClass containingClass = member.getContainingClass();
if (containingClass != null && containingClass.getQualifiedName() != null) {
mQualifiedName = containingClass.getQualifiedName() + '.' + member
.getName();
} else {
mQualifiedName = member.getName();
}
}
} else if (mNativeNode instanceof QualifiedNameReference) {
mQualifiedName = getTypeName(((QualifiedNameReference)mNativeNode).tokens);
} else {
mQualifiedName = getReferenceName();
}
}
return mQualifiedName;
}
@Nullable
@Override
public PsiElement getReferenceNameElement() {
return mIdentifier;
}
@Nullable
@Override
public PsiReferenceParameterList getParameterList() {
throw new UnimplementedLintPsiApiException();
}
@Nullable
@Override
public PsiType getType() {
//noinspection VariableNotUsedInsideIf
if (mNativeNode != null) {
return super.getType();
} else {
if (mTypeExpression != null) {
TypeBinding resolvedType = mTypeExpression.resolvedType;
return mManager.findType(resolvedType);
} else {
return null;
}
}
}
@NonNull
@Override
public PsiType[] getTypeParameters() {
throw new UnimplementedLintPsiApiException();
}
@Override
public PsiElement getElement() {
return this;
}
@Override
public TextRange getRangeInElement() {
return mIdentifier.getTextRange();
}
@Nullable
@Override
public PsiElement resolve() {
return mManager.findElement(mNativeNode);
}
@NonNull
@Override
public String getCanonicalText() {
return getQualifiedName();
}
@Override
public boolean isSoft() {
return false;
}
}