Dropping package facades:

- light classes: do not generate light class for package facade
- drop package facades as multifile classes compilation mode support
- get rid of some additional package facade fqName usages
- update tests for light classes
This commit is contained in:
Dmitry Petrov
2015-10-15 18:13:04 +03:00
parent e7fb7483c5
commit 149e70aa07
42 changed files with 60 additions and 373 deletions
@@ -21,14 +21,7 @@ import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider
import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.psi.JetFile
public class CodegenFileClassesProvider(private val packageFacadesAsMultifileClasses: Boolean) : JvmFileClassesProvider { public class CodegenFileClassesProvider : JvmFileClassesProvider {
override public fun getFileClassInfo(file: JetFile): JvmFileClassInfo { override public fun getFileClassInfo(file: JetFile): JvmFileClassInfo =
val fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(file) JvmFileClassUtil.getFileClassInfoNoResolve(file)
if (packageFacadesAsMultifileClasses && !fileClassInfo.withJvmMultifileClass) {
return JvmFileClassUtil.getMultifilePackageFacadePartInfo(file)
}
else {
return fileClassInfo
}
}
} }
@@ -61,7 +61,7 @@ public class KotlinCodegenFacade {
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
MultiMap<FqName, JetFile> filesInPackageClasses = new MultiMap<FqName, JetFile>(); MultiMap<FqName, JetFile> filesInPackages = new MultiMap<FqName, JetFile>();
MultiMap<FqName, JetFile> filesInMultifileClasses = new MultiMap<FqName, JetFile>(); MultiMap<FqName, JetFile> filesInMultifileClasses = new MultiMap<FqName, JetFile>();
for (JetFile file : state.getFiles()) { for (JetFile file : state.getFiles()) {
@@ -72,14 +72,8 @@ public class KotlinCodegenFacade {
if (fileClassInfo.getWithJvmMultifileClass()) { if (fileClassInfo.getWithJvmMultifileClass()) {
filesInMultifileClasses.putValue(fileClassInfo.getFacadeClassFqName(), file); filesInMultifileClasses.putValue(fileClassInfo.getFacadeClassFqName(), file);
} }
if (state.getPackageFacadesAsMultifileClasses()) {
if (!fileClassInfo.getWithJvmMultifileClass()) {
filesInMultifileClasses.putValue(PackageClassUtils.getPackageClassFqName(file.getPackageFqName()), file);
}
}
else { else {
filesInPackageClasses.putValue(file.getPackageFqName(), file); filesInPackages.putValue(file.getPackageFqName(), file);
} }
} }
@@ -90,9 +84,9 @@ public class KotlinCodegenFacade {
} }
Set<FqName> packagesWithObsoleteParts = new HashSet<FqName>(state.getPackagesWithObsoleteParts()); Set<FqName> packagesWithObsoleteParts = new HashSet<FqName>(state.getPackagesWithObsoleteParts());
for (FqName packageFqName : Sets.union(packagesWithObsoleteParts, filesInPackageClasses.keySet())) { for (FqName packageFqName : Sets.union(packagesWithObsoleteParts, filesInPackages.keySet())) {
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
generatePackage(state, packageFqName, filesInPackageClasses.get(packageFqName), errorHandler); generatePackage(state, packageFqName, filesInPackages.get(packageFqName), errorHandler);
} }
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled(); ProgressIndicatorAndCompilationCanceledStatus.checkCanceled();
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl; import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl;
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl; import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation; import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor; import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils; import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
@@ -169,16 +170,16 @@ public class SamWrapperCodegen {
@NotNull @NotNull
private FqName getWrapperName(@NotNull JetFile containingFile) { private FqName getWrapperName(@NotNull JetFile containingFile) {
FqName packageClassFqName = PackageClassUtils.getPackageClassFqName(containingFile.getPackageFqName()); FqName fileClassFqName = JvmFileClassUtil.getFileClassInfoNoResolve(containingFile).getFileClassFqName();
JavaClassDescriptor descriptor = samType.getJavaClassDescriptor(); JavaClassDescriptor descriptor = samType.getJavaClassDescriptor();
int hash = PackagePartClassUtils.getPathHashCode(containingFile.getVirtualFile()) * 31 + int hash = PackagePartClassUtils.getPathHashCode(containingFile.getVirtualFile()) * 31 +
DescriptorUtils.getFqNameSafe(descriptor).hashCode(); DescriptorUtils.getFqNameSafe(descriptor).hashCode();
String shortName = String.format( String shortName = String.format(
"%s$sam$%s$%08x", "%s$sam$%s$%08x",
packageClassFqName.shortName().asString(), fileClassFqName.shortName().asString(),
descriptor.getName().asString(), descriptor.getName().asString(),
hash hash
); );
return packageClassFqName.parent().child(Name.identifier(shortName)); return fileClassFqName.parent().child(Name.identifier(shortName));
} }
} }
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.codegen.optimization.OptimizationClassBuilderFactory
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.ScriptDescriptor import org.jetbrains.kotlin.descriptors.ScriptDescriptor
import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
import org.jetbrains.kotlin.modules.TargetId import org.jetbrains.kotlin.modules.TargetId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
@@ -53,7 +52,6 @@ public class GenerationState @JvmOverloads constructor(
disableInline: Boolean = false, disableInline: Boolean = false,
disableOptimization: Boolean = false, disableOptimization: Boolean = false,
public val useTypeTableInSerializer: Boolean = false, public val useTypeTableInSerializer: Boolean = false,
public val packageFacadesAsMultifileClasses: Boolean = false,
public val diagnostics: DiagnosticSink = DiagnosticSink.DO_NOTHING, public val diagnostics: DiagnosticSink = DiagnosticSink.DO_NOTHING,
public val packagesWithObsoleteParts: Collection<FqName> = emptySet(), public val packagesWithObsoleteParts: Collection<FqName> = emptySet(),
public val obsoleteMultifileClasses: Collection<FqName> = emptySet(), public val obsoleteMultifileClasses: Collection<FqName> = emptySet(),
@@ -86,7 +84,7 @@ public class GenerationState @JvmOverloads constructor(
} }
} }
public val fileClassesProvider: CodegenFileClassesProvider = CodegenFileClassesProvider(packageFacadesAsMultifileClasses) public val fileClassesProvider: CodegenFileClassesProvider = CodegenFileClassesProvider()
private fun getIncrementalCacheForThisTarget() = private fun getIncrementalCacheForThisTarget() =
if (incrementalCompilationComponents != null && targetId != null) if (incrementalCompilationComponents != null && targetId != null)
@@ -43,7 +43,6 @@ import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor; import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor; import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor;
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageScope; import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageScope;
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider; import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackageFragmentProvider;
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache; import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache;
import org.jetbrains.kotlin.name.*; import org.jetbrains.kotlin.name.*;
@@ -148,18 +147,13 @@ public class JetTypeMapper {
@NotNull @NotNull
public Type mapOwner(@NotNull DeclarationDescriptor descriptor) { public Type mapOwner(@NotNull DeclarationDescriptor descriptor) {
return mapOwner(descriptor, false);
}
@NotNull
private Type mapOwner(@NotNull DeclarationDescriptor descriptor, boolean isImplementation) {
if (isLocalFunction(descriptor)) { if (isLocalFunction(descriptor)) {
return asmTypeForAnonymousClass(bindingContext, (FunctionDescriptor) descriptor); return asmTypeForAnonymousClass(bindingContext, (FunctionDescriptor) descriptor);
} }
DeclarationDescriptor container = descriptor.getContainingDeclaration(); DeclarationDescriptor container = descriptor.getContainingDeclaration();
if (container instanceof PackageFragmentDescriptor) { if (container instanceof PackageFragmentDescriptor) {
return Type.getObjectType(internalNameForPackageMemberOwner((CallableMemberDescriptor) descriptor, isImplementation)); return Type.getObjectType(internalNameForPackageMemberOwner((CallableMemberDescriptor) descriptor));
} }
else if (container instanceof ClassDescriptor) { else if (container instanceof ClassDescriptor) {
return mapClass((ClassDescriptor) container); return mapClass((ClassDescriptor) container);
@@ -184,7 +178,8 @@ public class JetTypeMapper {
if (isImplementation || if (isImplementation ||
descriptor instanceof PropertyDescriptor || descriptor instanceof PropertyDescriptor ||
Visibilities.isPrivate(visibility) || Visibilities.isPrivate(visibility) ||
isAccessor/*Cause of KT-9603*/) { isAccessor/*Cause of KT-9603*/
) {
return FileClasses.getFileClassInternalName(fileClassesProvider, file); return FileClasses.getFileClassInternalName(fileClassesProvider, file);
} }
else { else {
@@ -199,8 +194,8 @@ public class JetTypeMapper {
if (facadeFqName != null) return facadeFqName; if (facadeFqName != null) return facadeFqName;
} }
throw new RuntimeException("Unreachable state"); throw new RuntimeException("Could not find package member for " + descriptor +
//return PackageClassUtils.getPackageClassInternalName(packageFragment.getFqName()); " in package fragment " + descriptor.getContainingDeclaration());
} }
public static class ContainingClassesInfo { public static class ContainingClassesInfo {
@@ -268,6 +263,8 @@ public class JetTypeMapper {
return JvmClassName.byClassId(containingClasses.getFacadeClassId()).getInternalName(); return JvmClassName.byClassId(containingClasses.getFacadeClassId()).getInternalName();
} }
private static final ClassId FAKE_CLASS_ID_FOR_BUILTINS = ClassId.topLevel(new FqName("kotlin.KotlinPackage"));
@Nullable @Nullable
private ContainingClassesInfo getPackageMemberContainingClassesInfo(@NotNull DeserializedCallableMemberDescriptor descriptor) { private ContainingClassesInfo getPackageMemberContainingClassesInfo(@NotNull DeserializedCallableMemberDescriptor descriptor) {
// XXX This method is a dirty hack. // XXX This method is a dirty hack.
@@ -279,8 +276,7 @@ public class JetTypeMapper {
PackageFragmentDescriptor packageFragmentDescriptor = (PackageFragmentDescriptor) containingDeclaration; PackageFragmentDescriptor packageFragmentDescriptor = (PackageFragmentDescriptor) containingDeclaration;
if (packageFragmentDescriptor instanceof BuiltinsPackageFragment) { if (packageFragmentDescriptor instanceof BuiltinsPackageFragment) {
ClassId builtinsFacadeClassId = ClassId.topLevel(PackageClassUtils.getPackageClassFqName(packageFragmentDescriptor.getFqName())); return new ContainingClassesInfo(FAKE_CLASS_ID_FOR_BUILTINS, FAKE_CLASS_ID_FOR_BUILTINS);
return new ContainingClassesInfo(builtinsFacadeClassId, builtinsFacadeClassId);
} }
Name implClassName = JvmFileClassUtil.getImplClassName(descriptor); Name implClassName = JvmFileClassUtil.getImplClassName(descriptor);
@@ -62,9 +62,6 @@ public class K2JVMCompilerArguments extends CommonCompilerArguments {
@Argument(value = "Xno-optimize", description = "Disable optimizations") @Argument(value = "Xno-optimize", description = "Disable optimizations")
public boolean noOptimize; public boolean noOptimize;
@Argument(value = "Xmultifile-package-facades", description = "Compile package facade classes as multifile classes")
public boolean packageFacadesAsMultifileClasses;
@Argument(value = "Xreport-perf", description = "Report detailed performance statistics") @Argument(value = "Xreport-perf", description = "Report detailed performance statistics")
public boolean reportPerf; public boolean reportPerf;
@@ -272,7 +272,6 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
configuration.put(JVMConfigurationKeys.DISABLE_PARAM_ASSERTIONS, arguments.noParamAssertions) configuration.put(JVMConfigurationKeys.DISABLE_PARAM_ASSERTIONS, arguments.noParamAssertions)
configuration.put(JVMConfigurationKeys.DISABLE_INLINE, arguments.noInline) configuration.put(JVMConfigurationKeys.DISABLE_INLINE, arguments.noInline)
configuration.put(JVMConfigurationKeys.DISABLE_OPTIMIZATION, arguments.noOptimize) configuration.put(JVMConfigurationKeys.DISABLE_OPTIMIZATION, arguments.noOptimize)
configuration.put(JVMConfigurationKeys.PACKAGE_FACADES_AS_MULTIFILE_CLASSES, arguments.packageFacadesAsMultifileClasses);
} }
private fun getClasspath(paths: KotlinPaths, arguments: K2JVMCompilerArguments): List<File> { private fun getClasspath(paths: KotlinPaths, arguments: K2JVMCompilerArguments): List<File> {
@@ -142,17 +142,6 @@ public class CliLightClassGenerationSupport(project: Project) : LightClassGenera
return KotlinLightClassForExplicitDeclaration.create(psiManager, classOrObject) return KotlinLightClassForExplicitDeclaration.create(psiManager, classOrObject)
} }
override fun getPackageClasses(packageFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
val filesInPackage = findFilesForPackage(packageFqName, scope)
val filesWithCallables = PackagePartClassUtils.getFilesWithCallables(filesInPackage)
if (filesWithCallables.isEmpty()) return emptyList()
return emptyOrSingletonList<PsiClass>(
KotlinLightClassForFacade.createForPackageFacade(psiManager, packageFqName, scope, filesWithCallables)
)
}
override fun resolveClassToDescriptor(classOrObject: JetClassOrObject): ClassDescriptor? { override fun resolveClassToDescriptor(classOrObject: JetClassOrObject): ClassDescriptor? {
return bindingContext.get(BindingContext.CLASS, classOrObject) return bindingContext.get(BindingContext.CLASS, classOrObject)
} }
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.config.CompilerConfiguration; import org.jetbrains.kotlin.config.CompilerConfiguration;
import org.jetbrains.kotlin.config.ContentRootsKt; import org.jetbrains.kotlin.config.ContentRootsKt;
import org.jetbrains.kotlin.context.ModuleContext; import org.jetbrains.kotlin.context.ModuleContext;
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil;
import org.jetbrains.kotlin.idea.MainFunctionDetector; import org.jetbrains.kotlin.idea.MainFunctionDetector;
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager; import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager;
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils; import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
@@ -205,7 +206,7 @@ public class KotlinToJVMBytecodeCompiler {
return null; return null;
} }
FqName fqName = file.getPackageFqName(); FqName fqName = file.getPackageFqName();
mainClass = PackageClassUtils.getPackageClassFqName(fqName); mainClass = JvmFileClassUtil.getFileClassInfoNoResolve(file).getFacadeClassFqName();
} }
} }
return mainClass; return mainClass;
@@ -399,7 +400,6 @@ public class KotlinToJVMBytecodeCompiler {
configuration.get(JVMConfigurationKeys.DISABLE_INLINE, false), configuration.get(JVMConfigurationKeys.DISABLE_INLINE, false),
configuration.get(JVMConfigurationKeys.DISABLE_OPTIMIZATION, false), configuration.get(JVMConfigurationKeys.DISABLE_OPTIMIZATION, false),
/* useTypeTableInSerializer = */ false, /* useTypeTableInSerializer = */ false,
configuration.get(JVMConfigurationKeys.PACKAGE_FACADES_AS_MULTIFILE_CLASSES, false),
diagnosticHolder, diagnosticHolder,
packagesWithObsoleteParts, packagesWithObsoleteParts,
obsoleteMultifileClasses, obsoleteMultifileClasses,
@@ -39,8 +39,6 @@ public class JVMConfigurationKeys {
CompilerConfigurationKey.create("disable inline"); CompilerConfigurationKey.create("disable inline");
public static final CompilerConfigurationKey<Boolean> DISABLE_OPTIMIZATION = public static final CompilerConfigurationKey<Boolean> DISABLE_OPTIMIZATION =
CompilerConfigurationKey.create("disable optimization"); CompilerConfigurationKey.create("disable optimization");
public static final CompilerConfigurationKey<Boolean> PACKAGE_FACADES_AS_MULTIFILE_CLASSES =
CompilerConfigurationKey.create("compile package facades as multifile classes");
public static final CompilerConfigurationKey<IncrementalCompilationComponents> INCREMENTAL_COMPILATION_COMPONENTS = public static final CompilerConfigurationKey<IncrementalCompilationComponents> INCREMENTAL_COMPILATION_COMPONENTS =
CompilerConfigurationKey.create("incremental cache provider"); CompilerConfigurationKey.create("incremental cache provider");
@@ -93,15 +93,6 @@ public object JvmFileClassUtil {
public fun getHiddenPartFqName(file: JetFile, jvmFileClassAnnotations: ParsedJmvFileClassAnnotations): FqName = public fun getHiddenPartFqName(file: JetFile, jvmFileClassAnnotations: ParsedJmvFileClassAnnotations): FqName =
file.packageFqName.child(Name.identifier(manglePartName(jvmFileClassAnnotations.name, file.name))) file.packageFqName.child(Name.identifier(manglePartName(jvmFileClassAnnotations.name, file.name)))
@JvmStatic
public fun getMultifilePackageFacadePartInfo(file: JetFile): JvmFileClassInfo {
val packageFqName = file.packageFqName
val packageFacadeFqName = PackageClassUtils.getPackageClassFqName(packageFqName)
val filePartName = manglePartName(packageFacadeFqName.shortName().asString(), file.name)
val filePartFqName = packageFqName.child(Name.identifier(filePartName))
return JvmMultifileClassPartInfo(filePartFqName, packageFacadeFqName)
}
@JvmStatic @JvmStatic
public fun manglePartName(facadeName: String, fileName: String): String = public fun manglePartName(facadeName: String, fileName: String): String =
"${facadeName}__${PackagePartClassUtils.getFilePartShortName(fileName)}" "${facadeName}__${PackagePartClassUtils.getFilePartShortName(fileName)}"
@@ -120,10 +120,6 @@ public class JavaElementFinder extends PsiElementFinder implements KotlinFinderM
answer.addAll(lightClassGenerationSupport.getFacadeClasses(qualifiedName, scope)); answer.addAll(lightClassGenerationSupport.getFacadeClasses(qualifiedName, scope));
if (PackageClassUtils.isPackageClassFqName(qualifiedName)) {
answer.addAll(lightClassGenerationSupport.getPackageClasses(qualifiedName.parent(), scope));
}
return sortByClasspath(answer, scope).toArray(new PsiClass[answer.size()]); return sortByClasspath(answer, scope).toArray(new PsiClass[answer.size()]);
} }
@@ -171,7 +167,6 @@ public class JavaElementFinder extends PsiElementFinder implements KotlinFinderM
Collection<JetClassOrObject> declarations = lightClassGenerationSupport.findClassOrObjectDeclarationsInPackage(packageFQN, scope); Collection<JetClassOrObject> declarations = lightClassGenerationSupport.findClassOrObjectDeclarationsInPackage(packageFQN, scope);
Set<String> answer = Sets.newHashSet(); Set<String> answer = Sets.newHashSet();
answer.add(PackageClassUtils.getPackageClassName(packageFQN));
answer.addAll(lightClassGenerationSupport.getFacadeNames(packageFQN, scope)); answer.addAll(lightClassGenerationSupport.getFacadeNames(packageFQN, scope));
for (JetClassOrObject declaration : declarations) { for (JetClassOrObject declaration : declarations) {
@@ -224,7 +219,6 @@ public class JavaElementFinder extends PsiElementFinder implements KotlinFinderM
List<PsiClass> answer = new SmartList<PsiClass>(); List<PsiClass> answer = new SmartList<PsiClass>();
FqName packageFQN = new FqName(psiPackage.getQualifiedName()); FqName packageFQN = new FqName(psiPackage.getQualifiedName());
answer.addAll(lightClassGenerationSupport.getPackageClasses(packageFQN, scope));
answer.addAll(lightClassGenerationSupport.getFacadeClassesInPackage(packageFQN, scope)); answer.addAll(lightClassGenerationSupport.getFacadeClassesInPackage(packageFQN, scope));
Collection<JetClassOrObject> declarations = lightClassGenerationSupport.findClassOrObjectDeclarationsInPackage(packageFQN, scope); Collection<JetClassOrObject> declarations = lightClassGenerationSupport.findClassOrObjectDeclarationsInPackage(packageFQN, scope);
@@ -435,7 +435,6 @@ public class KotlinJavaFileStubProvider<T extends WithFileStubAndExtraDiagnostic
/*disableInline=*/false, /*disableInline=*/false,
/*disableOptimization=*/false, /*disableOptimization=*/false,
/*useTypeTableInSerializer=*/false, /*useTypeTableInSerializer=*/false,
/*packageFacadesAsMultifileClasses=*/false,
forExtraDiagnostics forExtraDiagnostics
); );
KotlinCodegenFacade.prepareForCompilation(state); KotlinCodegenFacade.prepareForCompilation(state);
@@ -30,7 +30,6 @@ import com.intellij.psi.util.PsiModificationTracker
import com.intellij.util.containers.SLRUCache import com.intellij.util.containers.SLRUCache
import org.jetbrains.annotations.NonNls import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.JetClassOrObject import org.jetbrains.kotlin.psi.JetClassOrObject
import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.psi.JetFile
@@ -237,23 +236,6 @@ public class KotlinLightClassForFacade private constructor(
} }
companion object Factory { companion object Factory {
public fun createForPackageFacade(
manager: PsiManager,
packageFqName: FqName,
searchScope: GlobalSearchScope,
files: Collection<JetFile> // this is redundant, but computing it multiple times is costly
): KotlinLightClassForFacade? {
if (files.any { LightClassUtil.belongsToKotlinBuiltIns(it) }) {
return null
}
assert(files.isNotEmpty()) { "No files for package $packageFqName" }
val packageClassFqName = PackageClassUtils.getPackageClassFqName(packageFqName)
val lightClassDataCache = PackageFacadeStubCache.getInstance(manager.project).get(packageFqName, searchScope)
return KotlinLightClassForFacade(manager, packageClassFqName, searchScope, lightClassDataCache, files, true)
}
public fun createForFacade( public fun createForFacade(
manager: PsiManager, manager: PsiManager,
facadeClassFqName: FqName, facadeClassFqName: FqName,
@@ -70,9 +70,6 @@ public abstract class LightClassGenerationSupport {
@Nullable @Nullable
public abstract PsiClass getPsiClass(@NotNull JetClassOrObject classOrObject); public abstract PsiClass getPsiClass(@NotNull JetClassOrObject classOrObject);
@NotNull
public abstract Collection<PsiClass> getPackageClasses(@NotNull FqName packageFqName, @NotNull GlobalSearchScope scope);
@Nullable @Nullable
public abstract ClassDescriptor resolveClassToDescriptor(@NotNull JetClassOrObject classOrObject); public abstract ClassDescriptor resolveClassToDescriptor(@NotNull JetClassOrObject classOrObject);
@@ -50,7 +50,6 @@ public class StubClassBuilder extends AbstractClassBuilder {
private final StubElement parent; private final StubElement parent;
private StubBuildingVisitor v; private StubBuildingVisitor v;
private final Stack<StubElement> parentStack; private final Stack<StubElement> parentStack;
private boolean isPackageClass = false;
public StubClassBuilder(@NotNull Stack<StubElement> parentStack) { public StubClassBuilder(@NotNull Stack<StubElement> parentStack) {
this.parentStack = parentStack; this.parentStack = parentStack;
@@ -79,18 +78,7 @@ public class StubClassBuilder extends AbstractClassBuilder {
super.defineClass(origin, version, access, name, signature, superName, interfaces); super.defineClass(origin, version, access, name, signature, superName, interfaces);
if (origin instanceof JetFile) { parentStack.push(v.getResult());
FqName packageName = ((JetFile) origin).getPackageFqName();
String packageClassName = PackageClassUtils.getPackageClassName(packageName);
if (name.equals(packageClassName) || name.endsWith("/" + packageClassName)) {
isPackageClass = true;
}
}
if (!isPackageClass) {
parentStack.push(v.getResult());
}
((StubBase) v.getResult()).putUserData(ClsWrapperStubPsiFactory.ORIGIN_ELEMENT, origin); ((StubBase) v.getResult()).putUserData(ClsWrapperStubPsiFactory.ORIGIN_ELEMENT, origin);
} }
@@ -149,10 +137,8 @@ public class StubClassBuilder extends AbstractClassBuilder {
@Override @Override
public void done() { public void done() {
if (!isPackageClass) { StubElement pop = parentStack.pop();
StubElement pop = parentStack.pop(); assert pop == v.getResult();
assert pop == v.getResult();
}
super.done(); super.done();
} }
} }
@@ -38,10 +38,6 @@ public class AnnotationGenTest extends CodegenTestCase {
return generateAndCreateClassLoader(); return generateAndCreateClassLoader();
} }
private Class<?> getPackageClass(@NotNull ClassLoader loader) throws ClassNotFoundException {
return loader.loadClass(PackageClassUtils.getPackageClassName(myFiles.getPsiFile().getPackageFqName()));
}
private Class<?> getPackageSrcClass(@NotNull ClassLoader loader) throws ClassNotFoundException { private Class<?> getPackageSrcClass(@NotNull ClassLoader loader) throws ClassNotFoundException {
return loader.loadClass(PackagePartClassUtils.getPackagePartInternalName(myFiles.getPsiFile())); return loader.loadClass(PackagePartClassUtils.getPackagePartInternalName(myFiles.getPsiFile()));
} }
@@ -68,7 +68,6 @@ public class CodegenTestUtil {
configuration.get(JVMConfigurationKeys.DISABLE_INLINE, false), configuration.get(JVMConfigurationKeys.DISABLE_INLINE, false),
configuration.get(JVMConfigurationKeys.DISABLE_OPTIMIZATION, false), configuration.get(JVMConfigurationKeys.DISABLE_OPTIMIZATION, false),
/* useTypeTableInSerializer = */ false, /* useTypeTableInSerializer = */ false,
configuration.get(JVMConfigurationKeys.PACKAGE_FACADES_AS_MULTIFILE_CLASSES, false),
forExtraDiagnostics forExtraDiagnostics
); );
KotlinCodegenFacade.compileCorrectFiles(state, CompilationErrorHandler.THROW_EXCEPTION); KotlinCodegenFacade.compileCorrectFiles(state, CompilationErrorHandler.THROW_EXCEPTION);
@@ -50,16 +50,8 @@ public class SyntheticMethodForAnnotatedPropertyGenTest extends CodegenTestCase
public void testTopLevel() { public void testTopLevel() {
loadFile(); loadFile();
String packageClassName = PackageClassUtils.getPackageClassName(FqName.ROOT); Class<?> a = generateClass("TopLevelKt");
for (OutputFile outputFile : generateClassesInFile().asList()) { assertAnnotatedSyntheticMethodExistence(true, a);
String filPath = outputFile.getRelativePath();
if (filPath.startsWith(packageClassName) && !filPath.equals(packageClassName + ".class")) {
// This should be package$src class
Class<?> a = generateClass(filPath.substring(0, filPath.length() - ".class".length()));
assertAnnotatedSyntheticMethodExistence(true, a);
}
}
} }
public void testInTrait() throws ClassNotFoundException { public void testInTrait() throws ClassNotFoundException {
@@ -1,68 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.name;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.junit.Test;
import static org.jetbrains.kotlin.load.kotlin.PackageClassUtils.getPackageClassName;
import static org.junit.Assert.assertEquals;
public class PackageClassNameTest {
@Test
public void testPackageName1() {
doTest("kotlin", "KotlinPackage", "_DefaultPackage");
}
@Test
public void testPackageName2() {
doTest("kotlin.io", "IoPackage", "KotlinPackage");
}
@Test
public void testPackageName3() {
doTest("kotlin.io.foo", "FooPackage", "IoPackage");
}
@Test
public void testPackageName4() {
doTest("kotlinTest.ioTest", "IoTestPackage", "KotlinTestPackage");
}
@Test
public void testPackageName5() {
doTest(FqName.ROOT, "_DefaultPackage", null);
}
@Test
public void testPackageName6() {
doTest(FqName.ROOT.child(Name.identifier("kotlin")), "KotlinPackage", "_DefaultPackage");
}
private static void doTest(@NotNull String name, @NotNull String expectedForChild, @Nullable String expectedForParent) {
doTest(new FqName(name), expectedForChild, expectedForParent);
}
private static void doTest(@NotNull FqName name, @NotNull String expectedForChild, @Nullable String expectedForParent) {
assertEquals("Wrong result for child [" + name + "].", expectedForChild, getPackageClassName(name));
if (expectedForParent != null) {
assertEquals("Wrong result for parent [" + name + "].", expectedForParent, getPackageClassName(name.parent()));
}
}
}
@@ -31,7 +31,7 @@ public final class PackageClassUtils {
// ex. <root> -> _DefaultPackage, a -> APackage, a.b -> BPackage // ex. <root> -> _DefaultPackage, a -> APackage, a.b -> BPackage
@NotNull @NotNull
public static String getPackageClassName(@NotNull FqName packageFQN) { private static String getPackageClassName(@NotNull FqName packageFQN) {
if (packageFQN.isRoot()) { if (packageFQN.isRoot()) {
return DEFAULT_PACKAGE_CLASS_NAME; return DEFAULT_PACKAGE_CLASS_NAME;
} }
@@ -133,41 +133,6 @@ public class IDELightClassGenerationSupport(private val project: Project) : Ligh
return KotlinLightClassForExplicitDeclaration.create(psiManager, classOrObject) return KotlinLightClassForExplicitDeclaration.create(psiManager, classOrObject)
} }
override fun getPackageClasses(packageFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
val filesWithCallables = PackagePartClassUtils.getFilesWithCallables(findFilesForPackage(packageFqName, scope))
val filesByModule = filesWithCallables.groupBy { it.getModuleInfo() }
return filesByModule.flatMap {
createLightClassForPackageFacade(it.value, it.key, packageFqName)
}
}
private fun createLightClassForPackageFacade(
files: List<JetFile>,
moduleInfo: IdeaModuleInfo,
packageFqName: FqName
): List<PsiClass> {
if (moduleInfo is ModuleSourceInfo) {
val lightClassForFacade = KotlinLightClassForFacade.createForPackageFacade(
psiManager, packageFqName, moduleInfo.contentScope(), files
)
return withFakeLightClasses(lightClassForFacade, files)
}
else {
val packageClassName = PackageClassUtils.getPackageClassName(packageFqName)
val virtualFileForPackageClass = files.asSequence().map {
it.virtualFile?.parent?.findChild("$packageClassName.class")
}.firstOrNull { it != null } ?: return emptyList()
val clsClassFromPackageClass = createClsJavaClassFromVirtualFile(
mirrorFile = files.first(),
classFile = virtualFileForPackageClass,
correspondingClassOrObject = null
) ?: return emptyList()
return listOf(KotlinLightClassForDecompiledDeclaration(clsClassFromPackageClass, null))
}
}
private fun withFakeLightClasses( private fun withFakeLightClasses(
lightClassForFacade: KotlinLightClassForFacade?, lightClassForFacade: KotlinLightClassForFacade?,
facadeFiles: List<JetFile> facadeFiles: List<JetFile>
@@ -240,7 +240,6 @@ public class KotlinBytecodeToolWindow extends JPanel implements Disposable {
!enableInline, !enableInline,
!enableOptimization, !enableOptimization,
/*useTypeTableInSerializer=*/false, /*useTypeTableInSerializer=*/false,
/*packageFacadesAsMultifileClasses=*/false,
sink); sink);
KotlinCodegenFacade.compileCorrectFiles(state, CompilationErrorHandler.THROW_EXCEPTION); KotlinCodegenFacade.compileCorrectFiles(state, CompilationErrorHandler.THROW_EXCEPTION);
} }
@@ -301,8 +301,7 @@ public class JetRunConfiguration extends ModuleBasedConfiguration<RunConfigurati
if (StringUtil.isEmpty(MAIN_CLASS_NAME)) { if (StringUtil.isEmpty(MAIN_CLASS_NAME)) {
return null; return null;
} }
return StringUtil.trimEnd(MAIN_CLASS_NAME, return MAIN_CLASS_NAME;
"." + PackageClassUtils.getPackageClassName(new FqName(MAIN_CLASS_NAME).parent()));
} }
@NotNull @NotNull
@@ -1,5 +0,0 @@
package test3
fun foo() {
}
@@ -1,5 +0,0 @@
package test3
fun bar() {
}
-3
View File
@@ -1,3 +0,0 @@
package test
fun foo() = 42
-3
View File
@@ -1,3 +0,0 @@
package test
fun bar() = 239 + foo()
@@ -1,11 +1,11 @@
package client; package client;
import server.ServerPackage; import server.KotlintopLevelMethodUsages_0Kt;
class JClient { class JClient {
String s = ServerPackage.processRequest(); String s = KotlintopLevelMethodUsages_0Kt.processRequest();
String sendRequest() { String sendRequest() {
return ServerPackage.processRequest(); return KotlintopLevelMethodUsages_0Kt.processRequest();
} }
} }
@@ -1,11 +0,0 @@
package client;
import server.KotlinTopLevelMethodUsages_0Kt;
class JClient {
String s = KotlinTopLevelMethodUsages_0Kt.processRequest();
String sendRequest() {
return KotlinTopLevelMethodUsages_0Kt.processRequest();
}
}
@@ -1,11 +1,11 @@
package client; package client;
import server.ServerPackage; import server.KotlinTopLevelPropertyUsages_0Kt;
class JClient { class JClient {
void fooBar() { void fooBar() {
System.out.println("foo = " + ServerPackage.getFoo()); System.out.println("foo = " + KotlinTopLevelPropertyUsages_0Kt.getFoo());
System.out.println("length: " + ServerPackage.getFoo().length()); System.out.println("length: " + KotlinTopLevelPropertyUsages_0Kt.getFoo().length());
ServerPackage.setFoo(""); KotlinTopLevelPropertyUsages_0Kt.setFoo("");
} }
} }
@@ -1,11 +0,0 @@
package client;
import server.KotlinTopLevelPropertyUsages_0Kt;
class JClient {
void fooBar() {
System.out.println("foo = " + KotlinTopLevelPropertyUsages_0Kt.getFoo());
System.out.println("length: " + KotlinTopLevelPropertyUsages_0Kt.getFoo().length());
KotlinTopLevelPropertyUsages_0Kt.setFoo("");
}
}
@@ -5,8 +5,8 @@ import foo.Obj;
class usedInJava { class usedInJava {
public static void main(String[] args) { public static void main(String[] args) {
FooPackage.getUsedByGetter(); UsedInJavaKt.getUsedByGetter();
FooPackage.setUsedBySetter(":|"); UsedInJavaKt.setUsedBySetter(":|");
System.out.println(Obj.CONST); System.out.println(Obj.CONST);
} }
} }
@@ -2,22 +2,22 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import test.TestPackage; import test.*;
class AssignMappedKotlinType { class AssignMappedKotlinType {
void test() { void test() {
int i1 = TestPackage.getInt(); int i1 = AssignMappedKotlinTypeKt.getInt();
Integer i2 = TestPackage.getInt(); Integer i2 = AssignMappedKotlinTypeKt.getInt();
Number number = TestPackage.getNumber(); Number number = AssignMappedKotlinTypeKt.getNumber();
String str = TestPackage.getString(); String str = AssignMappedKotlinTypeKt.getString();
Collection<Integer> intCollection = TestPackage.getList(); Collection<Integer> intCollection = AssignMappedKotlinTypeKt.getList();
List<Integer> intList = TestPackage.getList(); List<Integer> intList = AssignMappedKotlinTypeKt.getList();
Collection<Integer> intMutableCollection = TestPackage.getMutableList(); Collection<Integer> intMutableCollection = AssignMappedKotlinTypeKt.getMutableList();
List<Integer> intMutableList = TestPackage.getMutableList(); List<Integer> intMutableList = AssignMappedKotlinTypeKt.getMutableList();
Collection<String> stringsCollection = TestPackage.getArrayList(); Collection<String> stringsCollection = AssignMappedKotlinTypeKt.getArrayList();
ArrayList<String> arrayListCollection = TestPackage.getArrayList(); ArrayList<String> arrayListCollection = AssignMappedKotlinTypeKt.getArrayList();
} }
} }
@@ -1,6 +1,6 @@
import test.kotlin.A; import test.kotlin.A;
import static test.kotlin.KotlinPackage.foo; import static test.kotlin.JvmOverloadsFunctionsKt.foo;
class JvmOverloadsFunctions { class JvmOverloadsFunctions {
public static void main(String[] args) { public static void main(String[] args) {
@@ -1,11 +1,11 @@
package test; package test;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import test.kotlin.KotlinPackage; import test.kotlin.*;
public class TopLevelFunctionInDataFlowInspection { public class TopLevelFunctionInDataFlowInspection {
void other(@NotNull Object some) { void other(@NotNull Object some) {
Object foo = KotlinPackage.foo(some); Object foo = TopLevelFunctionInDataFlowInspectionKt.foo(some);
} }
} }
@@ -1,10 +1,10 @@
import test.TestPackage; package test;
// Check absence of 'Static method reference via subclass warning' for kotlin usages // Check absence of 'Static method reference via subclass warning' for kotlin usages
public class UsingKotlinPackageDeclarations { public class UsingKotlinPackageDeclarations {
public static int test() { public static int test() {
TestPackage.foo(); UsingKotlinPackageDeclarationsKt.foo();
TestPackage.setBar(15); UsingKotlinPackageDeclarationsKt.setBar(15);
return TestPackage.getBar(); return UsingKotlinPackageDeclarationsKt.getBar();
} }
} }
@@ -1,62 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.asJava;
import com.google.common.collect.Sets;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiFile;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.testFramework.LightProjectDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.idea.test.JetLightCodeInsightFixtureTestCase;
import org.jetbrains.kotlin.idea.test.JetLightProjectDescriptor;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.psi.JetFile;
import java.util.Set;
public class FakeLightClassForPackageTest extends JetLightCodeInsightFixtureTestCase {
private static final String TEST_DATA_PATH = "idea/testData/fakeLightClassForPackage/";
public void testMultiFile() {
myFixture.configureByFiles(TEST_DATA_PATH + "1.kt", TEST_DATA_PATH + "2.kt");
GlobalSearchScope searchScope = GlobalSearchScope.allScope(getProject());
PsiClass[] classes = JavaElementFinder.getInstance(getProject()).findClasses("test.TestPackage", searchScope);
assertEquals(3, classes.length);
assertInstanceOf(classes[0], KotlinLightClassForFacade.class);
Set<JetFile> expectedFiles = Sets.newHashSet(
LightClassGenerationSupport.getInstance(getProject()).findFilesForPackage(new FqName("test"), searchScope)
);
Set<PsiFile> actualFiles = Sets.newHashSet();
for (int i = 1; i < classes.length; i++) {
assertInstanceOf(classes[i], FakeLightClassForFileOfPackage.class);
actualFiles.add(((FakeLightClassForFileOfPackage) classes[i]).getContainingFile());
}
assertEquals(expectedFiles, actualFiles);
}
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return JetLightProjectDescriptor.INSTANCE;
}
}
@@ -31,12 +31,8 @@ class LightClassesClasspathSortingTest : KotlinCodeInsightTestCase() {
doTest("test1.A") doTest("test1.A")
} }
fun testPackageClassOneFile() { fun testFileClass() {
doTest("test2.Test2Package") doTest("test2.FileKt")
}
fun testPackageClassTwoFiles() {
doTest("test3.Test3Package")
} }
private fun doTest(fqName: String) { private fun doTest(fqName: String) {
@@ -60,10 +60,6 @@ public class NavigateToDecompiledLibraryTest extends LightCodeInsightFixtureTest
doTest(); doTest();
} }
public void testLibrariesPackage() {
doTest();
}
public void testSimpleClass() { public void testSimpleClass() {
doTest(); doTest();
} }
@@ -33,7 +33,6 @@ import com.intellij.testFramework.PsiTestUtil
import junit.framework.TestCase import junit.framework.TestCase
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils.getPackageClassFqName import org.jetbrains.kotlin.load.kotlin.PackageClassUtils.getPackageClassFqName
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils.getPackageClassName
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.test.MockLibraryUtil import org.jetbrains.kotlin.test.MockLibraryUtil
@@ -109,11 +108,11 @@ public class JetExceptionFilterTest : MultiFileTestCase() {
} }
public fun testBreakpointReachedAt() { public fun testBreakpointReachedAt() {
doTest("breakpointReachedAt.kt", 2, { getPackageClassName(FqName.ROOT) }, linePrefix = "Breakpoint reached at ") doTest("breakpointReachedAt.kt", 2, { "BreakpointReachedAtKt" }, linePrefix = "Breakpoint reached at ")
} }
public fun testSimple() { public fun testSimple() {
doTest("simple.kt", 2, { getPackageClassName(FqName.ROOT) }) doTest("simple.kt", 2, { "SimpleKt" })
} }
public fun testKt2489() { public fun testKt2489() {