From 43468c6d55599b7b8f2cf2e858a57b89590c99e5 Mon Sep 17 00:00:00 2001 From: Igor Yakovlev Date: Thu, 26 Mar 2020 23:36:31 +0300 Subject: [PATCH] Filter enum synthetic methods for stub based classes Fixed #KT-36095 --- .../kotlin/asJava/SyntheticElementUtils.kt | 15 +++++++ .../load/java/structure/impl/JavaClassImpl.kt | 12 +----- .../builder/ClsWrapperStubPsiFactory.java | 43 ++++++++++++------- 3 files changed, 45 insertions(+), 25 deletions(-) create mode 100644 compiler/frontend.java/src/org/jetbrains/kotlin/asJava/SyntheticElementUtils.kt diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/asJava/SyntheticElementUtils.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/asJava/SyntheticElementUtils.kt new file mode 100644 index 00000000000..59b8734bb52 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/asJava/SyntheticElementUtils.kt @@ -0,0 +1,15 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.asJava + +import com.intellij.psi.PsiMethod +import com.intellij.psi.SyntheticElement +import org.jetbrains.kotlin.resolve.DescriptorUtils + +fun isSyntheticValuesOrValueOfMethod(method: PsiMethod): Boolean { + if (method !is SyntheticElement) return false + return DescriptorUtils.ENUM_VALUE_OF.asString() == method.name || DescriptorUtils.ENUM_VALUES.asString() == method.name +} diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/JavaClassImpl.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/JavaClassImpl.kt index e74aba3b71b..a5ec0e97d62 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/JavaClassImpl.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/java/structure/impl/JavaClassImpl.kt @@ -19,17 +19,15 @@ package org.jetbrains.kotlin.load.java.structure.impl import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.vfs.VirtualFile import com.intellij.psi.PsiClass -import com.intellij.psi.PsiMethod import com.intellij.psi.PsiTypeParameter -import com.intellij.psi.SyntheticElement import com.intellij.psi.search.SearchScope import org.jetbrains.kotlin.asJava.KtLightClassMarker +import org.jetbrains.kotlin.asJava.isSyntheticValuesOrValueOfMethod import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.load.java.structure.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtPsiUtil -import org.jetbrains.kotlin.resolve.DescriptorUtils class JavaClassImpl(psiClass: PsiClass) : JavaClassifierImpl(psiClass), VirtualFileBoundJavaClass, JavaAnnotationOwnerImpl, JavaModifierListOwnerImpl { init { @@ -80,7 +78,7 @@ class JavaClassImpl(psiClass: PsiClass) : JavaClassifierImpl(psiClass) // Return type seems to be null for example for the 'clone' Groovy method generated by @AutoClone (see EA-73795) return methods( psi.methods.filter { method -> - !method.isConstructor && method.returnType != null && !isSyntheticValuesOrValueOfMethod(method) + !method.isConstructor && method.returnType != null && !(isEnum && isSyntheticValuesOrValueOfMethod(method)) } ).distinct() } @@ -124,12 +122,6 @@ class JavaClassImpl(psiClass: PsiClass) : JavaClassifierImpl(psiClass) override fun getAnnotationOwnerPsi() = psi.modifierList - private fun isSyntheticValuesOrValueOfMethod(method: PsiMethod): Boolean { - if (!isEnum) return false - if (method !is SyntheticElement) return false - return DescriptorUtils.ENUM_VALUE_OF.asString() == method.name || DescriptorUtils.ENUM_VALUES.asString() == method.name - } - private fun assertNotLightClass() { val psiClass = psi if (psiClass !is KtLightClassMarker) return diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/builder/ClsWrapperStubPsiFactory.java b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/builder/ClsWrapperStubPsiFactory.java index 1ce0a9f621a..5d05d4fca2a 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/builder/ClsWrapperStubPsiFactory.java +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/builder/ClsWrapperStubPsiFactory.java @@ -1,34 +1,23 @@ /* - * Copyright 2010-2016 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. + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.asJava.builder; import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.UserDataHolder; import com.intellij.psi.*; import com.intellij.psi.impl.compiled.ClsClassImpl; import com.intellij.psi.impl.compiled.ClsEnumConstantImpl; import com.intellij.psi.impl.compiled.ClsFieldImpl; -import com.intellij.psi.impl.compiled.ClsRepositoryPsiElement; import com.intellij.psi.impl.java.stubs.*; import com.intellij.psi.stubs.StubBase; import com.intellij.psi.stubs.StubElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import static org.jetbrains.kotlin.asJava.SyntheticElementUtilsKt.isSyntheticValuesOrValueOfMethod; + public class ClsWrapperStubPsiFactory extends StubPsiFactory { public static final Key ORIGIN = Key.create("ORIGIN"); public static final ClsWrapperStubPsiFactory INSTANCE = new ClsWrapperStubPsiFactory(); @@ -54,6 +43,30 @@ public class ClsWrapperStubPsiFactory extends StubPsiFactory { public PsiClass getSourceMirrorClass() { return null; } + + @NotNull + @Override + public PsiMethod[] getMethods() { + PsiMethod[] baseMethods = super.getMethods(); + if (!isEnum()) return baseMethods; + + int filteredArraySize = 0; + for (PsiMethod method : baseMethods) { + if (!isSyntheticValuesOrValueOfMethod(method)) filteredArraySize++; + } + + if (filteredArraySize == baseMethods.length) return baseMethods; + + PsiMethod[] filteredMethods = new PsiMethod[filteredArraySize]; + int index = 0; + for (PsiMethod method : baseMethods) { + if (!isSyntheticValuesOrValueOfMethod(method)) { + filteredMethods[index] = method; + index++; + } + } + return filteredMethods; + } }; }