From 19dd2e5e1b91b32ba29382e7641d73564cbc14cf Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 28 Aug 2013 21:54:03 +0400 Subject: [PATCH] Create special classes for decompiled Java enums Simplify logic in JavaConstructorResolver and JavaClassResolver --- .../JavaEnumClassObjectDescriptor.java | 61 +++++++++++++++++++ .../java/resolver/JavaClassResolver.java | 56 +++++++---------- .../resolver/JavaConstructorResolver.java | 8 +-- .../scope/JavaClassNonStaticMembersScope.java | 10 +-- .../java/scope/JavaEnumClassObjectScope.java | 42 +++++++++++++ 5 files changed, 129 insertions(+), 48 deletions(-) create mode 100644 core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/descriptor/JavaEnumClassObjectDescriptor.java create mode 100644 core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaEnumClassObjectScope.java diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/descriptor/JavaEnumClassObjectDescriptor.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/descriptor/JavaEnumClassObjectDescriptor.java new file mode 100644 index 00000000000..405988bde39 --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/descriptor/JavaEnumClassObjectDescriptor.java @@ -0,0 +1,61 @@ +/* + * Copyright 2010-2013 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.lang.resolve.java.descriptor; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.ClassKind; +import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl; +import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptorLite; +import org.jetbrains.jet.lang.resolve.DescriptorFactory; + +import java.util.Collection; +import java.util.Collections; + +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getClassObjectName; + +public class JavaEnumClassObjectDescriptor extends MutableClassDescriptorLite { + private ConstructorDescriptor constructor; + + public JavaEnumClassObjectDescriptor(@NotNull DeclarationDescriptor enumClass) { + super(enumClass, getClassObjectName(enumClass.getName()), ClassKind.CLASS_OBJECT, false); + } + + private void initConstructor() { + if (constructor == null) { + ConstructorDescriptorImpl constructor = DescriptorFactory.createPrimaryConstructorForObject(this); + constructor.setReturnType(getDefaultType()); + this.constructor = constructor; + } + } + + @NotNull + @Override + public Collection getConstructors() { + initConstructor(); + return Collections.singleton(constructor); + } + + @Nullable + @Override + public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() { + initConstructor(); + return constructor; + } +} diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java index ccb0ec2449d..262cce0bb53 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java @@ -28,8 +28,10 @@ import org.jetbrains.jet.lang.resolve.java.JavaClassFinder; import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames; import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode; +import org.jetbrains.jet.lang.resolve.java.descriptor.JavaEnumClassObjectDescriptor; import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils; import org.jetbrains.jet.lang.resolve.java.scope.JavaClassNonStaticMembersScope; +import org.jetbrains.jet.lang.resolve.java.scope.JavaEnumClassObjectScope; import org.jetbrains.jet.lang.resolve.java.structure.JavaClass; import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod; import org.jetbrains.jet.lang.resolve.kotlin.DeserializedDescriptorResolver; @@ -271,7 +273,7 @@ public final class JavaClassResolver { classDescriptor.setModality(determineClassModality(javaClass)); classDescriptor.createTypeConstructor(); - JavaClassNonStaticMembersScope scope = new JavaClassNonStaticMembersScope(classDescriptor, javaClass, false, memberResolver); + JavaClassNonStaticMembersScope scope = new JavaClassNonStaticMembersScope(classDescriptor, javaClass, memberResolver); classDescriptor.setScopeForMemberLookup(scope); classDescriptor.setScopeForConstructorResolve(scope); @@ -282,9 +284,10 @@ public final class JavaClassResolver { supertypes.addAll(supertypesResolver.getSupertypes(classDescriptor, javaClass, classTypeParameters)); if (javaClass.isEnum()) { - ClassDescriptorFromJvmBytecode classObjectDescriptor = createClassObjectDescriptorForEnum(classDescriptor, javaClass); - cache(getFqNameForClassObject(javaClass), classObjectDescriptor); - classDescriptor.getBuilder().setClassObjectDescriptor(classObjectDescriptor); + JavaEnumClassObjectDescriptor enumClassObject = createEnumClassObject(classDescriptor, javaClass); + createEnumSyntheticMethods(enumClassObject, classDescriptor.getDefaultType()); + cache(getFqNameForClassObject(javaClass), enumClassObject); + classDescriptor.getBuilder().setClassObjectDescriptor(enumClassObject); } classDescriptor.setAnnotations(annotationResolver.resolveAnnotations(javaClass, taskList)); @@ -424,43 +427,30 @@ public final class JavaClassResolver { return javaClass.getOuterClass() != null && !javaClass.isStatic(); } - @NotNull - private ClassDescriptorFromJvmBytecode createClassObjectDescriptorForEnum( - @NotNull ClassDescriptor containing, - @NotNull JavaClass javaClass - ) { - ClassDescriptorFromJvmBytecode classObjectDescriptor = createSyntheticClassObject(containing, javaClass); + private static void createEnumSyntheticMethods(@NotNull JavaEnumClassObjectDescriptor classObject, @NotNull JetType enumType) { + JetType valuesReturnType = KotlinBuiltIns.getInstance().getArrayType(enumType); + SimpleFunctionDescriptor valuesMethod = DescriptorFactory.createEnumClassObjectValuesMethod(classObject, valuesReturnType); + classObject.getBuilder().addFunctionDescriptor(valuesMethod); - JetType valuesReturnType = KotlinBuiltIns.getInstance().getArrayType(containing.getDefaultType()); - SimpleFunctionDescriptor valuesMethod = - DescriptorFactory.createEnumClassObjectValuesMethod(classObjectDescriptor, valuesReturnType); - classObjectDescriptor.getBuilder().addFunctionDescriptor(valuesMethod); - - JetType valueOfReturnType = containing.getDefaultType(); - SimpleFunctionDescriptor valueOfMethod = - DescriptorFactory.createEnumClassObjectValueOfMethod(classObjectDescriptor, valueOfReturnType); - classObjectDescriptor.getBuilder().addFunctionDescriptor(valueOfMethod); - - return classObjectDescriptor; + SimpleFunctionDescriptor valueOfMethod = DescriptorFactory.createEnumClassObjectValueOfMethod(classObject, enumType); + classObject.getBuilder().addFunctionDescriptor(valueOfMethod); } @NotNull - private ClassDescriptorFromJvmBytecode createSyntheticClassObject(@NotNull ClassDescriptor containing, @NotNull JavaClass javaClass) { - ClassDescriptorFromJvmBytecode classObjectDescriptor = - new ClassDescriptorFromJvmBytecode(containing, getClassObjectName(containing.getName()), ClassKind.CLASS_OBJECT, false); + private JavaEnumClassObjectDescriptor createEnumClassObject(@NotNull ClassDescriptor enumClass, @NotNull JavaClass javaClass) { + JavaEnumClassObjectDescriptor classObject = new JavaEnumClassObjectDescriptor(enumClass); - classObjectDescriptor.setModality(Modality.FINAL); - classObjectDescriptor.setVisibility(containing.getVisibility()); - classObjectDescriptor.setTypeParameterDescriptors(Collections.emptyList()); - classObjectDescriptor.createTypeConstructor(); + classObject.setModality(Modality.FINAL); + classObject.setVisibility(enumClass.getVisibility()); + classObject.setTypeParameterDescriptors(Collections.emptyList()); + classObject.createTypeConstructor(); - JavaClassNonStaticMembersScope scope = new JavaClassNonStaticMembersScope(classObjectDescriptor, javaClass, true, memberResolver); + JavaEnumClassObjectScope scope = new JavaEnumClassObjectScope(classObject, javaClass, memberResolver); WritableScopeImpl writableScope = - new WritableScopeImpl(scope, classObjectDescriptor, RedeclarationHandler.THROW_EXCEPTION, "Member lookup scope"); + new WritableScopeImpl(scope, classObject, RedeclarationHandler.THROW_EXCEPTION, "Enum class object scope"); writableScope.changeLockLevel(WritableScope.LockLevel.BOTH); - classObjectDescriptor.setScopeForMemberLookup(writableScope); - classObjectDescriptor.setScopeForConstructorResolve(scope); + classObject.setScopeForMemberLookup(writableScope); - return classObjectDescriptor; + return classObject; } } diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaConstructorResolver.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaConstructorResolver.java index cd56a59261f..64eb66f4244 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaConstructorResolver.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaConstructorResolver.java @@ -22,7 +22,6 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl; import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl; -import org.jetbrains.jet.lang.resolve.DescriptorFactory; import org.jetbrains.jet.lang.resolve.java.JavaVisibilities; import org.jetbrains.jet.lang.resolve.java.structure.JavaArrayType; import org.jetbrains.jet.lang.resolve.java.structure.JavaClass; @@ -71,10 +70,7 @@ public final class JavaConstructorResolver { Collection constructors = javaClass.getConstructors(); - if (containingClass.getKind() == ClassKind.OBJECT || containingClass.getKind() == ClassKind.CLASS_OBJECT) { - result.add(DescriptorFactory.createPrimaryConstructorForObject(containingClass)); - } - else if (constructors.isEmpty()) { + if (constructors.isEmpty()) { ConstructorDescriptor defaultConstructor = resolveDefaultConstructor(javaClass, containingClass); if (defaultConstructor != null) { result.add(defaultConstructor); @@ -225,4 +221,4 @@ public final class JavaConstructorResolver { private static ConstructorDescriptor resolveSamAdapter(@NotNull ConstructorDescriptor original) { return isSamAdapterNecessary(original) ? (ConstructorDescriptor) createSamAdapterConstructor(original) : null; } -} \ No newline at end of file +} diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaClassNonStaticMembersScope.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaClassNonStaticMembersScope.java index bd36883dca4..d4f2d12acde 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaClassNonStaticMembersScope.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaClassNonStaticMembersScope.java @@ -25,7 +25,6 @@ import org.jetbrains.jet.lang.resolve.name.FqName; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.List; import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.IGNORE_KOTLIN_SOURCES; @@ -35,18 +34,15 @@ public final class JavaClassNonStaticMembersScope extends JavaClassMembersScope private final ClassDescriptor descriptor; @NotNull private final JavaClass javaClass; - private final boolean staticMembersOfPsiClass; public JavaClassNonStaticMembersScope( @NotNull ClassDescriptor descriptor, @NotNull JavaClass javaClass, - boolean staticMembersOfClass, @NotNull JavaMemberResolver memberResolver ) { - super(descriptor, MembersProvider.forClass(javaClass, staticMembersOfClass), memberResolver); + super(descriptor, MembersProvider.forClass(javaClass, false), memberResolver); this.descriptor = descriptor; this.javaClass = javaClass; - this.staticMembersOfPsiClass = staticMembersOfClass; } @NotNull @@ -57,10 +53,6 @@ public final class JavaClassNonStaticMembersScope extends JavaClassMembersScope @NotNull @Override protected Collection computeInnerClasses() { - if (staticMembersOfPsiClass) { - return Collections.emptyList(); - } - Collection innerClasses = javaClass.getInnerClasses(); List result = new ArrayList(innerClasses.size()); for (JavaClass innerClass : innerClasses) { diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaEnumClassObjectScope.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaEnumClassObjectScope.java new file mode 100644 index 00000000000..e4b3869930b --- /dev/null +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaEnumClassObjectScope.java @@ -0,0 +1,42 @@ +/* + * Copyright 2010-2013 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.lang.resolve.java.scope; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor; +import org.jetbrains.jet.lang.resolve.java.resolver.JavaMemberResolver; +import org.jetbrains.jet.lang.resolve.java.structure.JavaClass; + +import java.util.Collection; +import java.util.Collections; + +public class JavaEnumClassObjectScope extends JavaClassMembersScope { + public JavaEnumClassObjectScope( + @NotNull ClassOrNamespaceDescriptor descriptor, + @NotNull JavaClass javaClass, + @NotNull JavaMemberResolver memberResolver + ) { + super(descriptor, MembersProvider.forClass(javaClass, true), memberResolver); + } + + @NotNull + @Override + protected Collection computeInnerClasses() { + return Collections.emptyList(); + } +}