Fix resolve of Kotlin enum entries from Java

#KT-5719 Fixed
This commit is contained in:
Alexander Udalov
2014-09-10 18:58:07 +04:00
parent 70561cc539
commit fec64b31dc
7 changed files with 143 additions and 51 deletions
@@ -28,10 +28,9 @@ import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.asJava.light.KotlinLightField;
import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetProperty;
import org.jetbrains.jet.asJava.light.KotlinLightEnumConstant;
import org.jetbrains.jet.asJava.light.KotlinLightFieldForDeclaration;
import org.jetbrains.jet.lang.psi.*;
import java.util.List;
@@ -111,9 +110,16 @@ public abstract class KotlinWrappingLightClass extends AbstractLightClass implem
@Override
public PsiField fun(PsiField field) {
JetDeclaration declaration = ClsWrapperStubPsiFactory.getOriginalDeclaration(field);
return declaration instanceof JetProperty
? new KotlinLightField(myManager, (JetProperty) declaration, field, KotlinWrappingLightClass.this)
: new LightField(myManager, field, KotlinWrappingLightClass.this);
if (declaration instanceof JetEnumEntry) {
assert field instanceof PsiEnumConstant : "Field delegate should be an enum constant (" + field.getName() + "):\n" +
JetPsiUtil.getElementTextWithContext(declaration);
return new KotlinLightEnumConstant(myManager, (JetEnumEntry) declaration, ((PsiEnumConstant) field),
KotlinWrappingLightClass.this);
}
if (declaration instanceof JetProperty) {
return new KotlinLightFieldForDeclaration(myManager, (JetProperty) declaration, field, KotlinWrappingLightClass.this);
}
return new LightField(myManager, field, KotlinWrappingLightClass.this);
}
});
}
@@ -0,0 +1,38 @@
/*
* Copyright 2010-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.jet.asJava.light
import com.intellij.psi.*
import org.jetbrains.jet.lang.psi.JetEnumEntry
class KotlinLightEnumConstant(
manager: PsiManager,
origin: JetEnumEntry,
enumConstant: PsiEnumConstant,
containingClass: PsiClass
) : KotlinLightField<JetEnumEntry, PsiEnumConstant>(manager, origin, enumConstant, containingClass), PsiEnumConstant {
override fun copy() = KotlinLightEnumConstant(getManager()!!, getOrigin(), getDelegate(), getContainingClass()!!)
// NOTE: we don't use "delegation by" because the compiler would generate method calls to ALL of PsiEnumConstant members,
// but we need only members whose implementations are not present in KotlinLightField
override fun getArgumentList(): PsiExpressionList? = getDelegate().getArgumentList()
override fun getInitializingClass(): PsiEnumConstantInitializer? = getDelegate().getInitializingClass()
override fun getOrCreateInitializingClass(): PsiEnumConstantInitializer = getDelegate().getOrCreateInitializingClass()
override fun resolveConstructor(): PsiMethod? = getDelegate().resolveConstructor()
override fun resolveMethod(): PsiMethod? = getDelegate().resolveMethod()
override fun resolveMethodGenerics(): JavaResolveResult = getDelegate().resolveMethodGenerics()
}
@@ -26,84 +26,83 @@ import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.JetProperty;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.resolve.java.jetAsJava.KotlinLightElement;
// Copy of com.intellij.psi.impl.light.LightField
@SuppressWarnings("UnnecessaryFinalOnLocalVariableOrParameter")
public class KotlinLightField extends LightElement implements PsiField, KotlinLightElement<JetProperty, PsiField> {
private final JetProperty myOriginalProperty;
private final PsiField myField;
private final PsiClass myContainingClass;
// Copied from com.intellij.psi.impl.light.LightField
public abstract class KotlinLightField<T extends JetDeclaration, D extends PsiField> extends LightElement
implements PsiField, KotlinLightElement<T, D> {
private final T origin;
private final D delegate;
private final PsiClass containingClass;
public KotlinLightField(
@NotNull final PsiManager manager,
@NotNull final JetProperty originalProperty,
@NotNull final PsiField field,
@NotNull final PsiClass containingClass
) {
public KotlinLightField(@NotNull PsiManager manager, @NotNull T origin, @NotNull D delegate, @NotNull PsiClass containingClass) {
super(manager, JavaLanguage.INSTANCE);
myOriginalProperty = originalProperty;
myField = field;
myContainingClass = containingClass;
this.origin = origin;
this.delegate = delegate;
this.containingClass = containingClass;
}
@NotNull
@Override
public void setInitializer(@Nullable final PsiExpression initializer) throws IncorrectOperationException {
public abstract KotlinLightField<T, D> copy();
@Override
public void setInitializer(@Nullable PsiExpression initializer) throws IncorrectOperationException {
throw new IncorrectOperationException("Not supported");
}
@NotNull
@Override
public SearchScope getUseScope() {
return myField.getUseScope();
return delegate.getUseScope();
}
@Override
public String getName() {
return myField.getName();
return delegate.getName();
}
@NotNull
@Override
public PsiIdentifier getNameIdentifier() {
return myField.getNameIdentifier();
return delegate.getNameIdentifier();
}
@Override
public PsiDocComment getDocComment() {
return myField.getDocComment();
return delegate.getDocComment();
}
@Override
public boolean isDeprecated() {
return myField.isDeprecated();
return delegate.isDeprecated();
}
@Override
public PsiClass getContainingClass() {
return myContainingClass;
return containingClass;
}
@NotNull
@Override
public PsiType getType() {
return myField.getType();
return delegate.getType();
}
@Override
public PsiTypeElement getTypeElement() {
return myField.getTypeElement();
return delegate.getTypeElement();
}
@Override
public PsiExpression getInitializer() {
return myField.getInitializer();
return delegate.getInitializer();
}
@Override
public boolean hasInitializer() {
return myField.hasInitializer();
return delegate.hasInitializer();
}
@Override
@@ -113,33 +112,27 @@ public class KotlinLightField extends LightElement implements PsiField, KotlinLi
@Override
public Object computeConstantValue() {
return myField.computeConstantValue();
return delegate.computeConstantValue();
}
@Override
public PsiElement setName(@NonNls @NotNull final String name) throws IncorrectOperationException {
public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException {
throw new IncorrectOperationException("Not supported");
}
@Override
public PsiModifierList getModifierList() {
return myField.getModifierList();
return delegate.getModifierList();
}
@Override
public boolean hasModifierProperty(@NonNls @NotNull final String name) {
return myField.hasModifierProperty(name);
public boolean hasModifierProperty(@NonNls @NotNull String name) {
return delegate.hasModifierProperty(name);
}
@Override
public String getText() {
return myField.getText();
}
@NotNull
@Override
public PsiElement copy() {
return new KotlinLightField(myManager, myOriginalProperty, (PsiField)myField.copy(), myContainingClass);
return delegate.getText();
}
@Override
@@ -149,7 +142,7 @@ public class KotlinLightField extends LightElement implements PsiField, KotlinLi
@Override
public boolean isValid() {
return myContainingClass.isValid();
return containingClass.isValid();
}
@Override
@@ -159,14 +152,14 @@ public class KotlinLightField extends LightElement implements PsiField, KotlinLi
@NotNull
@Override
public JetProperty getOrigin() {
return myOriginalProperty;
public T getOrigin() {
return origin;
}
@NotNull
@Override
public PsiField getDelegate() {
return myField;
public D getDelegate() {
return delegate;
}
@NotNull
@@ -0,0 +1,29 @@
/*
* Copyright 2010-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.jet.asJava.light
import com.intellij.psi.*
import org.jetbrains.jet.lang.psi.JetProperty
class KotlinLightFieldForDeclaration(
manager: PsiManager,
origin: JetProperty,
field: PsiField,
containingClass: PsiClass
) : KotlinLightField<JetProperty, PsiField>(manager, origin, field, containingClass) {
override fun copy() = KotlinLightFieldForDeclaration(getManager()!!, getOrigin(), getDelegate(), getContainingClass()!!)
}