Generified subpackages obtaining, fixed it for mixed packages.

This commit is contained in:
Evgeny Gerashchenko
2013-11-29 20:31:09 +04:00
parent 3de7f7646b
commit df1e92959e
11 changed files with 123 additions and 38 deletions
@@ -44,7 +44,8 @@ import org.jetbrains.jet.lang.resolve.java.descriptor.JavaPackageFragmentDescrip
import org.jetbrains.jet.lang.resolve.java.mapping.KotlinToJavaTypesMap; import org.jetbrains.jet.lang.resolve.java.mapping.KotlinToJavaTypesMap;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaPackageFragmentProvider; import org.jetbrains.jet.lang.resolve.java.resolver.JavaPackageFragmentProvider;
import org.jetbrains.jet.lang.resolve.java.scope.JavaClassStaticMembersScope; import org.jetbrains.jet.lang.resolve.java.scope.JavaClassStaticMembersScope;
import org.jetbrains.jet.lang.resolve.java.scope.JavaPackageScope; import org.jetbrains.jet.lang.resolve.java.scope.JavaFullPackageScope;
import org.jetbrains.jet.lang.resolve.java.scope.JavaPurePackageScope;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe; import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.name.Name;
@@ -126,7 +127,10 @@ public class JetTypeMapper extends BindingTraceAware {
@NotNull DeclarationDescriptor descriptor, @NotNull DeclarationDescriptor descriptor,
boolean insideModule boolean insideModule
) { ) {
if (!(packageFragment instanceof JavaPackageFragmentDescriptor) || packageFragment.getMemberScope() instanceof DeserializedPackageMemberScope) { JetScope packageScope = packageFragment.getMemberScope();
if (!(packageFragment instanceof JavaPackageFragmentDescriptor)
|| packageScope instanceof DeserializedPackageMemberScope
|| packageScope instanceof JavaFullPackageScope) {
JetFile file = BindingContextUtils.getContainingFile(bindingContext, descriptor); JetFile file = BindingContextUtils.getContainingFile(bindingContext, descriptor);
if (insideModule && file != null) { if (insideModule && file != null) {
return NamespaceCodegen.getNamespacePartInternalName(file); return NamespaceCodegen.getNamespacePartInternalName(file);
@@ -136,8 +140,8 @@ public class JetTypeMapper extends BindingTraceAware {
} }
} }
if (!(packageFragment.getMemberScope() instanceof JavaClassStaticMembersScope)) { if (!(packageScope instanceof JavaClassStaticMembersScope)) {
throw new IllegalStateException("Unexpected scope: " + packageFragment.getMemberScope().getClass()); throw new IllegalStateException("Unexpected scope: " + packageScope.getClass());
} }
JavaPackageFragmentProvider javaFragmentProvider = ((JavaPackageFragmentDescriptor) packageFragment).getProvider(); JavaPackageFragmentProvider javaFragmentProvider = ((JavaPackageFragmentDescriptor) packageFragment).getProvider();
@@ -153,7 +157,7 @@ public class JetTypeMapper extends BindingTraceAware {
if (memberScope instanceof JavaClassStaticMembersScope) { if (memberScope instanceof JavaClassStaticMembersScope) {
r.append("$"); r.append("$");
} }
else if (memberScope instanceof JavaPackageScope) { else if (memberScope instanceof JavaPurePackageScope || memberScope instanceof JavaFullPackageScope) {
r.append("/"); r.append("/");
} }
else { else {
@@ -1,5 +1,6 @@
package test package test
public /*synthesized*/ fun SamInterface(/*0*/ function: () -> jet.Unit): test.SamInterface
public fun topLevelFunction(): jet.Unit public fun topLevelFunction(): jet.Unit
public open class JavaClass : java.lang.Object { public open class JavaClass : java.lang.Object {
@@ -11,6 +12,10 @@ public final class KotlinClass {
public constructor KotlinClass() public constructor KotlinClass()
} }
public trait SamInterface : java.lang.Object {
public abstract fun instanceMethod(): jet.Unit
}
package JavaClass { package JavaClass {
public open fun staticMethod(): jet.Unit public open fun staticMethod(): jet.Unit
} }
@@ -0,0 +1,5 @@
package test;
public interface SamInterface {
void instanceMethod();
}
@@ -21,9 +21,9 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.ConfigurationKind; import org.jetbrains.jet.ConfigurationKind;
import org.jetbrains.jet.analyzer.AnalyzeExhaust; import org.jetbrains.jet.analyzer.AnalyzeExhaust;
import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedClassDescriptor; import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedClassDescriptor;
import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedPackageMemberScope;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.scope.JavaFullPackageScope;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.test.TestCaseWithTmpdir; import org.jetbrains.jet.test.TestCaseWithTmpdir;
import org.jetbrains.jet.test.util.RecursiveDescriptorComparator; import org.jetbrains.jet.test.util.RecursiveDescriptorComparator;
@@ -78,11 +78,11 @@ public abstract class AbstractLoadCompiledKotlinTest extends TestCaseWithTmpdir
} }
} }
if (hasOwnMembers) { if (hasOwnMembers) {
assert scope instanceof DeserializedPackageMemberScope : "If namespace has members, members should be inside deserialized scope."; assert scope instanceof JavaFullPackageScope : "If namespace has members, members should be inside deserialized scope.";
} }
else { else {
//NOTE: should probably change //NOTE: should probably change
assert !(scope instanceof DeserializedPackageMemberScope) : "We don't use deserialized scopes for namespaces without members."; assert !(scope instanceof JavaFullPackageScope) : "We don't use deserialized scopes for namespaces without members.";
} }
} }
} }
@@ -26,8 +26,8 @@ import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.DeclarationDescriptorImpl; import org.jetbrains.jet.lang.descriptors.impl.DeclarationDescriptorImpl;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaPackageFragmentProvider; import org.jetbrains.jet.lang.resolve.java.resolver.JavaPackageFragmentProvider;
import org.jetbrains.jet.lang.resolve.java.scope.JavaPackageFragmentScope;
import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.TypeSubstitutor; import org.jetbrains.jet.lang.types.TypeSubstitutor;
import java.util.Collections; import java.util.Collections;
@@ -35,12 +35,12 @@ import java.util.Collections;
public class JavaPackageFragmentDescriptor extends DeclarationDescriptorImpl implements PackageFragmentDescriptor { public class JavaPackageFragmentDescriptor extends DeclarationDescriptorImpl implements PackageFragmentDescriptor {
private final JavaPackageFragmentProvider provider; private final JavaPackageFragmentProvider provider;
private final FqName fqName; private final FqName fqName;
private final JetScope memberScope; private final JavaPackageFragmentScope memberScope;
private JavaPackageFragmentDescriptor( private JavaPackageFragmentDescriptor(
@NotNull JavaPackageFragmentProvider provider, @NotNull JavaPackageFragmentProvider provider,
@NotNull FqName fqName, @NotNull FqName fqName,
@NotNull NullableFunction<JavaPackageFragmentDescriptor, JetScope> scopeFactory @NotNull NullableFunction<JavaPackageFragmentDescriptor, JavaPackageFragmentScope> scopeFactory
) { ) {
super(Collections.<AnnotationDescriptor>emptyList(), fqName.shortNameOrSpecial()); super(Collections.<AnnotationDescriptor>emptyList(), fqName.shortNameOrSpecial());
this.provider = provider; this.provider = provider;
@@ -52,7 +52,7 @@ public class JavaPackageFragmentDescriptor extends DeclarationDescriptorImpl imp
public static JavaPackageFragmentDescriptor create( public static JavaPackageFragmentDescriptor create(
@NotNull JavaPackageFragmentProvider provider, @NotNull JavaPackageFragmentProvider provider,
@NotNull FqName fqName, @NotNull FqName fqName,
@NotNull NullableFunction<JavaPackageFragmentDescriptor, JetScope> scopeFactory @NotNull NullableFunction<JavaPackageFragmentDescriptor, JavaPackageFragmentScope> scopeFactory
) { ) {
JavaPackageFragmentDescriptor descriptor = new JavaPackageFragmentDescriptor(provider, fqName, scopeFactory); JavaPackageFragmentDescriptor descriptor = new JavaPackageFragmentDescriptor(provider, fqName, scopeFactory);
return descriptor.memberScope == null ? null : descriptor; return descriptor.memberScope == null ? null : descriptor;
@@ -77,7 +77,7 @@ public class JavaPackageFragmentDescriptor extends DeclarationDescriptorImpl imp
@NotNull @NotNull
@Override @Override
public JetScope getMemberScope() { public JavaPackageFragmentScope getMemberScope() {
return memberScope; return memberScope;
} }
@@ -47,10 +47,8 @@ public final class DescriptorResolverUtils {
public static boolean isCompiledKotlinPackageClass(@NotNull JavaClass javaClass) { public static boolean isCompiledKotlinPackageClass(@NotNull JavaClass javaClass) {
if (javaClass.getOriginKind() == JavaClass.OriginKind.COMPILED) { if (javaClass.getOriginKind() == JavaClass.OriginKind.COMPILED) {
FqName fqName = javaClass.getFqName(); return javaClass.findAnnotation(JvmAnnotationNames.KOTLIN_PACKAGE) != null
if (fqName != null && PackageClassUtils.isPackageClassFqName(fqName)) { || javaClass.findAnnotation(JvmAnnotationNames.KOTLIN_PACKAGE_FRAGMENT) != null;
return javaClass.findAnnotation(JvmAnnotationNames.KOTLIN_PACKAGE) != null;
}
} }
return false; return false;
} }
@@ -28,7 +28,9 @@ import org.jetbrains.jet.lang.resolve.java.JavaClassFinder;
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaPackageFragmentDescriptor; import org.jetbrains.jet.lang.resolve.java.descriptor.JavaPackageFragmentDescriptor;
import org.jetbrains.jet.lang.resolve.java.scope.JavaClassStaticMembersScope; import org.jetbrains.jet.lang.resolve.java.scope.JavaClassStaticMembersScope;
import org.jetbrains.jet.lang.resolve.java.scope.JavaPackageScope; import org.jetbrains.jet.lang.resolve.java.scope.JavaFullPackageScope;
import org.jetbrains.jet.lang.resolve.java.scope.JavaPackageFragmentScope;
import org.jetbrains.jet.lang.resolve.java.scope.JavaPurePackageScope;
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass; import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
import org.jetbrains.jet.lang.resolve.java.structure.JavaPackage; import org.jetbrains.jet.lang.resolve.java.structure.JavaPackage;
import org.jetbrains.jet.lang.resolve.kotlin.DeserializedDescriptorResolver; import org.jetbrains.jet.lang.resolve.kotlin.DeserializedDescriptorResolver;
@@ -93,20 +95,12 @@ public final class JavaPackageFragmentProvider implements PackageFragmentProvide
@NotNull @NotNull
@Override @Override
public Collection<FqName> getSubPackagesOf(@NotNull FqName fqName) { public Collection<FqName> getSubPackagesOf(@NotNull FqName fqName) {
PackageFragmentDescriptor packageFragment = getOrCreatePackage(fqName); JavaPackageFragmentDescriptor packageFragment = getOrCreatePackage(fqName);
if (packageFragment == null) { if (packageFragment == null) {
return Collections.emptyList(); return Collections.emptyList();
} }
JetScope scope = packageFragment.getMemberScope(); return packageFragment.getMemberScope().getSubPackages();
// TODO 2 replace instanceof with interface
if (scope instanceof JavaPackageScope) {
return ((JavaPackageScope) scope).getSubPackages();
}
if (scope instanceof JavaClassStaticMembersScope) {
return ((JavaClassStaticMembersScope) scope).getSubPackages();
}
return Collections.emptyList();
} }
@Nullable @Nullable
@@ -115,10 +109,11 @@ public final class JavaPackageFragmentProvider implements PackageFragmentProvide
return packageFragments.get(fqName); return packageFragments.get(fqName);
} }
JavaPackageFragmentDescriptor packageFragment = JavaPackageFragmentDescriptor.create(this, fqName, new NullableFunction<JavaPackageFragmentDescriptor, JetScope>() { JavaPackageFragmentDescriptor packageFragment = JavaPackageFragmentDescriptor.create(
this, fqName, new NullableFunction<JavaPackageFragmentDescriptor, JavaPackageFragmentScope>() {
@Override @Override
@Nullable @Nullable
public JetScope fun(JavaPackageFragmentDescriptor packageFragment) { public JavaPackageFragmentScope fun(JavaPackageFragmentDescriptor packageFragment) {
return createPackageScope(fqName, packageFragment); return createPackageScope(fqName, packageFragment);
} }
}); });
@@ -128,7 +123,7 @@ public final class JavaPackageFragmentProvider implements PackageFragmentProvide
} }
@Nullable @Nullable
private JetScope createPackageScope( private JavaPackageFragmentScope createPackageScope(
@NotNull FqName fqName, @NotNull FqName fqName,
@NotNull PackageFragmentDescriptor packageFragment @NotNull PackageFragmentDescriptor packageFragment
) { ) {
@@ -142,11 +137,14 @@ public final class JavaPackageFragmentProvider implements PackageFragmentProvide
if (kotlinClass != null) { if (kotlinClass != null) {
JetScope kotlinPackageScope = deserializedDescriptorResolver.createKotlinPackageScope(packageFragment, kotlinClass); JetScope kotlinPackageScope = deserializedDescriptorResolver.createKotlinPackageScope(packageFragment, kotlinClass);
if (kotlinPackageScope != null) { if (kotlinPackageScope != null) {
return kotlinPackageScope; return new JavaFullPackageScope(packageFragment, kotlinPackageScope,
new JavaPurePackageScope(packageFragment, javaPackage, fqName, memberResolver,
/* includeCompiledKotlinClasses = */ false));
} }
} }
return new JavaPackageScope(packageFragment, javaPackage, fqName, memberResolver); return new JavaPurePackageScope(packageFragment, javaPackage, fqName, memberResolver,
/* includeCompiledKotlinClasses = */ true);
} }
JavaClass javaClass = javaClassFinder.findClass(fqName); JavaClass javaClass = javaClassFinder.findClass(fqName);
@@ -165,7 +163,7 @@ public final class JavaPackageFragmentProvider implements PackageFragmentProvide
Collection<JavaClass> classes = DescriptorResolverUtils.getClassesInPackage(javaPackage); Collection<JavaClass> classes = DescriptorResolverUtils.getClassesInPackage(javaPackage);
List<Name> result = new ArrayList<Name>(classes.size()); List<Name> result = new ArrayList<Name>(classes.size());
for (JavaClass javaClass : classes) { for (JavaClass javaClass : classes) {
if (DescriptorResolverUtils.isCompiledKotlinClass(javaClass)) { if (!DescriptorResolverUtils.isCompiledKotlinPackageClass(javaClass)) {
result.add(javaClass.getName()); result.add(javaClass.getName());
} }
} }
@@ -29,7 +29,7 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
public final class JavaClassStaticMembersScope extends JavaClassMembersScope { public final class JavaClassStaticMembersScope extends JavaClassMembersScope implements JavaPackageFragmentScope {
@NotNull @NotNull
private final JavaClass javaClass; private final JavaClass javaClass;
@@ -48,6 +48,7 @@ public final class JavaClassStaticMembersScope extends JavaClassMembersScope {
return Collections.emptyList(); return Collections.emptyList();
} }
@Override
@NotNull @NotNull
public Collection<FqName> getSubPackages() { public Collection<FqName> getSubPackages() {
List<FqName> result = Lists.newArrayList(); List<FqName> result = Lists.newArrayList();
@@ -0,0 +1,43 @@
/*
* 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.PackageFragmentDescriptor;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.scopes.ChainedScope;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import java.util.Collection;
public class JavaFullPackageScope extends ChainedScope implements JavaPackageFragmentScope {
private final JavaPurePackageScope purePackageScope;
public JavaFullPackageScope(
@NotNull PackageFragmentDescriptor packageFragment,
@NotNull JetScope kotlinPackageScope,
@NotNull JavaPurePackageScope purePackageScope
) {
super(packageFragment, kotlinPackageScope, purePackageScope);
this.purePackageScope = purePackageScope;
}
@Override
public Collection<FqName> getSubPackages() {
return purePackageScope.getSubPackages();
}
}
@@ -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.scope;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import java.util.Collection;
public interface JavaPackageFragmentScope extends JetScope {
Collection<FqName> getSubPackages();
}
@@ -31,21 +31,24 @@ import java.util.*;
import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.IGNORE_KOTLIN_SOURCES; import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.IGNORE_KOTLIN_SOURCES;
public final class JavaPackageScope extends JavaBaseScope { public final class JavaPurePackageScope extends JavaBaseScope implements JavaPackageFragmentScope {
@NotNull @NotNull
private final JavaPackage javaPackage; private final JavaPackage javaPackage;
@NotNull @NotNull
private final FqName packageFQN; private final FqName packageFQN;
private final boolean includeCompiledKotlinClasses;
public JavaPackageScope( public JavaPurePackageScope(
@NotNull PackageFragmentDescriptor descriptor, @NotNull PackageFragmentDescriptor descriptor,
@NotNull JavaPackage javaPackage, @NotNull JavaPackage javaPackage,
@NotNull FqName packageFQN, @NotNull FqName packageFQN,
@NotNull JavaMemberResolver memberResolver @NotNull JavaMemberResolver memberResolver,
boolean includeCompiledKotlinClasses
) { ) {
super(descriptor, memberResolver, MembersProvider.forPackage(javaPackage)); super(descriptor, memberResolver, MembersProvider.forPackage(javaPackage));
this.javaPackage = javaPackage; this.javaPackage = javaPackage;
this.packageFQN = packageFQN; this.packageFQN = packageFQN;
this.includeCompiledKotlinClasses = includeCompiledKotlinClasses;
} }
@Override @Override
@@ -67,6 +70,7 @@ public final class JavaPackageScope extends JavaBaseScope {
for (JavaClass javaClass : DescriptorResolverUtils.getClassesInPackage(javaPackage)) { for (JavaClass javaClass : DescriptorResolverUtils.getClassesInPackage(javaPackage)) {
if (DescriptorResolverUtils.isCompiledKotlinPackageClass(javaClass)) continue; if (DescriptorResolverUtils.isCompiledKotlinPackageClass(javaClass)) continue;
if (!includeCompiledKotlinClasses && DescriptorResolverUtils.isCompiledKotlinClass(javaClass)) continue;
if (javaClass.getOriginKind() == JavaClass.OriginKind.KOTLIN_LIGHT_CLASS) continue; if (javaClass.getOriginKind() == JavaClass.OriginKind.KOTLIN_LIGHT_CLASS) continue;
@@ -106,6 +110,7 @@ public final class JavaPackageScope extends JavaBaseScope {
return Collections.emptyList(); return Collections.emptyList();
} }
@Override
@NotNull @NotNull
public Collection<FqName> getSubPackages() { public Collection<FqName> getSubPackages() {
List<FqName> result = Lists.newArrayList(); List<FqName> result = Lists.newArrayList();