Introduce 'mayHaveContract'-flag in stubs

This is needed for further commit, which supports contracts-based
smartcasts in partial body resolve mode.

NB: Stubs can be built from 3 sources:
- source code (contract presence can be checked by PSI)
- binary data (contract presence can be checked by Kotlin Metadata)
- decompiled sources

The last case is a bit of a headache, because usually bodies are omitted
in decompiled sources. To workaround it, we have to inject stubbed
contract-call in the body.
This commit is contained in:
Dmitry Savvinov
2018-07-27 11:18:13 +03:00
parent 24245c2245
commit 5ab79a111d
59 changed files with 235 additions and 127 deletions
@@ -26,6 +26,7 @@ import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt;
import org.jetbrains.kotlin.psi.stubs.KotlinFunctionStub;
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes;
import org.jetbrains.kotlin.psi.typeRefHelpers.TypeRefHelpersKt;
@@ -219,4 +220,13 @@ public class KtNamedFunction extends KtTypeParameterListOwnerStub<KotlinFunction
// Suppress Java check for out-of-block
return false;
}
public boolean mayHaveContract() {
KotlinFunctionStub stub = getStub();
if (stub != null) {
return stub.mayHaveContract();
}
return KtPsiUtilKt.isContractPresentPsiCheck(this);
}
}
@@ -69,6 +69,7 @@ interface KotlinFunctionStub : KotlinCallableStubBase<KtNamedFunction> {
fun hasBlockBody(): Boolean
fun hasBody(): Boolean
fun hasTypeParameterListBeforeFunctionName(): Boolean
fun mayHaveContract(): Boolean
}
interface KotlinImportAliasStub : StubElement<KtImportAlias> {
@@ -46,7 +46,8 @@ public class KtFunctionElementType extends KtStubElementType<KotlinFunctionStub,
boolean hasBlockBody = psi.hasBlockBody();
boolean hasBody = psi.hasBody();
return new KotlinFunctionStubImpl(parentStub, StringRef.fromString(psi.getName()), isTopLevel, fqName,
isExtension, hasBlockBody, hasBody, psi.hasTypeParameterListBeforeFunctionName());
isExtension, hasBlockBody, hasBody, psi.hasTypeParameterListBeforeFunctionName(),
psi.mayHaveContract());
}
@Override
@@ -61,6 +62,7 @@ public class KtFunctionElementType extends KtStubElementType<KotlinFunctionStub,
dataStream.writeBoolean(stub.hasBlockBody());
dataStream.writeBoolean(stub.hasBody());
dataStream.writeBoolean(stub.hasTypeParameterListBeforeFunctionName());
dataStream.writeBoolean(stub.mayHaveContract());
}
@NotNull
@@ -76,9 +78,10 @@ public class KtFunctionElementType extends KtStubElementType<KotlinFunctionStub,
boolean hasBlockBody = dataStream.readBoolean();
boolean hasBody = dataStream.readBoolean();
boolean hasTypeParameterListBeforeFunctionName = dataStream.readBoolean();
boolean mayHaveContract = dataStream.readBoolean();
return new KotlinFunctionStubImpl(parentStub, name, isTopLevel, fqName, isExtension, hasBlockBody, hasBody,
hasTypeParameterListBeforeFunctionName);
hasTypeParameterListBeforeFunctionName, mayHaveContract);
}
@Override
@@ -32,7 +32,8 @@ class KotlinFunctionStubImpl(
private val isExtension: Boolean,
private val hasBlockBody: Boolean,
private val hasBody: Boolean,
private val hasTypeParameterListBeforeFunctionName: Boolean
private val hasTypeParameterListBeforeFunctionName: Boolean,
private val mayHaveContract: Boolean
) : KotlinStubBaseImpl<KtNamedFunction>(parent, KtStubElementTypes.FUNCTION), KotlinFunctionStub {
init {
if (isTopLevel && fqName == null) {
@@ -48,4 +49,5 @@ class KotlinFunctionStubImpl(
override fun hasBlockBody() = hasBlockBody
override fun hasBody() = hasBody
override fun hasTypeParameterListBeforeFunctionName() = hasTypeParameterListBeforeFunctionName
override fun mayHaveContract(): Boolean = mayHaveContract
}