diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightClassForPackage.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightClassForPackage.kt index 94b7dc58e9a..84064915408 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightClassForPackage.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightClassForPackage.kt @@ -14,439 +14,324 @@ * limitations under the License. */ -package org.jetbrains.kotlin.asJava; +package org.jetbrains.kotlin.asJava -import com.google.common.collect.Sets; -import com.intellij.openapi.components.ServiceManager; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.*; -import com.intellij.psi.impl.compiled.ClsFileImpl; -import com.intellij.psi.impl.light.LightEmptyImplementsList; -import com.intellij.psi.impl.light.LightModifierList; -import com.intellij.psi.javadoc.PsiDocComment; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.stubs.PsiClassHolderFileStub; -import com.intellij.psi.util.CachedValue; -import com.intellij.psi.util.CachedValueProvider; -import com.intellij.psi.util.CachedValuesManager; -import com.intellij.psi.util.PsiModificationTracker; -import com.intellij.util.containers.SLRUCache; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.ReadOnly; -import org.jetbrains.kotlin.idea.JetLanguage; -import org.jetbrains.kotlin.load.kotlin.PackageClassUtils; -import org.jetbrains.kotlin.name.FqName; -import org.jetbrains.kotlin.psi.JetClassOrObject; -import org.jetbrains.kotlin.psi.JetFile; +import com.google.common.collect.Sets +import com.intellij.openapi.components.ServiceManager +import com.intellij.openapi.project.Project +import com.intellij.openapi.util.Comparing +import com.intellij.psi.* +import com.intellij.psi.impl.compiled.ClsFileImpl +import com.intellij.psi.impl.light.LightEmptyImplementsList +import com.intellij.psi.impl.light.LightModifierList +import com.intellij.psi.javadoc.PsiDocComment +import com.intellij.psi.search.GlobalSearchScope +import com.intellij.psi.stubs.PsiClassHolderFileStub +import com.intellij.psi.util.CachedValue +import com.intellij.psi.util.CachedValueProvider +import com.intellij.psi.util.CachedValuesManager +import com.intellij.psi.util.PsiModificationTracker +import com.intellij.util.containers.SLRUCache +import org.jetbrains.annotations.NonNls +import org.jetbrains.kotlin.idea.JetLanguage +import org.jetbrains.kotlin.load.kotlin.PackageClassUtils +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.JetClassOrObject +import org.jetbrains.kotlin.psi.JetFile -import javax.swing.*; -import java.util.Collection; -import java.util.Collections; -import java.util.List; +import javax.swing.* -public class KotlinLightClassForPackage extends KotlinWrappingLightClass implements JetJavaMirrorMarker { +public class KotlinLightClassForPackage private(manager: PsiManager, private val packageFqName: FqName, private val searchScope: GlobalSearchScope, files: Collection) : KotlinWrappingLightClass(manager), JetJavaMirrorMarker { - public static class FileStubCache { + public class FileStubCache(private val project: Project) { - @NotNull - public static FileStubCache getInstance(@NotNull Project project) { - return ServiceManager.getService(project, FileStubCache.class); - } + private class Key private(private val fqName: FqName, private val searchScope: GlobalSearchScope) { - private static final class Key { - private final FqName fqName; - private final GlobalSearchScope searchScope; + override fun equals(o: Any?): Boolean { + if (this == o) return true + if (o == null || javaClass != o.javaClass) return false - private Key( - @NotNull FqName fqName, - @NotNull GlobalSearchScope searchScope - ) { - this.fqName = fqName; - this.searchScope = searchScope; + val key = o as Key + + if (fqName != key.fqName) return false + if (searchScope != key.searchScope) return false + + return true } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Key key = (Key) o; - - if (!fqName.equals(key.fqName)) return false; - if (!searchScope.equals(key.searchScope)) return false; - - return true; - } - - @Override - public int hashCode() { - int result = fqName.hashCode(); - result = 31 * result + searchScope.hashCode(); - return result; + override fun hashCode(): Int { + var result = fqName.hashCode() + result = 31 * result + searchScope.hashCode() + return result } } - private final class CacheData { + private inner class CacheData { - private final SLRUCache> cache = new SLRUCache>(20, 30) { - @NotNull - @Override - public CachedValue createValue(Key key) { - KotlinJavaFileStubProvider stubProvider = - KotlinJavaFileStubProvider.createForPackageClass(project, key.fqName, key.searchScope); - return CachedValuesManager.getManager(project).createCachedValue(stubProvider, /*trackValue = */false); + private val cache = object : SLRUCache>(20, 30) { + override fun createValue(key: Key): CachedValue { + val stubProvider = KotlinJavaFileStubProvider.createForPackageClass(project, key.fqName, key.searchScope) + return CachedValuesManager.getManager(project).createCachedValue(stubProvider, /*trackValue = */false) } - }; + } } - private final Project project; - private final CachedValue cachedValue; + private val cachedValue: CachedValue - public FileStubCache(@NotNull Project project) { - this.project = project; - this.cachedValue = CachedValuesManager.getManager(project).createCachedValue( - new CachedValueProvider() { - @Nullable - @Override - public Result compute() { - return Result.create(new CacheData(), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT); - } - }, - /*trackValue = */ false - ); + { + this.cachedValue = CachedValuesManager.getManager(project).createCachedValue(object : CachedValueProvider { + override fun compute(): CachedValueProvider.Result? { + return CachedValueProvider.Result.create(CacheData(), PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT) + } + }, /*trackValue = */ false) } - @NotNull - public CachedValue get( - @NotNull FqName qualifiedName, - @NotNull GlobalSearchScope searchScope - ) { + public fun get(qualifiedName: FqName, searchScope: GlobalSearchScope): CachedValue { synchronized (cachedValue) { - return cachedValue.getValue().cache.get(new Key(qualifiedName, searchScope)); + return cachedValue.getValue().cache.get(Key(qualifiedName, searchScope)) + } + } + + class object { + + public fun getInstance(project: Project): FileStubCache { + return ServiceManager.getService(project, javaClass()) } } } - private final FqName packageFqName; - private final FqName packageClassFqName; // derived from packageFqName - private final GlobalSearchScope searchScope; - private final Collection files; - private final int hashCode; - private final CachedValue lightClassDataCache; - private final PsiModifierList modifierList; - private final LightEmptyImplementsList implementsList; - private final ClsFileImpl packageClsFile; + private val packageClassFqName: FqName // derived from packageFqName + public val files: Collection + private val hashCode: Int + private val lightClassDataCache: CachedValue + private val modifierList: PsiModifierList + private val implementsList: LightEmptyImplementsList + private val packageClsFile: ClsFileImpl - private KotlinLightClassForPackage( - @NotNull PsiManager manager, - @NotNull FqName packageFqName, - @NotNull GlobalSearchScope searchScope, - @NotNull Collection files - ) { - super(manager); - this.modifierList = new LightModifierList(manager, JetLanguage.INSTANCE, PsiModifier.PUBLIC, PsiModifier.FINAL); - this.implementsList = new LightEmptyImplementsList(manager); - this.packageFqName = packageFqName; - this.packageClassFqName = PackageClassUtils.getPackageClassFqName(packageFqName); - this.searchScope = searchScope; - assert !files.isEmpty() : "No files for package " + packageFqName; - this.files = Sets.newHashSet(files); // needed for hashCode - this.hashCode = computeHashCode(); - this.lightClassDataCache = FileStubCache.getInstance(getProject()).get(packageFqName, searchScope); + { + this.modifierList = LightModifierList(manager, JetLanguage.INSTANCE, PsiModifier.PUBLIC, PsiModifier.FINAL) + this.implementsList = LightEmptyImplementsList(manager) + this.packageClassFqName = PackageClassUtils.getPackageClassFqName(packageFqName) + assert(!files.isEmpty()) { "No files for package " + packageFqName } + this.files = Sets.newHashSet(files) // needed for hashCode + this.hashCode = computeHashCode() + this.lightClassDataCache = FileStubCache.getInstance(getProject()).get(packageFqName, searchScope) - VirtualFile virtualFile = KotlinJavaFileStubProvider.getRepresentativeVirtualFile(files); - packageClsFile = new ClsFileImpl(new ClassFileViewProvider(PsiManager.getInstance(getProject()), virtualFile)) { - @NotNull - @Override - public PsiClassHolderFileStub getStub() { - return ((ClsFileImpl) getDelegate().getContainingFile()).getStub(); + val virtualFile = KotlinJavaFileStubProvider.getRepresentativeVirtualFile(files) + packageClsFile = object : ClsFileImpl(ClassFileViewProvider(PsiManager.getInstance(getProject()), virtualFile)) { + override fun getStub(): PsiClassHolderFileStub { + return (getDelegate().getContainingFile() as ClsFileImpl).getStub() } - @NotNull - @Override - public String getPackageName() { - return KotlinLightClassForPackage.this.packageFqName.asString(); + override fun getPackageName(): String { + return this@KotlinLightClassForPackage.packageFqName.asString() } - }; - packageClsFile.setPhysical(false); - } - - @Nullable - public static KotlinLightClassForPackage create( - @NotNull PsiManager manager, - @NotNull FqName qualifiedName, - @NotNull GlobalSearchScope searchScope, - @NotNull Collection files // this is redundant, but computing it multiple times is costly - ) { - for (JetFile file : files) { - if (LightClassUtil.belongsToKotlinBuiltIns(file)) return null; } - return new KotlinLightClassForPackage(manager, qualifiedName, searchScope, files); + packageClsFile.setPhysical(false) } - private static boolean allValid(Collection files) { - for (JetFile file : files) { - if (!file.isValid()) return false; - } - return true; + override fun getOrigin(): JetClassOrObject? { + return null } - @Nullable - @Override - public JetClassOrObject getOrigin() { - return null; + override fun getModifierList(): PsiModifierList? { + return modifierList } - @Nullable - @Override - public PsiModifierList getModifierList() { - return modifierList; + override fun hasModifierProperty(NonNls name: String): Boolean { + return modifierList.hasModifierProperty(name) } - @Override - public boolean hasModifierProperty(@NonNls @NotNull String name) { - return modifierList.hasModifierProperty(name); + override fun isDeprecated(): Boolean { + return false } - @Override - public boolean isDeprecated() { - return false; + override fun isInterface(): Boolean { + return false } - @Override - public boolean isInterface() { - return false; + override fun isAnnotationType(): Boolean { + return false } - @Override - public boolean isAnnotationType() { - return false; + override fun isEnum(): Boolean { + return false } - @Override - public boolean isEnum() { - return false; + override fun getContainingClass(): PsiClass? { + return null } - @Nullable - @Override - public PsiClass getContainingClass() { - return null; + override fun getContainingFile(): PsiFile { + return packageClsFile } - @Override - public PsiFile getContainingFile() { - return packageClsFile; + override fun hasTypeParameters(): Boolean { + return false } - @Override - public boolean hasTypeParameters() { - return false; + override fun getTypeParameters(): Array { + return PsiTypeParameter.EMPTY_ARRAY } - @NotNull - @Override - public PsiTypeParameter[] getTypeParameters() { - return PsiTypeParameter.EMPTY_ARRAY; + override fun getTypeParameterList(): PsiTypeParameterList? { + return null } - @Nullable - @Override - public PsiTypeParameterList getTypeParameterList() { - return null; + override fun getDocComment(): PsiDocComment? { + return null } - @Nullable - @Override - public PsiDocComment getDocComment() { - return null; + override fun getImplementsList(): PsiReferenceList? { + return implementsList } - @Nullable - @Override - public PsiReferenceList getImplementsList() { - return implementsList; + override fun getImplementsListTypes(): Array { + return PsiClassType.EMPTY_ARRAY } - @NotNull - @Override - public PsiClassType[] getImplementsListTypes() { - return PsiClassType.EMPTY_ARRAY; - } - - @Nullable - @Override - public PsiReferenceList getExtendsList() { + override fun getExtendsList(): PsiReferenceList? { // TODO: Find a way to return just Object - return super.getExtendsList(); + return super.getExtendsList() } - @NotNull - @Override - public PsiClassType[] getExtendsListTypes() { + override fun getExtendsListTypes(): Array { // TODO see getExtendsList() - return super.getExtendsListTypes(); + return super.getExtendsListTypes() } - @Nullable - @Override - public PsiClass getSuperClass() { + override fun getSuperClass(): PsiClass? { // TODO see getExtendsList() - return super.getSuperClass(); + return super.getSuperClass() } - @NotNull - @Override - public PsiClass[] getSupers() { + override fun getSupers(): Array { // TODO see getExtendsList() - return super.getSupers(); + return super.getSupers() } - @NotNull - @Override - public PsiClassType[] getSuperTypes() { + override fun getSuperTypes(): Array { // TODO see getExtendsList() - return super.getSuperTypes(); + return super.getSuperTypes() } - @Override - public PsiClass[] getInterfaces() { - return PsiClass.EMPTY_ARRAY; + override fun getInterfaces(): Array { + return PsiClass.EMPTY_ARRAY } - @NotNull - @Override - public PsiClass[] getInnerClasses() { - return PsiClass.EMPTY_ARRAY; + override fun getInnerClasses(): Array { + return PsiClass.EMPTY_ARRAY } - @NotNull - @Override - public List getOwnInnerClasses() { - return Collections.emptyList(); + override fun getOwnInnerClasses(): List { + return listOf() } - @NotNull - @Override - public PsiClass[] getAllInnerClasses() { - return PsiClass.EMPTY_ARRAY; + override fun getAllInnerClasses(): Array { + return PsiClass.EMPTY_ARRAY } - @NotNull - @Override - public PsiClassInitializer[] getInitializers() { - return PsiClassInitializer.EMPTY_ARRAY; + override fun getInitializers(): Array { + return PsiClassInitializer.EMPTY_ARRAY } - @Nullable - @Override - public PsiClass findInnerClassByName(@NonNls String name, boolean checkBases) { - return null; + override fun findInnerClassByName(NonNls name: String, checkBases: Boolean): PsiClass? { + return null } - @NotNull - @Override - public FqName getFqName() { - return packageClassFqName; + override fun getFqName(): FqName { + return packageClassFqName } - @Nullable - @Override - public String getName() { - return packageClassFqName.shortName().asString(); + override fun getName(): String? { + return packageClassFqName.shortName().asString() } - @Nullable - @Override - public String getQualifiedName() { - return packageClassFqName.asString(); + override fun getQualifiedName(): String? { + return packageClassFqName.asString() } - @Override - public boolean isValid() { - return allValid(files); + override fun isValid(): Boolean { + return allValid(files) } - @NotNull - @Override - public PsiElement copy() { - return new KotlinLightClassForPackage(getManager(), packageFqName, searchScope, files); + override fun copy(): PsiElement { + return KotlinLightClassForPackage(getManager(), packageFqName, searchScope, files) } - @NotNull - @Override - public PsiClass getDelegate() { - PsiClass psiClass = LightClassUtil.findClass(packageClassFqName, lightClassDataCache.getValue().getJavaFileStub()); + override fun getDelegate(): PsiClass { + val psiClass = LightClassUtil.findClass(packageClassFqName, lightClassDataCache.getValue().javaFileStub) if (psiClass == null) { - throw new IllegalStateException("Package class was not found " + packageFqName); + throw IllegalStateException("Package class was not found " + packageFqName) } - return psiClass; + return psiClass } - @NotNull - @Override - public PsiElement getNavigationElement() { - return files.iterator().next(); + override fun getNavigationElement(): PsiElement { + return files.iterator().next() } - @Override - public boolean isEquivalentTo(PsiElement another) { - return another instanceof PsiClass && Comparing.equal(((PsiClass) another).getQualifiedName(), getQualifiedName()); + override fun isEquivalentTo(another: PsiElement?): Boolean { + return another is PsiClass && Comparing.equal((another as PsiClass).getQualifiedName(), getQualifiedName()) } - @Override - public Icon getElementIcon(int flags) { - throw new UnsupportedOperationException("This should be done byt JetIconProvider"); + override fun getElementIcon(flags: Int): Icon? { + throw UnsupportedOperationException("This should be done byt JetIconProvider") } - @Override - public int hashCode() { - return hashCode; + override fun hashCode(): Int { + return hashCode } - private int computeHashCode() { - int result = getManager().hashCode(); - result = 31 * result + files.hashCode(); - result = 31 * result + packageFqName.hashCode(); - return result; + private fun computeHashCode(): Int { + var result = getManager().hashCode() + result = 31 * result + files.hashCode() + result = 31 * result + packageFqName.hashCode() + return result } - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null || getClass() != obj.getClass()) { - return false; + override fun equals(obj: Any?): Boolean { + if (this == obj) return true + if (obj == null || javaClass != obj.javaClass) { + return false } - KotlinLightClassForPackage lightClass = (KotlinLightClassForPackage) obj; + val lightClass = obj as KotlinLightClassForPackage - if (this.hashCode != lightClass.hashCode) return false; - if (getManager() != lightClass.getManager()) return false; - if (!files.equals(lightClass.files)) return false; - if (!packageFqName.equals(lightClass.packageFqName)) return false; + if (this.hashCode != lightClass.hashCode) return false + if (getManager() != lightClass.getManager()) return false + if (files != lightClass.files) return false + if (packageFqName != lightClass.packageFqName) return false - return true; + return true } - @Override - public String toString() { + override fun toString(): String { try { - return KotlinLightClassForPackage.class.getSimpleName() + ":" + getQualifiedName(); + return javaClass().getSimpleName() + ":" + getQualifiedName() } - catch (Throwable e) { - return KotlinLightClassForPackage.class.getSimpleName() + ":" + e.toString(); + catch (e: Throwable) { + return javaClass().getSimpleName() + ":" + e.toString() } + } - //NOTE: this is only needed to compute plugin module info - @NotNull - @ReadOnly - public final Collection getFiles() { - return files; + class object { + + public fun create(manager: PsiManager, qualifiedName: FqName, searchScope: GlobalSearchScope, files: Collection // this is redundant, but computing it multiple times is costly + ): KotlinLightClassForPackage? { + for (file in files) { + if (LightClassUtil.belongsToKotlinBuiltIns(file)) return null + } + return KotlinLightClassForPackage(manager, qualifiedName, searchScope, files) + } + + private fun allValid(files: Collection): Boolean { + for (file in files) { + if (!file.isValid()) return false + } + return true + } } -} +}//NOTE: this is only needed to compute plugin module info