Extension callables index and its use in completion

This commit is contained in:
Valentin Kipyatkov
2015-03-30 22:45:14 +03:00
parent 546af84435
commit 5ba5618718
15 changed files with 245 additions and 75 deletions
@@ -133,7 +133,7 @@ private class CallableClsStubBuilder(
hasDelegate = false,
hasDelegateExpression = false,
hasInitializer = false,
hasReceiverTypeRef = callableProto.hasReceiverType(),
isExtension = callableProto.hasReceiverType(),
hasReturnTypeRef = true,
fqName = c.containerFqName.child(callableName),
isProbablyNothingType = isProbablyNothing(callableProto)
@@ -0,0 +1,66 @@
/*
* 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.IndexSink
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.stubs.KotlinCallableStubBase
fun indexTopLevelExtension<TDeclaration : JetCallableDeclaration>(stub: KotlinCallableStubBase<TDeclaration>, sink: IndexSink) {
if (stub.isExtension()) {
val declaration = stub.getPsi()
declaration.getReceiverTypeReference()!!.getTypeElement()?.index(declaration, sink)
}
}
private fun <TDeclaration : JetCallableDeclaration> JetTypeElement.index(declaration: TDeclaration, sink: IndexSink) {
fun occurrence(typeName: String) {
val name = declaration.getName() ?: return
sink.occurrence(JetTopLevelExtensionsByReceiverTypeIndex.INSTANCE.getKey(),
JetTopLevelExtensionsByReceiverTypeIndex.buildKey(typeName, name))
}
when (this) {
is JetUserType -> {
//TODO: aliases
var typeName = getReferencedName() ?: return
if (declaration is JetNamedFunction) {
val typeParameter = declaration.getTypeParameters().firstOrNull { it.getName() == typeName }
if (typeParameter != null) {
val bound = typeParameter.getExtendsBound()
if (bound != null) {
bound.getTypeElement()?.index(declaration, sink)
return
}
typeName = "Any"
}
}
occurrence(typeName)
}
is JetNullableType -> getInnerType()?.index(declaration, sink)
is JetFunctionType -> {
val typeName = (if (getReceiverTypeReference() != null) "ExtensionFunction" else "Function") + getParameters().size()
occurrence(typeName)
}
else -> occurrence("Any")
}
}
@@ -0,0 +1,43 @@
/*
* 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.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.stubs.StringStubIndexExtension
import com.intellij.psi.stubs.StubIndexKey
import org.jetbrains.kotlin.psi.JetCallableDeclaration
public class JetTopLevelExtensionsByReceiverTypeIndex private() : StringStubIndexExtension<JetCallableDeclaration>() {
override fun getKey() = KEY
override fun get(s: String, project: Project, scope: GlobalSearchScope)
= super.get(s, project, JetSourceFilterScope.kotlinSourcesAndLibraries(scope, project))
companion object {
private val KEY = KotlinIndexUtil.createIndexKey<String, JetCallableDeclaration>(javaClass<JetTopLevelExtensionsByReceiverTypeIndex>())
public val INSTANCE: JetTopLevelExtensionsByReceiverTypeIndex = JetTopLevelExtensionsByReceiverTypeIndex()
public fun buildKey(receiverTypeName: String, callableName: String): String = receiverTypeName + "\n" + callableName
public fun receiverTypeNameFromKey(key: String): String = key.substringBefore('\n', "")
public fun callableNameFromKey(key: String): String = key.substringAfter('\n', "")
}
}
@@ -17,10 +17,7 @@
package org.jetbrains.kotlin.idea.stubindex;
import com.intellij.psi.stubs.IndexSink;
import com.intellij.psi.stubs.StubElement;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.JetClassOrObject;
import org.jetbrains.kotlin.psi.stubs.*;
import org.jetbrains.kotlin.psi.stubs.elements.StubIndexService;
@@ -95,6 +92,7 @@ public class StubIndexServiceImpl implements StubIndexService {
if (fqName != null) {
sink.occurrence(JetTopLevelFunctionFqnNameIndex.getInstance().getKey(), fqName.asString());
sink.occurrence(JetTopLevelFunctionByPackageIndex.getInstance().getKey(), fqName.parent().asString());
StubindexPackage.indexTopLevelExtension(stub, sink);
}
}
}
@@ -116,6 +114,7 @@ public class StubIndexServiceImpl implements StubIndexService {
if (fqName != null) {
sink.occurrence(JetTopLevelPropertyFqnNameIndex.getInstance().getKey(), fqName.asString());
sink.occurrence(JetTopLevelPropertyByPackageIndex.getInstance().getKey(), fqName.parent().asString());
StubindexPackage.indexTopLevelExtension(stub, sink);
}
}
}