Use kotlin.Lazy for script definition computation, add test for no definition

This commit is contained in:
Alexander Udalov
2017-06-21 18:50:17 +03:00
parent 4178188e15
commit 1f34dfabd5
2 changed files with 32 additions and 15 deletions
@@ -18,6 +18,8 @@ package org.jetbrains.kotlin.psi;
import com.intellij.lang.ASTNode;
import com.intellij.psi.util.PsiTreeUtil;
import kotlin.Lazy;
import kotlin.LazyKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.psi.stubs.KotlinScriptStub;
@@ -26,21 +28,15 @@ import org.jetbrains.kotlin.script.KotlinScriptDefinition;
import org.jetbrains.kotlin.script.KotlinScriptDefinitionProviderKt;
import java.util.List;
import java.util.Objects;
import static kotlin.LazyThreadSafetyMode.PUBLICATION;
public class KtScript extends KtNamedDeclarationStub<KotlinScriptStub> implements KtDeclarationContainer {
private KotlinScriptDefinition kotlinScriptDefinitionField = null;
private boolean kotlinScriptDefinitionInitialized = false;
// make it a simple lazy value after converting to kotlin
private KotlinScriptDefinition getKotlinScriptDefinition() {
if (!kotlinScriptDefinitionInitialized) {
kotlinScriptDefinitionField = KotlinScriptDefinitionProviderKt.getScriptDefinition(getContainingKtFile());
kotlinScriptDefinitionInitialized = true;
}
assert kotlinScriptDefinitionField != null : "Should not parse a script without definition: " + getContainingKtFile().toString();
return kotlinScriptDefinitionField;
}
private final Lazy<KotlinScriptDefinition> kotlinScriptDefinition = LazyKt.lazy(PUBLICATION, () -> Objects.requireNonNull(
KotlinScriptDefinitionProviderKt.getScriptDefinition(getContainingKtFile()),
() -> "Should not parse a script without definition: " + getContainingKtFile().getVirtualFile().getPath()
));
public KtScript(@NotNull ASTNode node) {
super(node);
@@ -58,7 +54,7 @@ public class KtScript extends KtNamedDeclarationStub<KotlinScriptStub> implement
return stub.getFqName();
}
KtFile containingKtFile = getContainingKtFile();
return containingKtFile.getPackageFqName().child(getKotlinScriptDefinition().getScriptName(this));
return containingKtFile.getPackageFqName().child(kotlinScriptDefinition.getValue().getScriptName(this));
}
@Override
@@ -67,7 +63,7 @@ public class KtScript extends KtNamedDeclarationStub<KotlinScriptStub> implement
}
@NotNull
public KtBlockExpression getBlockExpression() {
private KtBlockExpression getBlockExpression() {
return findNotNullChildByClass(KtBlockExpression.class);
}
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.script.*
import org.jetbrains.kotlin.test.ConfigurationKind
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.TestJdkKind
import org.jetbrains.kotlin.util.KotlinFrontEndException
import org.jetbrains.kotlin.utils.PathUtil
import org.junit.Assert
import org.junit.Test
@@ -251,6 +252,20 @@ class ScriptTemplateTest {
Assert.assertTrue(exceptionThrown)
}
@Test
fun testScriptWithNoMatchingTemplate() {
try {
compileScript("fib.kts", ScriptWithDifferentFileNamePattern::class, null)
Assert.fail("should throw compilation error")
}
catch (e: KotlinFrontEndException) {
if (e.message?.contains("Should not parse a script without definition") != true) {
// unexpected error
throw e
}
}
}
private fun compileScript(
scriptPath: String,
scriptTemplate: KClass<out Any>,
@@ -387,6 +402,12 @@ abstract class ScriptWithoutParams(num: Int)
resolver = TestKotlinScriptDependenciesResolver::class)
abstract class ScriptBaseClassWithOverriddenProperty(override val num: Int) : TestClassWithOverridableProperty(num)
@ScriptTemplateDefinition(
scriptFilePattern = ".*\\.custom\\.kts",
resolver = TestKotlinScriptDependenciesResolver::class
)
abstract class ScriptWithDifferentFileNamePattern
@ScriptTemplateDefinition(resolver = TestKotlinScriptDependenciesResolver::class)
abstract class ScriptWithArrayParam(val myArgs: Array<String>)