diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightEnumConstant.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightEnumConstant.kt deleted file mode 100644 index 59747e820fe..00000000000 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightEnumConstant.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2010-2015 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.kotlin.asJava - -import com.intellij.psi.* -import org.jetbrains.kotlin.psi.KtEnumEntry - -class KotlinLightEnumConstant( - manager: PsiManager, - origin: KtEnumEntry, - enumConstant: PsiEnumConstant, - containingClass: PsiClass, - private val initializingClass: PsiEnumConstantInitializer? -) : KotlinLightField(manager, origin, enumConstant, containingClass), PsiEnumConstant { - override fun copy() = KotlinLightEnumConstant(getManager()!!, getOrigin(), getDelegate(), getContainingClass()!!, initializingClass) - - // 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? = initializingClass - override fun getOrCreateInitializingClass(): PsiEnumConstantInitializer = - initializingClass ?: throw UnsupportedOperationException("Can't create enum constant body: ${getDelegate().getName()}") - override fun resolveConstructor(): PsiMethod? = getDelegate().resolveConstructor() - override fun resolveMethod(): PsiMethod? = getDelegate().resolveMethod() - override fun resolveMethodGenerics(): JavaResolveResult = getDelegate().resolveMethodGenerics() -} diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightField.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightField.kt index 53cc4fbdb18..94ff30c33f0 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightField.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightField.kt @@ -16,135 +16,122 @@ package org.jetbrains.kotlin.asJava -import com.intellij.lang.Language -import com.intellij.lang.java.JavaLanguage import com.intellij.openapi.util.TextRange import com.intellij.psi.* import com.intellij.psi.impl.light.LightElement -import com.intellij.psi.javadoc.PsiDocComment -import com.intellij.psi.search.SearchScope import com.intellij.util.IncorrectOperationException import org.jetbrains.annotations.NonNls import org.jetbrains.kotlin.idea.KotlinLanguage +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtEnumEntry +import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext + +public interface KotlinLightField : PsiField, KotlinLightElement // Copied from com.intellij.psi.impl.light.LightField -abstract class KotlinLightField( - manager: PsiManager, - private val origin: T, - private val delegate: D, - private val containingClass: PsiClass -) : LightElement(manager, JavaLanguage.INSTANCE), PsiField, KotlinLightElement { +sealed class KotlinLightFieldImpl( + private val origin: KtDeclaration?, + private val delegate: PsiField, + private val containingClass: KotlinLightClass +) : LightElement(delegate.manager, KotlinLanguage.INSTANCE), KotlinLightField { + @Throws(IncorrectOperationException::class) + override fun setInitializer(initializer: PsiExpression?) = throw IncorrectOperationException("Not supported") - abstract override fun copy(): KotlinLightField + override fun getUseScope() = origin?.useScope ?: super.getUseScope() + + override fun getName() = delegate.name + + override fun getNameIdentifier() = delegate.nameIdentifier + + override fun getDocComment() = delegate.docComment + + override fun isDeprecated() = delegate.isDeprecated + + override fun getContainingClass() = containingClass + + override fun getType() = delegate.type + + override fun getTypeElement() = delegate.typeElement + + override fun getInitializer() = delegate.initializer + + override fun hasInitializer() = delegate.hasInitializer() @Throws(IncorrectOperationException::class) - override fun setInitializer(initializer: PsiExpression?) { - throw IncorrectOperationException("Not supported") - } + override fun normalizeDeclaration() = throw IncorrectOperationException("Not supported") - override fun getUseScope(): SearchScope { - return origin.useScope - } - - override fun getName(): String? { - return delegate.name - } - - override fun getNameIdentifier(): PsiIdentifier { - return delegate.nameIdentifier - } - - override fun getDocComment(): PsiDocComment? { - return delegate.docComment - } - - override fun isDeprecated(): Boolean { - return delegate.isDeprecated - } - - override fun getContainingClass(): PsiClass? { - return containingClass - } - - override fun getType(): PsiType { - return delegate.type - } - - override fun getTypeElement(): PsiTypeElement? { - return delegate.typeElement - } - - override fun getInitializer(): PsiExpression? { - return delegate.initializer - } - - override fun hasInitializer(): Boolean { - return delegate.hasInitializer() - } + override fun computeConstantValue() = delegate.computeConstantValue() @Throws(IncorrectOperationException::class) - override fun normalizeDeclaration() { - throw IncorrectOperationException("Not supported") - } + override fun setName(@NonNls name: String) = throw IncorrectOperationException("Not supported") - override fun computeConstantValue(): Any? { - return delegate.computeConstantValue() - } + override fun getModifierList() = delegate.modifierList - @Throws(IncorrectOperationException::class) - override fun setName(@NonNls name: String): PsiElement { - throw IncorrectOperationException("Not supported") - } + override fun hasModifierProperty(@NonNls name: String) = delegate.hasModifierProperty(name) - override fun getModifierList(): PsiModifierList? { - return delegate.modifierList - } + override fun getText() = delegate.text - override fun hasModifierProperty(@NonNls name: String): Boolean { - return delegate.hasModifierProperty(name) - } + override fun getTextRange() = TextRange(-1, -1) - override fun getText(): String { - return delegate.text - } + override fun isValid() = containingClass.isValid - override fun getTextRange(): TextRange { - return TextRange(-1, -1) - } + override fun toString(): String = "${this.javaClass.simpleName}:$name" - override fun isValid(): Boolean { - return containingClass.isValid - } + override fun getOrigin() = origin - override fun toString(): String { - return "KotlinLightField:" + name!! - } + override fun getDelegate() = delegate - override fun getOrigin(): T { - return origin - } - - override fun getDelegate(): D { - return delegate - } - - override fun getNavigationElement(): PsiElement { - return getOrigin() - } - - override fun getLanguage(): Language { - return KotlinLanguage.INSTANCE - } + override fun getNavigationElement() = origin ?: super.getNavigationElement() override fun isEquivalentTo(another: PsiElement?): Boolean { - if (another is KotlinLightField<*, *> && origin.isEquivalentTo(another.getOrigin())) { + if (another is KotlinLightField && origin == another.getOrigin() && delegate == another.getDelegate()) { return true } return super.isEquivalentTo(another) } - override fun isWritable(): Boolean { - return getOrigin().isWritable + override fun isWritable() = getOrigin()?.isWritable ?: false + + override fun copy() = Factory.create(origin?.copy() as? KtDeclaration, delegate, containingClass) + + class KotlinLightEnumConstant( + origin: KtEnumEntry, + enumConstant: PsiEnumConstant, + containingClass: KotlinLightClass, + private val initializingClass: PsiEnumConstantInitializer? + ) : KotlinLightFieldImpl(origin, enumConstant, containingClass), PsiEnumConstant { + override fun getDelegate() = super.getDelegate() as PsiEnumConstant + + // 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() = getDelegate().argumentList + + override fun getInitializingClass(): PsiEnumConstantInitializer? = initializingClass + override fun getOrCreateInitializingClass(): PsiEnumConstantInitializer = + initializingClass ?: throw UnsupportedOperationException("Can't create enum constant body: ${getDelegate().getName()}") + + override fun resolveConstructor() = getDelegate().resolveConstructor() + override fun resolveMethod() = getDelegate().resolveMethod() + override fun resolveMethodGenerics() = getDelegate().resolveMethodGenerics() + } + + public class KotlinLightFieldForDeclaration(origin: KtDeclaration?, delegate: PsiField, containingClass: KotlinLightClass) + : KotlinLightFieldImpl(origin, delegate, containingClass) + + companion object Factory { + fun create(origin: KtDeclaration?, delegate: PsiField, containingClass: KotlinLightClass): KotlinLightField { + if (origin is KtEnumEntry) { + assert(delegate is PsiEnumConstant) { "Field delegate should be an enum constant (${delegate.name}):\n${origin.getElementTextWithContext()}" } + val enumConstant = delegate as PsiEnumConstant + val enumConstantFqName = FqName(containingClass.getFqName().asString() + "." + origin.name) + val initializingClass = if (origin.declarations.isEmpty()) + null + else + KotlinLightClassForEnumEntry(delegate.manager, enumConstantFqName, origin, enumConstant) + return KotlinLightEnumConstant(origin, enumConstant, containingClass, initializingClass) + } + return KotlinLightFieldForDeclaration(origin, delegate, containingClass) + } } } diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightFieldForDeclaration.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightFieldForDeclaration.kt deleted file mode 100644 index f5fd571c3a5..00000000000 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightFieldForDeclaration.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2010-2015 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.kotlin.asJava - -import com.intellij.psi.* -import org.jetbrains.kotlin.psi.KtDeclaration - -class KotlinLightFieldForDeclaration( - manager: PsiManager, - origin: KtDeclaration, - field: PsiField, - containingClass: PsiClass -) : KotlinLightField(manager, origin, field, containingClass) { - override fun copy() = KotlinLightFieldForDeclaration(getManager()!!, getOrigin(), getDelegate(), getContainingClass()!!) -} diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightNoOriginElements.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightNoOriginElements.kt deleted file mode 100644 index 531dd69f830..00000000000 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightNoOriginElements.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2010-2015 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.kotlin.asJava - -import com.intellij.psi.PsiClass -import com.intellij.psi.PsiField -import com.intellij.psi.PsiManager -import com.intellij.psi.impl.light.LightField - -public class KotlinNoOriginLightField(manager: PsiManager, field: PsiField, containingClass: PsiClass) : - LightField(manager, field, containingClass) { - - override fun toString() = "KotlinNoOriginLightField:${getName()}" -} \ No newline at end of file diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinWrappingLightClass.java b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinWrappingLightClass.java index 14c96bda575..09ae32b5275 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinWrappingLightClass.java +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinWrappingLightClass.java @@ -122,22 +122,7 @@ public abstract class KotlinWrappingLightClass extends AbstractLightClass implem @Override public PsiField fun(PsiField field) { KtDeclaration declaration = ClsWrapperStubPsiFactory.getOriginalDeclaration(field); - if (declaration instanceof KtEnumEntry) { - assert field instanceof PsiEnumConstant : "Field delegate should be an enum constant (" + field.getName() + "):\n" + - PsiUtilsKt.getElementTextWithContext(declaration); - KtEnumEntry enumEntry = (KtEnumEntry) declaration; - PsiEnumConstant enumConstant = (PsiEnumConstant) field; - FqName enumConstantFqName = new FqName(getFqName().asString() + "." + enumEntry.getName()); - KotlinLightClassForEnumEntry initializingClass = - enumEntry.getDeclarations().isEmpty() - ? null - : new KotlinLightClassForEnumEntry(myManager, enumConstantFqName, enumEntry, enumConstant); - return new KotlinLightEnumConstant(myManager, enumEntry, enumConstant, KotlinWrappingLightClass.this, initializingClass); - } - if (declaration != null) { - return new KotlinLightFieldForDeclaration(myManager, declaration, field, KotlinWrappingLightClass.this); - } - return new KotlinNoOriginLightField(myManager, field, KotlinWrappingLightClass.this); + return KotlinLightFieldImpl.Factory.create(declaration, field, KotlinWrappingLightClass.this); } }); } diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/LightClassUtil.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/LightClassUtil.kt index 876396ea7f8..49007608200 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/LightClassUtil.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/LightClassUtil.kt @@ -179,7 +179,7 @@ public object LightClassUtil { } for (field in psiClass.fields) { - if (field is KotlinLightField<*, *> && field.getOrigin() === declaration) { + if (field is KotlinLightField && field.getOrigin() === declaration) { return field } } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinReferencesSearcher.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinReferencesSearcher.kt index 036c81fcbf6..85d6dcd6729 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinReferencesSearcher.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinReferencesSearcher.kt @@ -192,7 +192,7 @@ public class KotlinReferencesSearcher : QueryExecutorBase?> = originLightClass.methods.map { it as? KotlinLightMethod } + - originLightClass.fields.map { it as? KotlinLightFieldForDeclaration } + originLightClass.fields.map { it as? KotlinLightField } for (declaration in element.declarations) { val lightDeclaration = lightDeclarations.find { it?.getOrigin() == declaration } diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/DeprecatedUsageOfStaticField.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/DeprecatedUsageOfStaticField.kt index b2607e6b12a..533aa91ac13 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/DeprecatedUsageOfStaticField.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/DeprecatedUsageOfStaticField.kt @@ -20,7 +20,7 @@ import com.intellij.codeInspection.* import com.intellij.openapi.project.Project import com.intellij.psi.* import org.jetbrains.kotlin.asJava.KotlinLightClass -import org.jetbrains.kotlin.asJava.KotlinLightFieldForDeclaration +import org.jetbrains.kotlin.asJava.KotlinLightField import org.jetbrains.kotlin.idea.quickfix.AddConstModifierFix import org.jetbrains.kotlin.idea.quickfix.AddConstModifierIntention import org.jetbrains.kotlin.idea.quickfix.replaceReferencesToGetterByReferenceToField @@ -39,7 +39,7 @@ class DeprecatedUsageOfStaticFieldInspection : LocalInspectionTool(), CleanupLoc val resolvedTo = expression.reference?.resolve() as? PsiField ?: return if (!resolvedTo.hasModifierProperty(PsiModifier.STATIC) || !resolvedTo.isDeprecated) return - val kotlinProperty = (resolvedTo as? KotlinLightFieldForDeclaration)?.getOrigin() as? KtProperty + val kotlinProperty = (resolvedTo as? KotlinLightField)?.getOrigin() as? KtProperty // NOTE: this is hack to avoid test failing with "action is still available" error if (kotlinProperty?.hasJvmFieldAnnotationOrConstModifier() ?: false) return @@ -88,7 +88,7 @@ class DeprecatedUsageOfStaticFieldInspection : LocalInspectionTool(), CleanupLoc abstract class StaticFieldUsageFix: LocalQuickFix { override fun applyFix(project: Project, descriptor: ProblemDescriptor) { val deprecatedField = descriptor.psiElement.reference?.resolve() as? PsiField ?: return - val kotlinProperty = (deprecatedField as? KotlinLightFieldForDeclaration)?.getOrigin() as? KtProperty + val kotlinProperty = (deprecatedField as? KotlinLightField)?.getOrigin() as? KtProperty if (kotlinProperty != null && kotlinProperty.hasJvmFieldAnnotationOrConstModifier()) return diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ExpressionConverter.kt b/j2k/src/org/jetbrains/kotlin/j2k/ExpressionConverter.kt index 59540ff52b7..f7d9c17a02d 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ExpressionConverter.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ExpressionConverter.kt @@ -422,7 +422,7 @@ class DefaultExpressionConverter : JavaElementVisitor(), ExpressionConverter { identifier = Identifier("size()", isNullable).assignNoPrototype() } else if (qualifier != null) { - if (target is KotlinLightField<*, *> && target.getOrigin() is KtObjectDeclaration) { + if (target is KotlinLightField && target.getOrigin() is KtObjectDeclaration) { result = codeConverter.convertExpression(qualifier) return }