diff --git a/.idea/libraries/coverage_plugin.xml b/.idea/libraries/coverage_plugin.xml new file mode 100644 index 00000000000..91df8c11739 --- /dev/null +++ b/.idea/libraries/coverage_plugin.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/idea/idea.iml b/idea/idea.iml index 21412d50803..ea77e4c848e 100644 --- a/idea/idea.iml +++ b/idea/idea.iml @@ -44,5 +44,6 @@ + \ No newline at end of file diff --git a/idea/src/META-INF/coverage.xml b/idea/src/META-INF/coverage.xml new file mode 100644 index 00000000000..ce1756d8453 --- /dev/null +++ b/idea/src/META-INF/coverage.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 2f695c90203..c34aef03115 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -15,6 +15,7 @@ com.intellij.copyright JavaScriptDebugger org.jetbrains.android + Coverage diff --git a/idea/src/org/jetbrains/jet/plugin/coverage/KotlinCoverageExtension.kt b/idea/src/org/jetbrains/jet/plugin/coverage/KotlinCoverageExtension.kt new file mode 100644 index 00000000000..3e29c7bf705 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/coverage/KotlinCoverageExtension.kt @@ -0,0 +1,85 @@ +/* + * Copyright 2010-2014 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.jet.plugin.coverage + +import com.intellij.coverage.JavaCoverageEngineExtension +import com.intellij.execution.configurations.RunConfigurationBase +import org.jetbrains.jet.plugin.run.JetRunConfiguration +import com.intellij.psi.PsiFile +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.coverage.CoverageSuitesBundle +import java.io.File +import org.jetbrains.jet.lang.psi.JetFile +import org.jetbrains.jet.plugin.debugger.JetPositionManager +import org.jetbrains.jet.plugin.caches.resolve.getModuleInfo +import java.util.HashSet +import org.jetbrains.jet.lang.psi.JetTreeVisitor +import org.jetbrains.jet.lang.psi.JetDeclaration +import com.intellij.openapi.roots.ProjectRootManager +import org.jetbrains.jet.lang.psi.JetTreeVisitorVoid +import org.jetbrains.annotations.TestOnly +import com.intellij.openapi.application.ApplicationManager + +public class KotlinCoverageExtension(): JavaCoverageEngineExtension() { + override fun isApplicableTo(conf: RunConfigurationBase?): Boolean = conf is JetRunConfiguration + + override fun collectOutputFiles(srcFile: PsiFile, + output: VirtualFile?, + testoutput: VirtualFile?, + suite: CoverageSuitesBundle, + classFiles: MutableSet): Boolean { + if (srcFile is JetFile) { + val fileIndex = ProjectRootManager.getInstance(srcFile.getProject()).getFileIndex() + if (fileIndex.isInLibraryClasses(srcFile.getVirtualFile()) || + fileIndex.isInLibrarySource(srcFile.getVirtualFile())) { + return false + } + + val classNames = ApplicationManager.getApplication().runReadAction> { collectOutputClassNames(srcFile) } + + fun findUnder(name: String, root: VirtualFile?): File? { + if (root != null) { + val outputFile = File(root.getPath(), name + ".class") + if (outputFile.exists()) { + return outputFile + } + } + return null + } + + classNames.map { findUnder(it, output) ?: findUnder(it, testoutput) }.filterNotNullTo(classFiles) + return true + } + return false + } + + class object { + TestOnly public fun collectOutputClassNames(srcFile: JetFile): Set { + val typeMapper = JetPositionManager.createTypeMapper(srcFile, srcFile.getModuleInfo()) + val classNames = HashSet() + srcFile.acceptChildren(object: JetTreeVisitorVoid() { + override fun visitDeclaration(dcl: JetDeclaration) { + val className = JetPositionManager.getClassNameForElement(dcl.getFirstChild(), typeMapper, srcFile, false) + if (className != null) { + classNames.add(className) + } + } + }) + return classNames + } + } +} \ No newline at end of file