diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/DescriptorResolverUtils.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/DescriptorResolverUtils.java index d7da4fb4381..276559c40fc 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/DescriptorResolverUtils.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/DescriptorResolverUtils.java @@ -40,9 +40,9 @@ public final class DescriptorResolverUtils { } public static boolean isCompiledKotlinPackageClass(@NotNull JavaClass javaClass) { - if (javaClass.getPsiClass() instanceof ClsClassImpl) { - String fqName = javaClass.getFqName(); - if (fqName != null && PackageClassUtils.isPackageClassFqName(new FqName(fqName))) { + if (javaClass.getPsi() instanceof ClsClassImpl) { + FqName fqName = javaClass.getFqName(); + if (fqName != null && PackageClassUtils.isPackageClassFqName(fqName)) { return hasAnnotation(javaClass, JvmAnnotationNames.KOTLIN_PACKAGE.getFqName()); } } @@ -50,7 +50,7 @@ public final class DescriptorResolverUtils { } public static boolean isCompiledKotlinClass(@NotNull JavaClass javaClass) { - if (javaClass.getPsiClass() instanceof ClsClassImpl) { + if (javaClass.getPsi() instanceof ClsClassImpl) { return hasAnnotation(javaClass, JvmAnnotationNames.KOTLIN_CLASS.getFqName()); } return false; @@ -153,11 +153,11 @@ public final class DescriptorResolverUtils { @NotNull public static Collection filterDuplicateClasses(@NotNull Collection classes) { - Set addedQualifiedNames = new HashSet(classes.size()); + Set addedQualifiedNames = new HashSet(classes.size()); List result = new ArrayList(classes.size()); for (JavaClass javaClass : classes) { - String fqName = javaClass.getFqName(); + FqName fqName = javaClass.getFqName(); if (fqName != null && addedQualifiedNames.add(fqName)) { result.add(javaClass); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java index d1cbeadb38c..818da8bd95d 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java @@ -123,7 +123,7 @@ public final class MembersCache { private void process() { for (JavaClass javaClass : javaClasses) { - PsiClass psiClass = javaClass.getPsiClass(); + PsiClass psiClass = javaClass.getPsi(); if (!(psiClass instanceof JetJavaMirrorMarker)) { // to filter out JetLightClasses if (SingleAbstractMethodUtils.isSamInterface(psiClass)) { @@ -145,7 +145,7 @@ public final class MembersCache { private final boolean staticMembers; private ClassMemberProcessor(@NotNull JavaClass javaClass, boolean staticMembers) { - this.psiClass = javaClass.getPsiClass(); + this.psiClass = javaClass.getPsi(); this.staticMembers = staticMembers; } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java index 4c8715d9506..4ece3f77c14 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java @@ -23,8 +23,6 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiMethod; -import com.intellij.psi.PsiModifier; import gnu.trove.THashMap; import gnu.trove.TObjectHashingStrategy; import org.jetbrains.annotations.NotNull; @@ -39,8 +37,8 @@ import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmByte 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.structure.JavaClass; +import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod; import org.jetbrains.jet.lang.resolve.java.vfilefinder.VirtualFileFinder; -import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqNameBase; import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe; @@ -254,14 +252,13 @@ public final class JavaClassResolver { } // Class may have been resolved previously by different Java resolver instance, and we are reusing its trace - ClassDescriptor alreadyResolved = trace.get(BindingContext.CLASS, javaClass.getPsiClass()); + ClassDescriptor alreadyResolved = trace.get(BindingContext.CLASS, javaClass.getPsi()); if (alreadyResolved != null) { return alreadyResolved; } - PsiClass psiClass = javaClass.getPsiClass(); //TODO: code duplication - ClassOrNamespaceDescriptor containingDeclaration = resolveParentDescriptor(qualifiedName, isContainedInClass(psiClass)); + ClassOrNamespaceDescriptor containingDeclaration = resolveParentDescriptor(qualifiedName, javaClass.getOuterClass() != null); // class may be resolved during resolution of parent ClassDescriptor cachedDescriptor = classDescriptorCache.get(javaClassToKotlinFqName(qualifiedName)); if (cachedDescriptor != null) { @@ -270,8 +267,8 @@ public final class JavaClassResolver { assert (!unresolvedCache .contains(qualifiedName)) : "We can resolve the class, so it can't be 'unresolved' during parent resolution"; - checkFqNamesAreConsistent(psiClass, qualifiedName); - checkPsiClassIsNotJet(psiClass); + checkFqNamesAreConsistent(javaClass, qualifiedName); + checkPsiClassIsNotJet(javaClass); return doCreateClassDescriptor(qualifiedName, javaClass, tasks, containingDeclaration); @@ -296,47 +293,46 @@ public final class JavaClassResolver { @NotNull PostponedTasks taskList, @NotNull ClassOrNamespaceDescriptor containingDeclaration ) { - PsiClass psiClass = javaClass.getPsiClass(); - - ClassDescriptorFromJvmBytecode classDescriptor = new ClassDescriptorFromJvmBytecode(containingDeclaration, getClassKind(psiClass), - isInnerClass(psiClass)); + ClassDescriptorFromJvmBytecode classDescriptor = new ClassDescriptorFromJvmBytecode(containingDeclaration, javaClass.getKind(), + isInnerClass(javaClass)); cache(javaClassToKotlinFqName(fqName), classDescriptor); - classDescriptor.setName(Name.identifier(psiClass.getName())); + classDescriptor.setName(javaClass.getName()); List typeParameterDescriptorInitializations - = JavaSignatureResolver.createUninitializedClassTypeParameters(psiClass, classDescriptor); + = JavaSignatureResolver.createUninitializedClassTypeParameters(javaClass, classDescriptor); classDescriptor.setTypeParameterDescriptors(getTypeParametersDescriptors(typeParameterDescriptorInitializations)); List supertypes = Lists.newArrayList(); classDescriptor.setSupertypes(supertypes); - classDescriptor.setVisibility(DescriptorResolverUtils.resolveVisibility(psiClass)); - classDescriptor.setModality(resolveModality(psiClass, classDescriptor)); + classDescriptor.setVisibility(javaClass.getVisibility()); + classDescriptor.setModality(javaClass.getModality()); classDescriptor.createTypeConstructor(); JavaClassNonStaticMembersScope scope = new JavaClassNonStaticMembersScope(classDescriptor, javaClass, false, javaDescriptorResolver); classDescriptor.setScopeForMemberLookup(scope); classDescriptor.setScopeForConstructorResolve(scope); - String context = "class " + psiClass.getQualifiedName(); - signatureResolver.initializeTypeParameters(typeParameterDescriptorInitializations, classDescriptor, context); + signatureResolver.initializeTypeParameters(typeParameterDescriptorInitializations, classDescriptor, + "class " + javaClass.getFqName()); // TODO: ugly hack: tests crash if initializeTypeParameters called with class containing proper supertypes List classTypeParameters = classDescriptor.getTypeConstructor().getParameters(); - supertypes.addAll(supertypesResolver.getSupertypes(classDescriptor, psiClass, classTypeParameters)); + supertypes.addAll(supertypesResolver.getSupertypes(classDescriptor, javaClass, classTypeParameters)); - if (psiClass.isEnum()) { + if (javaClass.isEnum()) { ClassDescriptorFromJvmBytecode classObjectDescriptor = createClassObjectDescriptorForEnum(classDescriptor, javaClass); - cache(getFqNameForClassObject(psiClass), classObjectDescriptor); + cache(getFqNameForClassObject(javaClass), classObjectDescriptor); classDescriptor.getBuilder().setClassObjectDescriptor(classObjectDescriptor); } + PsiClass psiClass = javaClass.getPsi(); classDescriptor.setAnnotations(annotationResolver.resolveAnnotations(psiClass, taskList)); trace.record(BindingContext.CLASS, psiClass, classDescriptor); - PsiMethod samInterfaceMethod = SingleAbstractMethodUtils.getSamInterfaceMethod(psiClass); + JavaMethod samInterfaceMethod = SingleAbstractMethodUtils.getSamInterfaceMethod(javaClass, psiClass.getProject()); if (samInterfaceMethod != null) { SimpleFunctionDescriptor abstractMethod = resolveFunctionOfSamInterface(samInterfaceMethod, classDescriptor); classDescriptor.setFunctionTypeForSamInterface(SingleAbstractMethodUtils.getFunctionTypeForAbstractMethod(abstractMethod)); @@ -346,25 +342,24 @@ public final class JavaClassResolver { } @NotNull - private static FqNameUnsafe getFqNameForClassObject(@NotNull PsiClass psiClass) { - String qualifiedName = psiClass.getQualifiedName(); - assert qualifiedName != null : "Reading java class with no qualified name"; - return new FqNameUnsafe(qualifiedName + "." + getClassObjectName(psiClass.getName()).asString()); + private static FqNameUnsafe getFqNameForClassObject(@NotNull JavaClass javaClass) { + FqName fqName = javaClass.getFqName(); + assert fqName != null : "Reading java class with no qualified name"; + return fqName.toUnsafe().child(getClassObjectName(javaClass.getName())); } @NotNull private SimpleFunctionDescriptor resolveFunctionOfSamInterface( - @NotNull PsiMethod samInterfaceMethod, + @NotNull JavaMethod samInterfaceMethod, @NotNull ClassDescriptorFromJvmBytecode samInterface ) { - PsiClass methodContainer = samInterfaceMethod.getContainingClass(); + JavaClass methodContainer = samInterfaceMethod.getContainingClass(); assert methodContainer != null : "method container is null for " + samInterfaceMethod; - String containerQualifiedName = methodContainer.getQualifiedName(); - assert containerQualifiedName != null : "qualified name is null for " + methodContainer; + FqName containerFqName = methodContainer.getFqName(); + assert containerFqName != null : "qualified name is null for " + methodContainer; - if (DescriptorUtils.getFQName(samInterface).asString().equals(containerQualifiedName)) { - SimpleFunctionDescriptor abstractMethod = - functionResolver.resolveFunctionMutely(new PsiMethodWrapper(samInterfaceMethod), samInterface); + if (DescriptorUtils.getFQName(samInterface).equalsTo(containerFqName)) { + SimpleFunctionDescriptor abstractMethod = functionResolver.resolveFunctionMutely(samInterfaceMethod, samInterface); assert abstractMethod != null : "couldn't resolve method " + samInterfaceMethod; return abstractMethod; } @@ -373,6 +368,7 @@ public final class JavaClassResolver { } } + @NotNull private static SimpleFunctionDescriptor findFunctionWithMostSpecificReturnType(@NotNull Set supertypes) { List candidates = Lists.newArrayList(); for (JetType supertype : supertypes) { @@ -386,7 +382,10 @@ public final class JavaClassResolver { } SimpleFunctionDescriptor currentMostSpecificType = candidates.get(0); for (SimpleFunctionDescriptor candidate : candidates) { - if (JetTypeChecker.INSTANCE.isSubtypeOf(candidate.getReturnType(), currentMostSpecificType.getReturnType())) { + JetType candidateReturnType = candidate.getReturnType(); + JetType currentMostSpecificReturnType = currentMostSpecificType.getReturnType(); + assert candidateReturnType != null && currentMostSpecificReturnType != null : candidate + ", " + currentMostSpecificReturnType; + if (JetTypeChecker.INSTANCE.isSubtypeOf(candidateReturnType, currentMostSpecificReturnType)) { currentMostSpecificType = candidate; } } @@ -414,31 +413,18 @@ public final class JavaClassResolver { return typeParameters; } - @NotNull - private static Modality resolveModality(@NotNull PsiClass psiClass, @NotNull ClassDescriptor classDescriptor) { - if (classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS) { - return Modality.FINAL; - } - return Modality.convertFromFlags( - psiClass.hasModifierProperty(PsiModifier.ABSTRACT) || psiClass.isInterface(), - !psiClass.hasModifierProperty(PsiModifier.FINAL)); - } - - private void checkFqNamesAreConsistent(@NotNull PsiClass psiClass, @NotNull FqName desiredFqName) { - String qualifiedName = psiClass.getQualifiedName(); - assert qualifiedName != null; - - FqName fqName = new FqName(qualifiedName); - assert fqName.equals(desiredFqName); + private void checkFqNamesAreConsistent(@NotNull JavaClass javaClass, @NotNull FqName desiredFqName) { + FqName fqName = javaClass.getFqName(); + assert desiredFqName.equals(fqName) : "Inconsistent FQ names: " + fqName + ", " + desiredFqName; FqNameUnsafe correctedName = javaClassToKotlinFqName(fqName); if (classDescriptorCache.containsKey(correctedName) || unresolvedCache.contains(correctedName)) { - throw new IllegalStateException(qualifiedName); + throw new IllegalStateException("Cache already contains FQ name: " + fqName.asString()); } } - private static void checkPsiClassIsNotJet(@NotNull PsiClass psiClass) { - if (psiClass instanceof JetJavaMirrorMarker) { - throw new IllegalStateException("trying to resolve fake jet PsiClass as regular PsiClass: " + psiClass.getQualifiedName()); + private static void checkPsiClassIsNotJet(@NotNull JavaClass javaClass) { + if (javaClass.getPsi() instanceof JetJavaMirrorMarker) { + throw new IllegalStateException("trying to resolve fake jet PsiClass as regular PsiClass: " + javaClass.getFqName()); } } @@ -478,23 +464,8 @@ public final class JavaClassResolver { return new FqNameUnsafe(StringUtil.join(correctedSegments, ".")); } - private static boolean isContainedInClass(@NotNull PsiClass psiClass) { - return psiClass.getContainingClass() != null; - } - - private static boolean isInnerClass(@NotNull PsiClass psiClass) { - return isContainedInClass(psiClass) && !psiClass.hasModifierProperty(PsiModifier.STATIC); - } - - @NotNull - private static ClassKind getClassKind(@NotNull PsiClass psiClass) { - if (psiClass.isInterface()) { - return (psiClass.isAnnotationType() ? ClassKind.ANNOTATION_CLASS : ClassKind.TRAIT); - } - if (psiClass.isEnum()) { - return ClassKind.ENUM_CLASS; - } - return ClassKind.CLASS; + private static boolean isInnerClass(@NotNull JavaClass javaClass) { + return javaClass.getOuterClass() != null && !javaClass.isStatic(); } @NotNull diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaConstructorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaConstructorResolver.java index 7f5be926aea..715a717f322 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaConstructorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaConstructorResolver.java @@ -69,7 +69,7 @@ public final class JavaConstructorResolver { @NotNull public Collection resolveConstructors(@NotNull JavaClass javaClass, @NotNull ClassDescriptor containingClass) { - PsiClass psiClass = javaClass.getPsiClass(); + PsiClass psiClass = javaClass.getPsi(); Collection constructors = Lists.newArrayList(); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java index b9ba99a520a..ae6e2bae530 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java @@ -35,6 +35,7 @@ import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmByte import org.jetbrains.jet.lang.resolve.java.kotlinSignature.AlternativeMethodSignatureData; import org.jetbrains.jet.lang.resolve.java.kotlinSignature.SignaturesPropagationData; import org.jetbrains.jet.lang.resolve.java.provider.NamedMembers; +import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod; import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScope; @@ -89,16 +90,18 @@ public final class JavaFunctionResolver { } @Nullable - SimpleFunctionDescriptor resolveFunctionMutely(@NotNull PsiMethodWrapper method, @NotNull ClassOrNamespaceDescriptor owner) { + SimpleFunctionDescriptor resolveFunctionMutely(@NotNull JavaMethod method, @NotNull ClassOrNamespaceDescriptor owner) { return resolveMethodToFunctionDescriptor(method, owner, false); } @Nullable private SimpleFunctionDescriptor resolveMethodToFunctionDescriptor( - @NotNull PsiMethodWrapper method, + @NotNull JavaMethod javaMethod, @NotNull ClassOrNamespaceDescriptor ownerDescriptor, boolean record ) { + PsiMethodWrapper method = new PsiMethodWrapper(javaMethod.getPsi()); + if (!DescriptorResolverUtils.isCorrectOwnerForEnumMember(ownerDescriptor, method.getPsiMember())) { return null; } @@ -244,7 +247,7 @@ public final class JavaFunctionResolver { Set functionsFromCurrent = Sets.newHashSet(); for (PsiMethodWrapper method : members.getMethods()) { - SimpleFunctionDescriptor function = resolveMethodToFunctionDescriptor(method, owner, true); + SimpleFunctionDescriptor function = resolveMethodToFunctionDescriptor(new JavaMethod(method.getPsiMethod()), owner, true); if (function != null) { functionsFromCurrent.add(function); ContainerUtil.addIfNotNull(functionsFromCurrent, resolveSamAdapter(function)); @@ -374,7 +377,8 @@ public final class JavaFunctionResolver { JetType transformedType = typeTransformer.transformToType(returnType, typeUsage, typeVariableResolver); if (JavaAnnotationResolver - .findAnnotationWithExternal(method.getPsiMethod(), JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().asString()) != + .findAnnotationWithExternal(method.getPsiMethod(), + JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().asString()) != null) { return TypeUtils.makeNullableAsSpecified(transformedType, false); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaNamespaceResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaNamespaceResolver.java index f29a9ee7726..5f51a1bf81a 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaNamespaceResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaNamespaceResolver.java @@ -176,7 +176,7 @@ public final class JavaNamespaceResolver { // Otherwise (if psiClass is null or doesn't have a supported Kotlin annotation), it's a Java class and the package is empty if (record) { - trace.record(BindingContext.NAMESPACE, javaPackage.getPsiPackage(), namespaceDescriptor); + trace.record(BindingContext.NAMESPACE, javaPackage.getPsi(), namespaceDescriptor); } return new JavaPackageScope(namespaceDescriptor, javaPackage, fqName, javaDescriptorResolver); @@ -190,7 +190,7 @@ public final class JavaNamespaceResolver { if (DescriptorResolverUtils.isCompiledKotlinClassOrPackageClass(javaClass)) { return null; } - PsiClass psiClass = javaClass.getPsiClass(); + PsiClass psiClass = javaClass.getPsi(); if (!hasStaticMembers(psiClass)) { return null; } @@ -258,7 +258,7 @@ public final class JavaNamespaceResolver { List result = new ArrayList(classes.size()); for (JavaClass javaClass : classes) { if (DescriptorResolverUtils.isCompiledKotlinClass(javaClass)) { - result.add(Name.identifier(javaClass.getName())); + result.add(javaClass.getName()); } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaSignatureResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaSignatureResolver.java index fb4b558124f..e8cd7fa1045 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaSignatureResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaSignatureResolver.java @@ -30,13 +30,16 @@ import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl; import org.jetbrains.jet.lang.resolve.java.JavaTypeTransformer; import org.jetbrains.jet.lang.resolve.java.TypeUsage; import org.jetbrains.jet.lang.resolve.java.TypeVariableResolver; +import org.jetbrains.jet.lang.resolve.java.structure.JavaClass; +import org.jetbrains.jet.lang.resolve.java.structure.JavaClassType; +import org.jetbrains.jet.lang.resolve.java.structure.JavaTypeParameter; import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper; -import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.Variance; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import javax.inject.Inject; +import java.util.Collection; import java.util.Collections; import java.util.List; @@ -52,14 +55,14 @@ public final class JavaSignatureResolver { public static class TypeParameterDescriptorInitialization { @NotNull private final TypeParameterDescriptorImpl descriptor; - private final PsiTypeParameter psiTypeParameter; + private final JavaTypeParameter javaTypeParameter; private TypeParameterDescriptorInitialization( @NotNull TypeParameterDescriptorImpl descriptor, - @NotNull PsiTypeParameter psiTypeParameter + @NotNull JavaTypeParameter javaTypeParameter ) { this.descriptor = descriptor; - this.psiTypeParameter = psiTypeParameter; + this.javaTypeParameter = javaTypeParameter; } @NotNull @@ -76,7 +79,7 @@ public final class JavaSignatureResolver { List result = Lists.newArrayList(); for (PsiTypeParameter typeParameter : typeParameters) { TypeParameterDescriptorInitialization typeParameterDescriptor = - makeUninitializedTypeParameter(containingDeclaration, typeParameter); + makeUninitializedTypeParameter(containingDeclaration, new JavaTypeParameter(typeParameter)); result.add(typeParameterDescriptor); } return result; @@ -85,17 +88,17 @@ public final class JavaSignatureResolver { @NotNull private static TypeParameterDescriptorInitialization makeUninitializedTypeParameter( @NotNull DeclarationDescriptor containingDeclaration, - @NotNull PsiTypeParameter psiTypeParameter + @NotNull JavaTypeParameter javaTypeParameter ) { TypeParameterDescriptorImpl typeParameterDescriptor = TypeParameterDescriptorImpl.createForFurtherModification( containingDeclaration, Collections.emptyList(), // TODO false, Variance.INVARIANT, - Name.identifier(psiTypeParameter.getName()), - psiTypeParameter.getIndex() + javaTypeParameter.getName(), + javaTypeParameter.getIndex() ); - return new TypeParameterDescriptorInitialization(typeParameterDescriptor, psiTypeParameter); + return new TypeParameterDescriptorInitialization(typeParameterDescriptor, javaTypeParameter); } private void initializeTypeParameter( @@ -103,13 +106,14 @@ public final class JavaSignatureResolver { TypeVariableResolver typeVariableByPsiResolver ) { TypeParameterDescriptorImpl typeParameterDescriptor = typeParameter.descriptor; - PsiClassType[] referencedTypes = typeParameter.psiTypeParameter.getExtendsList().getReferencedTypes(); - if (referencedTypes.length == 0) { + Collection upperBounds = typeParameter.javaTypeParameter.getUpperBounds(); + if (upperBounds.isEmpty()) { typeParameterDescriptor.addUpperBound(KotlinBuiltIns.getInstance().getNullableAnyType()); } else { - for (PsiClassType referencedType : referencedTypes) { - JetType transformedType = typeTransformer.transformToType(referencedType, TypeUsage.UPPER_BOUND, typeVariableByPsiResolver); + for (JavaClassType upperBound : upperBounds) { + PsiClassType psiClassType = upperBound.getPsi(); + JetType transformedType = typeTransformer.transformToType(psiClassType, TypeUsage.UPPER_BOUND, typeVariableByPsiResolver); typeParameterDescriptor.addUpperBound(transformedType); } } @@ -138,10 +142,10 @@ public final class JavaSignatureResolver { @NotNull public static List createUninitializedClassTypeParameters( - PsiClass psiClass, ClassDescriptor classDescriptor + JavaClass javaClass, ClassDescriptor classDescriptor ) { List result = Lists.newArrayList(); - for (PsiTypeParameter typeParameter : psiClass.getTypeParameters()) { + for (JavaTypeParameter typeParameter : javaClass.getTypeParameters()) { TypeParameterDescriptorInitialization typeParameterDescriptor = makeUninitializedTypeParameter(classDescriptor, typeParameter); result.add(typeParameterDescriptor); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaSupertypeResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaSupertypeResolver.java index 6ac3b46c5ea..a330596caaa 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaSupertypeResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaSupertypeResolver.java @@ -16,8 +16,6 @@ package org.jetbrains.jet.lang.resolve.java.resolver; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiClassType; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassKind; @@ -28,6 +26,8 @@ import org.jetbrains.jet.lang.resolve.java.JavaTypeTransformer; import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.TypeUsage; import org.jetbrains.jet.lang.resolve.java.TypeVariableResolver; +import org.jetbrains.jet.lang.resolve.java.structure.JavaClass; +import org.jetbrains.jet.lang.resolve.java.structure.JavaClassType; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetType; @@ -37,6 +37,7 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import javax.inject.Inject; 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; @@ -63,46 +64,45 @@ public final class JavaSupertypeResolver { this.classResolver = classResolver; } + @NotNull public Collection getSupertypes( @NotNull ClassDescriptor classDescriptor, - @NotNull PsiClass psiClass, + @NotNull JavaClass javaClass, @NotNull List typeParameters ) { + TypeVariableResolver typeVariableResolver = new TypeVariableResolver(typeParameters, classDescriptor, + "class " + javaClass.getFqName()); - List result = new ArrayList(); - - String context = "class " + psiClass.getQualifiedName(); - - TypeVariableResolver typeVariableResolverForSupertypes = new TypeVariableResolver(typeParameters, classDescriptor, context); - transformSupertypeList(result, psiClass.getExtendsListTypes(), typeVariableResolverForSupertypes); - transformSupertypeList(result, psiClass.getImplementsListTypes(), typeVariableResolverForSupertypes); + List result = transformSupertypeList(javaClass.getSupertypes(), typeVariableResolver); reportIncompleteHierarchyForErrorTypes(classDescriptor, result); if (result.isEmpty()) { - addBaseClass(psiClass, classDescriptor, result); + return Collections.singletonList(getDefaultSupertype(javaClass)); } + return result; } - private void addBaseClass(@NotNull PsiClass psiClass, @NotNull ClassDescriptor classDescriptor, @NotNull List result) { - if (OBJECT_FQ_NAME.asString().equals(psiClass.getQualifiedName()) || classDescriptor.getKind() == ClassKind.ANNOTATION_CLASS) { - result.add(KotlinBuiltIns.getInstance().getAnyType()); + @NotNull + private JetType getDefaultSupertype(@NotNull JavaClass javaClass) { + if (OBJECT_FQ_NAME.equals(javaClass.getFqName()) || javaClass.getKind() == ClassKind.ANNOTATION_CLASS) { + return KotlinBuiltIns.getInstance().getAnyType(); } else { ClassDescriptor object = classResolver.resolveClass(OBJECT_FQ_NAME, IGNORE_KOTLIN_SOURCES); if (object != null) { - result.add(object.getDefaultType()); + return object.getDefaultType(); } else { //TODO: hack here - result.add(KotlinBuiltIns.getInstance().getAnyType()); + return KotlinBuiltIns.getInstance().getAnyType(); // throw new IllegalStateException("Could not resolve java.lang.Object"); } } } - private void reportIncompleteHierarchyForErrorTypes(ClassDescriptor classDescriptor, List result) { + private void reportIncompleteHierarchyForErrorTypes(@NotNull ClassDescriptor classDescriptor, @NotNull List result) { for (JetType supertype : result) { if (ErrorUtils.isErrorType(supertype)) { trace.record(BindingContext.INCOMPLETE_HIERARCHY, classDescriptor); @@ -110,28 +110,27 @@ public final class JavaSupertypeResolver { } } - private void transformSupertypeList( - List result, - PsiClassType[] extendsListTypes, - TypeVariableResolver typeVariableResolver + @NotNull + private List transformSupertypeList( + @NotNull Collection supertypes, + @NotNull TypeVariableResolver typeVariableResolver ) { - for (PsiClassType type : extendsListTypes) { - PsiClass resolved = type.resolve(); + List result = new ArrayList(supertypes.size()); + for (JavaClassType type : supertypes) { + JavaClass resolved = type.resolve(); if (resolved != null) { - String qualifiedName = resolved.getQualifiedName(); - assert qualifiedName != null; - if (JvmAbi.JET_OBJECT.getFqName().equalsTo(qualifiedName)) { + FqName fqName = resolved.getFqName(); + assert fqName != null : "Unresolved supertype: " + resolved; + if (JvmAbi.JET_OBJECT.getFqName().equals(fqName)) { continue; } } - JetType transform = typeTransformer - .transformToType(type, TypeUsage.SUPERTYPE, typeVariableResolver); - if (ErrorUtils.isErrorType(transform)) { - continue; + JetType transformed = typeTransformer.transformToType(type.getPsi(), TypeUsage.SUPERTYPE, typeVariableResolver); + if (!ErrorUtils.isErrorType(transformed)) { + result.add(TypeUtils.makeNotNullable(transformed)); } - - result.add(TypeUtils.makeNotNullable(transform)); } + return result; } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java index 62e89729531..906daf394dd 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.lang.resolve.java.sam; import com.google.common.collect.Lists; +import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.util.MethodSignatureBackedByPsiMethod; import com.intellij.util.ArrayUtil; @@ -31,6 +32,10 @@ import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl; import org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils; import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode; import org.jetbrains.jet.lang.resolve.java.kotlinSignature.SignaturesUtil; +import org.jetbrains.jet.lang.resolve.java.structure.JavaClass; +import org.jetbrains.jet.lang.resolve.java.structure.JavaClassType; +import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod; +import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; @@ -316,26 +321,26 @@ public class SingleAbstractMethodUtils { } public static boolean isSamInterface(@NotNull PsiClass psiClass) { - return getSamInterfaceMethod(psiClass) != null; + return getSamInterfaceMethod(new JavaClass(psiClass), psiClass.getProject()) != null; } // Returns null if not SAM interface @Nullable - public static PsiMethod getSamInterfaceMethod(@NotNull PsiClass psiClass) { - String qualifiedName = psiClass.getQualifiedName(); - if (qualifiedName == null || qualifiedName.startsWith(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME.asString() + ".")) { + public static JavaMethod getSamInterfaceMethod(@NotNull JavaClass javaClass, @NotNull Project project) { + FqName fqName = javaClass.getFqName(); + if (fqName == null || fqName.firstSegmentIs(KotlinBuiltIns.BUILT_INS_PACKAGE_NAME)) { return null; } - if (!psiClass.isInterface() || psiClass.isAnnotationType()) { + if (!javaClass.isInterface() || javaClass.isAnnotationType()) { return null; } - return findOnlyAbstractMethod(psiClass); + return findOnlyAbstractMethod(javaClass, project); } @Nullable - private static PsiMethod findOnlyAbstractMethod(@NotNull PsiClass psiClass) { - PsiClassType classType = JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(psiClass); + private static JavaMethod findOnlyAbstractMethod(@NotNull JavaClass javaClass, @NotNull Project project) { + JavaClassType classType = new JavaClassType(JavaPsiFacade.getElementFactory(project).createType(javaClass.getPsi())); OnlyAbstractMethodFinder finder = new OnlyAbstractMethodFinder(); if (finder.find(classType)) { @@ -370,39 +375,40 @@ public class SingleAbstractMethodUtils { private static class OnlyAbstractMethodFinder { private MethodSignatureBackedByPsiMethod found; - private boolean find(@NotNull PsiClassType classType) { - PsiClassType.ClassResolveResult classResolveResult = classType.resolveGenerics(); + private boolean find(@NotNull JavaClassType classType) { + PsiClassType.ClassResolveResult classResolveResult = classType.getPsi().resolveGenerics(); PsiSubstitutor classSubstitutor = classResolveResult.getSubstitutor(); - PsiClass psiClass = classResolveResult.getElement(); - if (psiClass == null) { + JavaClass javaClass = classType.resolve(); + if (javaClass == null) { return false; // can't resolve class -> not a SAM interface } - if (CommonClassNames.JAVA_LANG_OBJECT.equals(psiClass.getQualifiedName())) { + if (new FqName(CommonClassNames.JAVA_LANG_OBJECT).equals(javaClass.getFqName())) { return true; } - for (PsiMethod method : psiClass.getMethods()) { - if (DescriptorResolverUtils.isObjectMethod(method)) { // e.g., ignore toString() declared in interface + for (JavaMethod method : javaClass.getMethods()) { + PsiMethod psiMethod = method.getPsi(); + if (DescriptorResolverUtils.isObjectMethod(psiMethod)) { // e.g., ignore toString() declared in interface continue; } - if (method.hasTypeParameters()) { + if (!method.getTypeParameters().isEmpty()) { return false; // if interface has generic methods, it is not a SAM interface } if (found == null) { - found = (MethodSignatureBackedByPsiMethod) method.getSignature(classSubstitutor); + found = (MethodSignatureBackedByPsiMethod) psiMethod.getSignature(classSubstitutor); continue; } - if (!found.getName().equals(method.getName())) { + if (!found.getName().equals(method.getName().asString())) { return false; // optimizing heuristic } - MethodSignatureBackedByPsiMethod current = (MethodSignatureBackedByPsiMethod) method.getSignature(classSubstitutor); - if (!areSignaturesErasureEqual(current, found) || isVarargMethod(method) != isVarargMethod(found.getMethod())) { + MethodSignatureBackedByPsiMethod current = (MethodSignatureBackedByPsiMethod) psiMethod.getSignature(classSubstitutor); + if (!areSignaturesErasureEqual(current, found) || isVarargMethod(psiMethod) != isVarargMethod(found.getMethod())) { return false; // different signatures } } - for (PsiType t : classType.getSuperTypes()) { - if (!find((PsiClassType) t)) { + for (JavaClassType t : classType.getSupertypes()) { + if (!find(t)) { return false; } } @@ -411,8 +417,8 @@ public class SingleAbstractMethodUtils { } @Nullable - PsiMethod getFoundMethod() { - return found == null ? null : found.getMethod(); + private JavaMethod getFoundMethod() { + return found == null ? null : new JavaMethod(found.getMethod()); } } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaClassNonStaticMembersScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaClassNonStaticMembersScope.java index 051b2850ab3..825ff0443ac 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaClassNonStaticMembersScope.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaClassNonStaticMembersScope.java @@ -43,13 +43,13 @@ public final class JavaClassNonStaticMembersScope extends JavaClassMembersScope public JavaClassNonStaticMembersScope( @NotNull ClassDescriptor descriptor, @NotNull JavaClass javaClass, - boolean staticMembersOfPsiClass, + boolean staticMembersOfClass, @NotNull JavaDescriptorResolver javaDescriptorResolver ) { - super(descriptor, MembersProvider.forClass(javaClass, staticMembersOfPsiClass), javaDescriptorResolver); + super(descriptor, MembersProvider.forClass(javaClass, staticMembersOfClass), javaDescriptorResolver); this.descriptor = descriptor; this.javaClass = javaClass; - this.staticMembersOfPsiClass = staticMembersOfPsiClass; + this.staticMembersOfPsiClass = staticMembersOfClass; } @@ -98,10 +98,10 @@ public final class JavaClassNonStaticMembersScope extends JavaClassMembersScope @NotNull private ClassDescriptor resolveInnerClass(@NotNull JavaClass innerClass) { - String name = innerClass.getFqName(); - assert name != null : "Inner class has no qualified name: " + innerClass; - ClassDescriptor classDescriptor = javaDescriptorResolver.resolveClass(new FqName(name), IGNORE_KOTLIN_SOURCES); - assert classDescriptor != null : "Couldn't resolve inner class " + name; + FqName fqName = innerClass.getFqName(); + assert fqName != null : "Inner class has no qualified name: " + innerClass; + ClassDescriptor classDescriptor = javaDescriptorResolver.resolveClass(fqName, IGNORE_KOTLIN_SOURCES); + assert classDescriptor != null : "Couldn't resolve inner class " + fqName; return classDescriptor; } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaClassStaticMembersScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaClassStaticMembersScope.java index 20fae02dc16..22a69b524b9 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaClassStaticMembersScope.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaClassStaticMembersScope.java @@ -58,7 +58,7 @@ public final class JavaClassStaticMembersScope extends JavaClassMembersScope { protected Collection computeAllDescriptors() { Collection result = super.computeAllDescriptors(); for (JavaClass nested : javaClass.getInnerClasses()) { - ContainerUtil.addIfNotNull(result, getNamespace(Name.identifier(nested.getName()))); + ContainerUtil.addIfNotNull(result, getNamespace(nested.getName())); } return result; } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaPackageScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaPackageScope.java index 5d2cb24a9bc..b36949fc1dc 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaPackageScope.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaPackageScope.java @@ -90,8 +90,7 @@ public final class JavaPackageScope extends JavaBaseScope { Collection result = Sets.newHashSet(); for (JavaPackage subPackage : javaPackage.getSubPackages()) { - FqName fqName = new FqName(subPackage.getFqName()); - NamespaceDescriptor childNs = javaDescriptorResolver.resolveNamespace(fqName, IGNORE_KOTLIN_SOURCES); + NamespaceDescriptor childNs = javaDescriptorResolver.resolveNamespace(subPackage.getFqName(), IGNORE_KOTLIN_SOURCES); if (childNs != null) { result.add(childNs); } @@ -102,13 +101,12 @@ public final class JavaPackageScope extends JavaBaseScope { if (isKotlinLightClass(javaClass)) continue; - if (!javaClass.getPsiClass().hasModifierProperty(PsiModifier.PUBLIC)) continue; + if (!javaClass.getPsi().hasModifierProperty(PsiModifier.PUBLIC)) continue; ProgressIndicatorProvider.checkCanceled(); - String qualifiedName = javaClass.getFqName(); - if (qualifiedName == null) continue; - FqName fqName = new FqName(qualifiedName); + FqName fqName = javaClass.getFqName(); + if (fqName == null) continue; ClassDescriptor classDescriptor = javaDescriptorResolver.resolveClass(fqName, IGNORE_KOTLIN_SOURCES); if (classDescriptor != null) { @@ -125,7 +123,7 @@ public final class JavaPackageScope extends JavaBaseScope { } private static boolean isKotlinLightClass(@NotNull JavaClass javaClass) { - return javaClass.getPsiClass() instanceof JetJavaMirrorMarker; + return javaClass.getPsi() instanceof JetJavaMirrorMarker; } @Override diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaClass.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaClass.java index 925bf31b41d..33bff08342a 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaClass.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaClass.java @@ -18,48 +18,49 @@ package org.jetbrains.jet.lang.resolve.java.structure; import com.intellij.psi.PsiAnnotation; import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiModifier; import com.intellij.psi.PsiModifierList; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.ClassKind; +import org.jetbrains.jet.lang.descriptors.Modality; +import org.jetbrains.jet.lang.descriptors.Visibilities; +import org.jetbrains.jet.lang.descriptors.Visibility; +import org.jetbrains.jet.lang.resolve.java.JavaVisibilities; +import org.jetbrains.jet.lang.resolve.name.FqName; +import org.jetbrains.jet.lang.resolve.name.Name; -import java.util.ArrayList; import java.util.Collection; -import java.util.List; +import java.util.Collections; -public class JavaClass { - private final PsiClass psiClass; +import static org.jetbrains.jet.lang.resolve.java.structure.JavaElementCollectionFromPsiArrayUtil.*; +public class JavaClass extends JavaElementImpl implements JavaNamedElement, JavaModifierListOwner, JavaTypeParameterListOwner { public JavaClass(@NotNull PsiClass psiClass) { - this.psiClass = psiClass; + super(psiClass); } @NotNull - public PsiClass getPsiClass() { - return psiClass; - } - - @NotNull - /* package */ static Collection javaClassesFromPsi(@NotNull PsiClass[] classes) { - List result = new ArrayList(classes.length); - for (PsiClass psiClass : classes) { - result.add(new JavaClass(psiClass)); - } - return result; + @Override + public PsiClass getPsi() { + return (PsiClass) super.getPsi(); } @NotNull public Collection getInnerClasses() { - return javaClassesFromPsi(psiClass.getInnerClasses()); + return classes(getPsi().getInnerClasses()); } @Nullable - public String getFqName() { - return psiClass.getQualifiedName(); + public FqName getFqName() { + String qualifiedName = getPsi().getQualifiedName(); + return qualifiedName == null ? null : new FqName(qualifiedName); } @Nullable public JavaAnnotation findAnnotation(@NotNull String fqName) { - PsiModifierList modifierList = psiClass.getModifierList(); + PsiModifierList modifierList = getPsi().getModifierList(); if (modifierList != null) { PsiAnnotation annotation = modifierList.findAnnotation(fqName); if (annotation != null) { @@ -70,7 +71,99 @@ public class JavaClass { } @NotNull - public String getName() { - return psiClass.getName(); + @Override + public Name getName() { + return Name.identifier(getPsi().getName()); + } + + public boolean isInterface() { + return getPsi().isInterface(); + } + + public boolean isAnnotationType() { + return getPsi().isAnnotationType(); + } + + public boolean isEnum() { + return getPsi().isEnum(); + } + + @NotNull + public ClassKind getKind() { + if (isInterface()) { + return isAnnotationType() ? ClassKind.ANNOTATION_CLASS : ClassKind.TRAIT; + } + return isEnum() ? ClassKind.ENUM_CLASS : ClassKind.CLASS; + } + + @Nullable + public JavaClass getOuterClass() { + PsiClass outer = getPsi().getContainingClass(); + return outer == null ? null : new JavaClass(outer); + } + + @NotNull + public Modality getModality() { + return isAnnotationType() ? Modality.FINAL : Modality.convertFromFlags(isAbstract() || isInterface(), !isFinal()); + } + + @Override + public boolean isAbstract() { + return getPsi().hasModifierProperty(PsiModifier.ABSTRACT); + } + + @Override + public boolean isFinal() { + return getPsi().hasModifierProperty(PsiModifier.FINAL); + } + + @Override + public boolean isStatic() { + return getPsi().hasModifierProperty(PsiModifier.STATIC); + } + + @NotNull + @Override + public Visibility getVisibility() { + if (getPsi().hasModifierProperty(PsiModifier.PUBLIC)) { + return Visibilities.PUBLIC; + } + if (getPsi().hasModifierProperty(PsiModifier.PRIVATE)) { + return Visibilities.PRIVATE; + } + if (getPsi().hasModifierProperty(PsiModifier.PROTECTED)) { + return isStatic() ? JavaVisibilities.PROTECTED_STATIC_VISIBILITY : JavaVisibilities.PROTECTED_AND_PACKAGE; + } + return JavaVisibilities.PACKAGE_VISIBILITY; + } + + @NotNull + @Override + public Collection getAnnotations() { + PsiModifierList modifierList = getPsi().getModifierList(); + if (modifierList != null) { + return annotations(modifierList.getAnnotations()); + } + return Collections.emptyList(); + } + + @NotNull + @Override + public Collection getTypeParameters() { + return typeParameters(getPsi().getTypeParameters()); + } + + @SuppressWarnings("unchecked") + @NotNull + public Collection getSupertypes() { + // TODO: getPsi().getSuperTypes() ? + Collection superClasses = classTypes(getPsi().getExtendsListTypes()); + Collection superInterfaces = classTypes(getPsi().getImplementsListTypes()); + return ContainerUtil.collect(ContainerUtil.concat(superClasses, superInterfaces).iterator()); + } + + @NotNull + public Collection getMethods() { + return methods(getPsi().getMethods()); } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaClassType.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaClassType.java new file mode 100644 index 00000000000..95077fa3794 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaClassType.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.structure; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiClassType; +import com.intellij.psi.PsiType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +public class JavaClassType { + private final PsiClassType psiClassType; + + public JavaClassType(@NotNull PsiClassType psiClassType) { + this.psiClassType = psiClassType; + } + + @NotNull + public PsiClassType getPsi() { + return psiClassType; + } + + @Nullable + public JavaClass resolve() { + PsiClass psiClass = getPsi().resolve(); + return psiClass == null ? null : new JavaClass(psiClass); + } + + @NotNull + public Collection getSupertypes() { + PsiType[] psiTypes = getPsi().getSuperTypes(); + if (psiTypes.length == 0) return Collections.emptyList(); + List result = new ArrayList(psiTypes.length); + for (PsiType psiType : psiTypes) { + if (!(psiType instanceof PsiClassType)) { + throw new IllegalStateException("Supertype should be a class: " + psiType + ", type: " + getPsi()); + } + result.add(new JavaClassType((PsiClassType) psiType)); + } + return result; + } +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaElement.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaElement.java new file mode 100644 index 00000000000..7c9eda8fa56 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaElement.java @@ -0,0 +1,25 @@ +/* + * 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.structure; + +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; + +public interface JavaElement { + @NotNull + PsiElement getPsi(); +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaElementCollectionFromPsiArrayUtil.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaElementCollectionFromPsiArrayUtil.java new file mode 100644 index 00000000000..a255a6a14ba --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaElementCollectionFromPsiArrayUtil.java @@ -0,0 +1,90 @@ +/* + * 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.structure; + +import com.intellij.psi.*; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/* package */ class JavaElementCollectionFromPsiArrayUtil { + private JavaElementCollectionFromPsiArrayUtil() { + } + + @NotNull + public static Collection classes(@NotNull PsiClass[] classes) { + if (classes.length == 0) return Collections.emptyList(); + List result = new ArrayList(classes.length); + for (PsiClass psiClass : classes) { + result.add(new JavaClass(psiClass)); + } + return result; + } + + @NotNull + public static Collection packages(@NotNull PsiPackage[] packages) { + if (packages.length == 0) return Collections.emptyList(); + List result = new ArrayList(packages.length); + for (PsiPackage psiPackage : packages) { + result.add(new JavaPackage(psiPackage)); + } + return result; + } + + @NotNull + public static Collection methods(@NotNull PsiMethod[] methods) { + if (methods.length == 0) return Collections.emptyList(); + List result = new ArrayList(methods.length); + for (PsiMethod psiMethod : methods) { + result.add(new JavaMethod(psiMethod)); + } + return result; + } + + @NotNull + public static Collection typeParameters(@NotNull PsiTypeParameter[] typeParameters) { + if (typeParameters.length == 0) return Collections.emptyList(); + List result = new ArrayList(typeParameters.length); + for (PsiTypeParameter psiTypeParameter : typeParameters) { + result.add(new JavaTypeParameter(psiTypeParameter)); + } + return result; + } + + @NotNull + public static Collection classTypes(@NotNull PsiClassType[] classTypes) { + if (classTypes.length == 0) return Collections.emptyList(); + List result = new ArrayList(classTypes.length); + for (PsiClassType psiClassType : classTypes) { + result.add(new JavaClassType(psiClassType)); + } + return result; + } + + @NotNull + public static Collection annotations(@NotNull PsiAnnotation[] annotations) { + if (annotations.length == 0) return Collections.emptyList(); + List result = new ArrayList(annotations.length); + for (PsiAnnotation psiAnnotation : annotations) { + result.add(new JavaAnnotation(psiAnnotation)); + } + return result; + } +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaElementImpl.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaElementImpl.java new file mode 100644 index 00000000000..e12a7917d81 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaElementImpl.java @@ -0,0 +1,34 @@ +/* + * 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.structure; + +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; + +public abstract class JavaElementImpl implements JavaElement { + private final PsiElement psiElement; + + protected JavaElementImpl(@NotNull PsiElement psiElement) { + this.psiElement = psiElement; + } + + @NotNull + @Override + public PsiElement getPsi() { + return psiElement; + } +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaMember.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaMember.java new file mode 100644 index 00000000000..4f7fbe50202 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaMember.java @@ -0,0 +1,25 @@ +/* + * 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.structure; + +import org.jetbrains.annotations.Nullable; + +public interface JavaMember extends JavaElement { + // TODO: NotNull ? + @Nullable + JavaClass getContainingClass(); +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaMethod.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaMethod.java new file mode 100644 index 00000000000..67aae316b01 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaMethod.java @@ -0,0 +1,59 @@ +/* + * 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.structure; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMethod; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.resolve.name.Name; + +import java.util.Collection; + +import static org.jetbrains.jet.lang.resolve.java.structure.JavaElementCollectionFromPsiArrayUtil.typeParameters; + +public class JavaMethod extends JavaElementImpl implements JavaTypeParameterListOwner, JavaNamedElement, JavaMember { + public JavaMethod(@NotNull PsiMethod psiMethod) { + super(psiMethod); + } + + @NotNull + @Override + public PsiMethod getPsi() { + return (PsiMethod) super.getPsi(); + } + + @NotNull + @Override + public Name getName() { + return Name.identifier(getPsi().getName()); + } + + // TODO: NotNull? + @Nullable + @Override + public JavaClass getContainingClass() { + PsiClass psiClass = getPsi().getContainingClass(); + return psiClass == null ? null : new JavaClass(psiClass); + } + + @NotNull + @Override + public Collection getTypeParameters() { + return typeParameters(getPsi().getTypeParameters()); + } +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaModifierListOwner.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaModifierListOwner.java new file mode 100644 index 00000000000..fa51410262a --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaModifierListOwner.java @@ -0,0 +1,36 @@ +/* + * 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.structure; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.Visibility; + +import java.util.Collection; + +public interface JavaModifierListOwner extends JavaElement { + boolean isAbstract(); + + boolean isStatic(); + + boolean isFinal(); + + @NotNull + Visibility getVisibility(); + + @NotNull + Collection getAnnotations(); +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaNamedElement.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaNamedElement.java new file mode 100644 index 00000000000..249c0233829 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaNamedElement.java @@ -0,0 +1,25 @@ +/* + * 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.structure; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.resolve.name.Name; + +public interface JavaNamedElement extends JavaElement { + @NotNull + Name getName(); +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaPackage.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaPackage.java index 51192e243a9..e522797078e 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaPackage.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaPackage.java @@ -18,50 +18,36 @@ package org.jetbrains.jet.lang.resolve.java.structure; import com.intellij.psi.PsiPackage; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.resolve.name.FqName; -import java.util.ArrayList; import java.util.Collection; -import java.util.List; -public class JavaPackage { - private final PsiPackage psiPackage; +import static org.jetbrains.jet.lang.resolve.java.structure.JavaElementCollectionFromPsiArrayUtil.classes; +import static org.jetbrains.jet.lang.resolve.java.structure.JavaElementCollectionFromPsiArrayUtil.packages; +public class JavaPackage extends JavaElementImpl { public JavaPackage(@NotNull PsiPackage psiPackage) { - this.psiPackage = psiPackage; + super(psiPackage); } @NotNull - public PsiPackage getPsiPackage() { - return psiPackage; - } - - @NotNull - private static Collection javaPackagesFromPsi(@NotNull PsiPackage[] packages) { - List result = new ArrayList(packages.length); - for (PsiPackage psiPackage : packages) { - result.add(new JavaPackage(psiPackage)); - } - return result; + @Override + public PsiPackage getPsi() { + return (PsiPackage) super.getPsi(); } @NotNull public Collection getClasses() { - return JavaClass.javaClassesFromPsi(psiPackage.getClasses()); + return classes(getPsi().getClasses()); } @NotNull public Collection getSubPackages() { - return javaPackagesFromPsi(psiPackage.getSubPackages()); + return packages(getPsi().getSubPackages()); } @NotNull - public String getFqName() { - return psiPackage.getQualifiedName(); - } - - @NotNull - public String getName() { - String name = psiPackage.getName(); - return name == null ? "" : name; + public FqName getFqName() { + return new FqName(getPsi().getQualifiedName()); } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaTypeParameter.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaTypeParameter.java new file mode 100644 index 00000000000..67129603884 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaTypeParameter.java @@ -0,0 +1,52 @@ +/* + * 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.structure; + +import com.intellij.psi.PsiTypeParameter; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.resolve.name.Name; + +import java.util.Collection; + +import static org.jetbrains.jet.lang.resolve.java.structure.JavaElementCollectionFromPsiArrayUtil.classTypes; + +public class JavaTypeParameter extends JavaElementImpl implements JavaNamedElement { + public JavaTypeParameter(@NotNull PsiTypeParameter psiTypeParameter) { + super(psiTypeParameter); + } + + @NotNull + @Override + public PsiTypeParameter getPsi() { + return (PsiTypeParameter) super.getPsi(); + } + + public int getIndex() { + return getPsi().getIndex(); + } + + @NotNull + @Override + public Name getName() { + return Name.identifier(getPsi().getName()); + } + + @NotNull + public Collection getUpperBounds() { + return classTypes(getPsi().getExtendsList().getReferencedTypes()); + } +} diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaTypeParameterListOwner.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaTypeParameterListOwner.java new file mode 100644 index 00000000000..a2d591fa36e --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaTypeParameterListOwner.java @@ -0,0 +1,26 @@ +/* + * 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.structure; + +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +public interface JavaTypeParameterListOwner extends JavaElement { + @NotNull + Collection getTypeParameters(); +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index 3592e58bb72..613430dbda0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -366,12 +366,7 @@ public class DescriptorUtils { @NotNull public static Name getClassObjectName(@NotNull Name className) { - return getClassObjectName(className.asString()); - } - - @NotNull - public static Name getClassObjectName(@NotNull String className) { - return Name.special(""); + return Name.special(""); } public static boolean isEnumClassObject(@NotNull DeclarationDescriptor descriptor) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java index 4c7ec761314..44a4e4c1823 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSession.java @@ -215,7 +215,7 @@ public class ResolveSession implements KotlinCodeAnalyzer { // build descriptors for such class objects. final JetClassLikeInfo classObjectInfo = parentClassDescriptor.getClassObjectInfo(classObject); if (classObjectInfo != null) { - final Name name = DescriptorUtils.getClassObjectName(parentClassDescriptor.getName().asString()); + final Name name = DescriptorUtils.getClassObjectName(parentClassDescriptor.getName()); return storageManager.compute(new Computable() { @Override public LazyClassDescriptor compute() {