diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/stubs/StubInterfaces.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/stubs/StubInterfaces.kt index ba95199fb72..4840377a248 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/stubs/StubInterfaces.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/stubs/StubInterfaces.kt @@ -26,8 +26,6 @@ import org.jetbrains.kotlin.psi.* public interface KotlinFileStub : PsiFileStub { public fun getPackageFqName(): FqName - public fun getFacadeSimpleName(): String? - public fun getPartSimpleName(): String? public fun isScript(): Boolean public fun findImportsByAlias(alias: String): List } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/stubs/elements/StubIndexService.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/stubs/elements/StubIndexService.kt index 5a536f63c45..8a85cfcfe6c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/stubs/elements/StubIndexService.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/stubs/elements/StubIndexService.kt @@ -23,6 +23,7 @@ import com.intellij.psi.stubs.StubOutputStream import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.psi.stubs.* import org.jetbrains.kotlin.psi.stubs.impl.KotlinFileStubImpl +import java.io.IOException public open class StubIndexService protected constructor() { public open fun indexFile(stub: KotlinFileStub, sink: IndexSink) { @@ -47,19 +48,17 @@ public open class StubIndexService protected constructor() { return KotlinFileStubImpl(file, file.packageFqNameByTree.asString(), file.isScriptByTree) } + throws(IOException::class) public open fun serializeFileStub(stub: KotlinFileStub, dataStream: StubOutputStream) { dataStream.writeName(stub.getPackageFqName().asString()) - dataStream.writeName(stub.getFacadeSimpleName()) - dataStream.writeName(stub.getPartSimpleName()) dataStream.writeBoolean(stub.isScript()) } + throws(IOException::class) public open fun deserializeFileStub(dataStream: StubInputStream): KotlinFileStub { val packageFqNameAsString = dataStream.readName() val isScript = dataStream.readBoolean() - val facadeSimpleName = dataStream.readName() - val partSimpleName = dataStream.readName() - return KotlinFileStubImpl(null, packageFqNameAsString!!, facadeSimpleName, partSimpleName, isScript) + return KotlinFileStubImpl(null, packageFqNameAsString!!, isScript) } companion object { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/stubs/impl/KotlinFileStubImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/psi/stubs/impl/KotlinFileStubImpl.kt index 2689db08950..58f3c9c611f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/stubs/impl/KotlinFileStubImpl.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/stubs/impl/KotlinFileStubImpl.kt @@ -30,20 +30,16 @@ import org.jetbrains.kotlin.psi.stubs.KotlinImportDirectiveStub import org.jetbrains.kotlin.psi.stubs.elements.JetStubElementTypes // SCRIPT: PsiJetFileStubImpl knows about scripting -public class KotlinFileStubImpl( +public open class KotlinFileStubImpl( jetFile: JetFile?, private val packageName: StringRef, - private val facadeSimpleName: StringRef?, - private val partSimpleName: StringRef?, private val isScript: Boolean ) : PsiFileStubImpl(jetFile), KotlinFileStub, PsiClassHolderFileStub { public constructor(jetFile: JetFile?, packageName: String, isScript: Boolean) - : this(jetFile, StringRef.fromString(packageName)!!, null, null, isScript) + : this(jetFile, StringRef.fromString(packageName)!!, isScript) override fun getPackageFqName(): FqName = FqName(StringRef.toString(packageName)!!) - override fun getFacadeSimpleName(): String? = StringRef.toString(facadeSimpleName) - override fun getPartSimpleName(): String? = StringRef.toString(partSimpleName) override fun isScript(): Boolean = isScript override fun getType(): IStubFileElementType = JetStubElementTypes.FILE @@ -57,30 +53,4 @@ public class KotlinFileStubImpl( val importList = childrenStubs.firstOrNull { it.stubType == JetStubElementTypes.IMPORT_LIST } ?: return emptyList() return importList.childrenStubs.filterIsInstance().filter { it.getAliasName() == alias } } - - companion object { - public fun forFile(packageFqName: FqName, isScript: Boolean): KotlinFileStubImpl = - KotlinFileStubImpl(jetFile = null, - packageName = StringRef.fromString(packageFqName.asString())!!, - facadeSimpleName = null, - partSimpleName = null, - isScript = isScript) - - public fun forFileFacadeStub(facadeFqName: FqName, isScript: Boolean): KotlinFileStubImpl = - KotlinFileStubImpl(jetFile = null, - packageName = facadeFqName.parent().stringRef(), - facadeSimpleName = facadeFqName.shortName().stringRef(), - partSimpleName = facadeFqName.shortName().stringRef(), - isScript = isScript) - - public fun forMultifileClassStub(facadeFqName: FqName, isScript: Boolean): KotlinFileStubImpl = - KotlinFileStubImpl(jetFile = null, - packageName = facadeFqName.parent().stringRef(), - facadeSimpleName = facadeFqName.shortName().stringRef(), - partSimpleName = null, - isScript = isScript) - - private fun FqName.stringRef() = StringRef.fromString(asString())!! - private fun Name.stringRef() = StringRef.fromString(asString())!! - } } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/clsStubBuilding.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/clsStubBuilding.kt index bf6e7398592..d66dc1edbc8 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/clsStubBuilding.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/stubBuilder/clsStubBuilding.kt @@ -20,6 +20,7 @@ import com.intellij.psi.PsiElement import com.intellij.psi.stubs.StubElement import com.intellij.util.io.StringRef import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.idea.stubindex.KotlinFileStubForIde import org.jetbrains.kotlin.lexer.JetModifierKeywordToken import org.jetbrains.kotlin.lexer.JetTokens import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader @@ -48,7 +49,7 @@ fun createPackageFacadeStub( packageFqName: FqName, c: ClsStubBuilderContext ): KotlinFileStubImpl { - val fileStub = KotlinFileStubImpl.forFile(packageFqName, packageFqName.isRoot) + val fileStub = KotlinFileStubForIde.forFile(packageFqName, packageFqName.isRoot) setupFileStub(fileStub, packageFqName) val container = ProtoContainer(null, packageFqName) for (callableProto in packageProto.getMemberList()) { @@ -63,7 +64,7 @@ fun createFileFacadeStub( c: ClsStubBuilderContext ): KotlinFileStubImpl { val packageFqName = facadeFqName.parent() - val fileStub = KotlinFileStubImpl.forFileFacadeStub(facadeFqName, packageFqName.isRoot) + val fileStub = KotlinFileStubForIde.forFileFacadeStub(facadeFqName, packageFqName.isRoot) setupFileStub(fileStub, packageFqName) val container = ProtoContainer(null, facadeFqName.parent()) for (callableProto in packageProto.getMemberList()) { @@ -78,7 +79,7 @@ fun createMultifileClassStub( components: ClsStubBuilderComponents ): KotlinFileStubImpl { val packageFqName = facadeFqName.parent() - val fileStub = KotlinFileStubImpl.forMultifileClassStub(facadeFqName, packageFqName.isRoot) + val fileStub = KotlinFileStubForIde.forMultifileClassStub(facadeFqName, packageFqName.isRoot) setupFileStub(fileStub, packageFqName) val multifileClassContainer = ProtoContainer(null, packageFqName) for (partHeader in partHeaders) { @@ -94,7 +95,7 @@ fun createMultifileClassStub( fun createIncompatibleAbiVersionFileStub() = createFileStub(FqName.ROOT) fun createFileStub(packageFqName: FqName): KotlinFileStubImpl { - val fileStub = KotlinFileStubImpl.forFile(packageFqName, packageFqName.isRoot) + val fileStub = KotlinFileStubForIde.forFile(packageFqName, packageFqName.isRoot) setupFileStub(fileStub, packageFqName) return fileStub } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/stubindex/IdeStubIndexService.java b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/stubindex/IdeStubIndexService.java index 1ea6c3fc99b..f3094cf2c7d 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/stubindex/IdeStubIndexService.java +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/stubindex/IdeStubIndexService.java @@ -17,17 +17,22 @@ package org.jetbrains.kotlin.idea.stubindex; import com.intellij.psi.stubs.IndexSink; +import com.intellij.psi.stubs.StubElement; +import com.intellij.psi.stubs.StubInputStream; +import com.intellij.psi.stubs.StubOutputStream; +import com.intellij.util.io.StringRef; +import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.fileClasses.JvmFileClassInfo; import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil; -import com.intellij.psi.stubs.StubElement; +import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils; import org.jetbrains.kotlin.name.FqName; -import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.psi.JetClassOrObject; import org.jetbrains.kotlin.psi.JetFile; import org.jetbrains.kotlin.psi.stubs.*; import org.jetbrains.kotlin.psi.stubs.elements.StubIndexService; import org.jetbrains.kotlin.util.UtilPackage; +import java.io.IOException; import java.util.List; public class IdeStubIndexService extends StubIndexService { @@ -38,16 +43,14 @@ public class IdeStubIndexService extends StubIndexService { sink.occurrence(JetExactPackagesIndex.getInstance().getKey(), packageFqName.asString()); - String facadeSimpleName = stub.getFacadeSimpleName(); - if (facadeSimpleName != null) { - FqName fileFacadeFqName = packageFqName.child(Name.identifier(facadeSimpleName)); - sink.occurrence(JetFileFacadeClassIndex.INSTANCE.getKey(), fileFacadeFqName.asString()); + FqName facadeFqName = ((KotlinFileStubForIde) stub).getFacadeFqName(); + if (facadeFqName != null) { + sink.occurrence(JetFileFacadeClassIndex.INSTANCE.getKey(), facadeFqName.asString()); } - String partSimpleName = stub.getPartSimpleName(); - if (partSimpleName != null) { - FqName filePartFqName = packageFqName.child(Name.identifier(partSimpleName)); - sink.occurrence(JetFilePartClassIndex.INSTANCE.getKey(), filePartFqName.asString()); + FqName partFqName = ((KotlinFileStubForIde) stub).getPartFqName(); + if (partFqName != null) { + sink.occurrence(JetFilePartClassIndex.INSTANCE.getKey(), partFqName.asString()); } JetFile jetFile = stub.getPsi(); @@ -169,4 +172,39 @@ public class IdeStubIndexService extends StubIndexService { } return null; } + + @NotNull + @Override + public KotlinFileStub createFileStub(@NotNull JetFile file) { + StringRef packageFqName = StringRef.fromString(file.getPackageFqNameByTree().asString()); + boolean isScript = file.isScriptByTree(); + if (PackagePartClassUtils.fileHasTopLevelCallables(file)) { + JvmFileClassInfo fileClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(file); + StringRef facadeSimpleName = StringRef.fromString(fileClassInfo.getFacadeClassFqName().shortName().asString()); + StringRef partSimpleName = StringRef.fromString(fileClassInfo.getFileClassFqName().shortName().asString()); + return new KotlinFileStubForIde(file, packageFqName, isScript, facadeSimpleName, partSimpleName); + } + return new KotlinFileStubForIde(file, packageFqName, isScript, null, null); + } + + @Override + public void serializeFileStub( + @NotNull KotlinFileStub stub, @NotNull StubOutputStream dataStream + ) throws IOException { + KotlinFileStubForIde fileStub = (KotlinFileStubForIde) stub; + dataStream.writeName(fileStub.getPackageFqName().asString()); + dataStream.writeBoolean(fileStub.isScript()); + dataStream.writeName(StringRef.toString(fileStub.getFacadeSimpleName())); + dataStream.writeName(StringRef.toString(fileStub.getPartSimpleName())); + } + + @NotNull + @Override + public KotlinFileStub deserializeFileStub(@NotNull StubInputStream dataStream) throws IOException { + StringRef packageFqNameAsString = dataStream.readName(); + boolean isScript = dataStream.readBoolean(); + StringRef facadeSimpleName = dataStream.readName(); + StringRef partSimpleName = dataStream.readName(); + return new KotlinFileStubForIde(null, packageFqNameAsString, isScript, facadeSimpleName, partSimpleName); + } } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/stubindex/KotlinFileStubForIde.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/stubindex/KotlinFileStubForIde.kt new file mode 100644 index 00000000000..f9e034ee90d --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/stubindex/KotlinFileStubForIde.kt @@ -0,0 +1,72 @@ +/* + * 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.idea.stubindex + +import com.intellij.psi.stubs.PsiClassHolderFileStub +import com.intellij.util.io.StringRef +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.JetFile +import org.jetbrains.kotlin.psi.stubs.KotlinFileStub +import org.jetbrains.kotlin.psi.stubs.impl +import org.jetbrains.kotlin.psi.stubs.impl.KotlinFileStubImpl + +public class KotlinFileStubForIde( + jetFile: JetFile?, + packageName: StringRef, + isScript: Boolean, + val facadeSimpleName: StringRef?, + val partSimpleName: StringRef? +) : KotlinFileStubImpl(jetFile, packageName, isScript), KotlinFileStub, PsiClassHolderFileStub { + + private fun StringRef.relativeToPackage() = getPackageFqName().child(Name.identifier(this.string)) + + val facadeFqName: FqName? + get() = facadeSimpleName?.relativeToPackage() + + val partFqName: FqName? + get() = partSimpleName?.relativeToPackage() + + public constructor(jetFile: JetFile?, packageName: String, isScript: Boolean) + : this(jetFile, StringRef.fromString(packageName)!!, isScript, null, null) + + companion object { + public fun forFile(packageFqName: FqName, isScript: Boolean): KotlinFileStubImpl = + KotlinFileStubForIde(jetFile = null, + packageName = StringRef.fromString(packageFqName.asString())!!, + facadeSimpleName = null, + partSimpleName = null, + isScript = isScript) + + public fun forFileFacadeStub(facadeFqName: FqName, isScript: Boolean): KotlinFileStubImpl = + KotlinFileStubForIde(jetFile = null, + packageName = facadeFqName.parent().stringRef(), + facadeSimpleName = facadeFqName.shortName().stringRef(), + partSimpleName = facadeFqName.shortName().stringRef(), + isScript = isScript) + + public fun forMultifileClassStub(facadeFqName: FqName, isScript: Boolean): KotlinFileStubImpl = + KotlinFileStubForIde(jetFile = null, + packageName = facadeFqName.parent().stringRef(), + facadeSimpleName = facadeFqName.shortName().stringRef(), + partSimpleName = null, + isScript = isScript) + + private fun FqName.stringRef() = StringRef.fromString(asString())!! + private fun Name.stringRef() = StringRef.fromString(asString())!! + } +}