diff --git a/compiler/psi/src/org/jetbrains/kotlin/script/KotlinScriptDefinition.kt b/compiler/psi/src/org/jetbrains/kotlin/script/KotlinScriptDefinition.kt index d9cacf50549..66ce08a177b 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/script/KotlinScriptDefinition.kt +++ b/compiler/psi/src/org/jetbrains/kotlin/script/KotlinScriptDefinition.kt @@ -48,6 +48,10 @@ open class KotlinScriptDefinition(open val template: KClass) : 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> get() = emptyList() diff --git a/compiler/psi/src/org/jetbrains/kotlin/script/KotlinScriptDefinitionProvider.kt b/compiler/psi/src/org/jetbrains/kotlin/script/KotlinScriptDefinitionProvider.kt index cd3ce4c0450..3c1cba17799 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/script/KotlinScriptDefinitionProvider.kt +++ b/compiler/psi/src/org/jetbrains/kotlin/script/KotlinScriptDefinitionProvider.kt @@ -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 || diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/TargetPlatformDetector.java b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/TargetPlatformDetector.java index b67c6f2d714..3297729e41c 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/TargetPlatformDetector.java +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/TargetPlatformDetector.java @@ -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); diff --git a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleBuildFileHighlightingTest.kt b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleBuildFileHighlightingTest.kt new file mode 100644 index 00000000000..85f9e015933 --- /dev/null +++ b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleBuildFileHighlightingTest.kt @@ -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) { + 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" +} \ No newline at end of file diff --git a/idea/testData/gradle/highlighting/ktsInJsProject/build.gradle.kts b/idea/testData/gradle/highlighting/ktsInJsProject/build.gradle.kts new file mode 100644 index 00000000000..e30ba944bab --- /dev/null +++ b/idea/testData/gradle/highlighting/ktsInJsProject/build.gradle.kts @@ -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 + } + } +} diff --git a/idea/testData/gradle/highlighting/ktsInJsProject/settings.gradle b/idea/testData/gradle/highlighting/ktsInJsProject/settings.gradle new file mode 100644 index 00000000000..7439557b5f8 --- /dev/null +++ b/idea/testData/gradle/highlighting/ktsInJsProject/settings.gradle @@ -0,0 +1,11 @@ +pluginManagement { + resolutionStrategy { + eachPlugin { + if (requested.id.id == "kotlin2js") { + useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}") + } + } + } +} + +rootProject.name = 'test' \ No newline at end of file diff --git a/plugins/uast-kotlin-idea/src/IdeaKotlinUastResolveProviderService.kt b/plugins/uast-kotlin-idea/src/IdeaKotlinUastResolveProviderService.kt index 789e00f8d0c..5511e3cfe93 100644 --- a/plugins/uast-kotlin-idea/src/IdeaKotlinUastResolveProviderService.kt +++ b/plugins/uast-kotlin-idea/src/IdeaKotlinUastResolveProviderService.kt @@ -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 } diff --git a/plugins/uast-kotlin-idea/src/IdeaKotlinUastResolveProviderService.kt.182 b/plugins/uast-kotlin-idea/src/IdeaKotlinUastResolveProviderService.kt.182 index 081f6b72752..52097b671b1 100644 --- a/plugins/uast-kotlin-idea/src/IdeaKotlinUastResolveProviderService.kt.182 +++ b/plugins/uast-kotlin-idea/src/IdeaKotlinUastResolveProviderService.kt.182 @@ -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 }