Get platform for scripts from script definition

Introduce 'platform' property in KotlinScripDefinition (should have a value which exists in TargetPlatform.ALL_KINDS)

^KT-27684 Fixed
This commit is contained in:
Natalia Selezneva
2018-12-21 16:37:13 +03:00
parent 0188cd5330
commit f3c828a17d
8 changed files with 122 additions and 0 deletions
@@ -48,6 +48,10 @@ open class KotlinScriptDefinition(open val template: KClass<out Any>) : UserData
open val fileExtension: String
get() = "kts"
// Target platform for script, ex. "JVM", "JS", "NATIVE"
open val platform: String
get() = "JVM"
open val dependencyResolver: DependenciesResolver get() = DependenciesResolver.NoDependencies
open val acceptedAnnotations: List<KClass<out Annotation>> get() = emptyList()
@@ -21,6 +21,7 @@ import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.fileTypes.FileTypeRegistry
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiManager
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.psi.KtFile
@@ -38,6 +39,11 @@ interface ScriptDefinitionProvider {
}
}
fun findScriptDefinition(psiFile: PsiFile): KotlinScriptDefinition? {
val virtualFile = psiFile.virtualFile ?: psiFile.originalFile.virtualFile ?: return null
return findScriptDefinition(virtualFile, psiFile.project)
}
fun findScriptDefinition(file: VirtualFile, project: Project): KotlinScriptDefinition? {
if (file.isDirectory ||
file.extension == KotlinFileType.EXTENSION ||
@@ -24,11 +24,16 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.platform.DefaultIdeTargetPlatformKindProvider;
import org.jetbrains.kotlin.platform.IdePlatform;
import org.jetbrains.kotlin.platform.IdePlatformKind;
import org.jetbrains.kotlin.psi.KtCodeFragment;
import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.psi.KtPsiFactoryKt;
import org.jetbrains.kotlin.resolve.TargetPlatform;
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform;
import org.jetbrains.kotlin.script.KotlinScriptDefinition;
import static org.jetbrains.kotlin.script.KotlinScriptDefinitionProviderKt.findScriptDefinition;
public class TargetPlatformDetector {
public static final TargetPlatformDetector INSTANCE = new TargetPlatformDetector();
@@ -55,6 +60,19 @@ public class TargetPlatformDetector {
return contextFile instanceof KtFile ? getPlatform((KtFile) contextFile) : JvmPlatform.INSTANCE;
}
if (file.isScript()) {
KotlinScriptDefinition scriptDefinition = findScriptDefinition(file);
if (scriptDefinition != null) {
String platformNameFromScriptDefinition = scriptDefinition.getPlatform();
for (IdePlatform platform : IdePlatformKind.Companion.getAll_PLATFORMS()) {
TargetPlatform compilerPlatform = platform.getKind().getCompilerPlatform();
if (compilerPlatform.getPlatformName().equals(platformNameFromScriptDefinition)) {
return compilerPlatform;
}
}
}
}
VirtualFile virtualFile = file.getOriginalFile().getVirtualFile();
if (virtualFile != null) {
Module moduleForFile = ProjectFileIndex.SERVICE.getInstance(file.getProject()).getModuleForFile(virtualFile);
@@ -0,0 +1,50 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.codeInsight.gradle
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiManager
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.core.script.ScriptDependenciesManager
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.plugins.gradle.tooling.annotation.TargetVersions
import org.jetbrains.plugins.gradle.util.GradleConstants
import org.junit.Test
class GradleBuildFileHighlightingTest : GradleImportingTestCase() {
@TargetVersions("4.8+")
@Test
fun testKtsInJsProject() {
val files = configureByFiles()
importProjectUsingSingeModulePerGradleProject()
checkHighlighting(files)
}
private fun checkHighlighting(files: List<VirtualFile>) {
for (file in files.filter { it.name.endsWith(GradleConstants.KOTLIN_DSL_SCRIPT_EXTENSION) }) {
runReadAction {
val psiFile = PsiManager.getInstance(myProject).findFile(file) as? KtFile
?: error("Couldn't find psiFile for virtual file: ${file.canonicalPath}")
ScriptDependenciesManager.updateScriptDependenciesSynchronously(file, myProject)
val bindingContext = psiFile.analyze()
val diagnostics = bindingContext.diagnostics.filter { it.severity == Severity.ERROR }
assert(diagnostics.isEmpty()) {
"Diagnostic's list should be empty:\n ${diagnostics.joinToString("\n") { DefaultErrorMessages.render(it) }}"
}
}
}
}
override fun testDataDirName() = "highlighting"
}
@@ -0,0 +1,21 @@
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
plugins {
id("kotlin2js") version "1.3.10"
}
dependencies {
implementation(kotlin("stdlib-js", "1.3.10"))
}
repositories {
jcenter()
}
tasks {
"compileKotlin2Js"(Kotlin2JsCompile::class) {
kotlinOptions {
metaInfo = true
}
}
}
@@ -0,0 +1,11 @@
pluginManagement {
resolutionStrategy {
eachPlugin {
if (requested.id.id == "kotlin2js") {
useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}")
}
}
}
}
rootProject.name = 'test'
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.idea.util.module
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
@@ -49,6 +50,11 @@ class IdeaKotlinUastResolveProviderService : KotlinUastResolveProviderService {
}
override fun isJvmElement(psiElement: PsiElement): Boolean {
val containingFile = psiElement.containingFile
if (containingFile is KtFile) {
return TargetPlatformDetector.getPlatform(containingFile) is JvmPlatform
}
val module = psiElement.module
return module == null || TargetPlatformDetector.getPlatform(module) is JvmPlatform
}
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.idea.util.module
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.uast.kotlin.KotlinUastResolveProviderService
@@ -45,6 +46,11 @@ class IdeaKotlinUastResolveProviderService : KotlinUastResolveProviderService {
}
override fun isJvmElement(psiElement: PsiElement): Boolean {
val containingFile = psiElement.containingFile
if (containingFile is KtFile) {
return TargetPlatformDetector.getPlatform(containingFile) is JvmPlatform
}
val module = psiElement.module
return module == null || TargetPlatformDetector.getPlatform(module) is JvmPlatform
}