From 95a3b337c6992ea6715561145f8eee16df4bef8d Mon Sep 17 00:00:00 2001 From: Vyacheslav Gerasimov Date: Thu, 13 Dec 2018 22:19:24 +0300 Subject: [PATCH] Build: add instrumentation to all JavaCompile tasks --- .idea/dictionaries/4u7.xml | 1 + build.gradle.kts | 8 +-- .../test/util/NotNullInstrumentationTest.java | 28 +++++++++ .../test/NotNullInstrumentationTest.java | 28 +++++++++ javaInstrumentation.gradle.kts | 61 +++++++++++++++++++ 5 files changed, 121 insertions(+), 5 deletions(-) create mode 100644 compiler/tests/org/jetbrains/kotlin/test/util/NotNullInstrumentationTest.java create mode 100644 idea/tests/org/jetbrains/kotlin/test/NotNullInstrumentationTest.java create mode 100644 javaInstrumentation.gradle.kts diff --git a/.idea/dictionaries/4u7.xml b/.idea/dictionaries/4u7.xml index 6daf4ae8e61..720bcaa440d 100644 --- a/.idea/dictionaries/4u7.xml +++ b/.idea/dictionaries/4u7.xml @@ -3,6 +3,7 @@ cidr foldable + instrumentator redirector diff --git a/build.gradle.kts b/build.gradle.kts index 4d514a8b880..3ff667cc066 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,13 +1,9 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar -import org.gradle.api.Project -import java.util.* -import java.io.File -import org.gradle.api.tasks.bundling.Jar import org.gradle.plugins.ide.idea.model.IdeaModel +import org.gradle.api.file.FileCollection import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile import proguard.gradle.ProGuardTask buildscript { @@ -148,7 +144,9 @@ fun checkJDK() { rootProject.apply { from(rootProject.file("versions.gradle.kts")) from(rootProject.file("report.gradle.kts")) + from(rootProject.file("javaInstrumentation.gradle.kts")) } + IdeVersionConfigurator.setCurrentIde(this) extra["versions.protobuf-java"] = "2.6.1" diff --git a/compiler/tests/org/jetbrains/kotlin/test/util/NotNullInstrumentationTest.java b/compiler/tests/org/jetbrains/kotlin/test/util/NotNullInstrumentationTest.java new file mode 100644 index 00000000000..21094a23b4a --- /dev/null +++ b/compiler/tests/org/jetbrains/kotlin/test/util/NotNullInstrumentationTest.java @@ -0,0 +1,28 @@ +/* + * 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.test.util; + +import junit.framework.TestCase; +import org.jetbrains.annotations.NotNull; +import org.junit.Assert; + +public class NotNullInstrumentationTest extends TestCase { + + public void testArgument() { + try { + //noinspection ConstantConditions + instrumented(null); + } catch (IllegalArgumentException e) { + return; + } + + Assert.fail("IllegalArgumentException is expected"); + } + + private void instrumented(@NotNull Object o) { + // This method should be instrumented with not null check + } +} diff --git a/idea/tests/org/jetbrains/kotlin/test/NotNullInstrumentationTest.java b/idea/tests/org/jetbrains/kotlin/test/NotNullInstrumentationTest.java new file mode 100644 index 00000000000..08f6e11f9db --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/test/NotNullInstrumentationTest.java @@ -0,0 +1,28 @@ +/* + * 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.test; + +import junit.framework.TestCase; +import org.jetbrains.annotations.NotNull; +import org.junit.Assert; + +public class NotNullInstrumentationTest extends TestCase { + + public void testArgument() { + try { + //noinspection ConstantConditions + instrumented(null); + } catch (IllegalArgumentException e) { + return; + } + + Assert.fail("IllegalArgumentException is expected"); + } + + private void instrumented(@NotNull Object o) { + // This method should be instrumented with not null check + } +} diff --git a/javaInstrumentation.gradle.kts b/javaInstrumentation.gradle.kts new file mode 100644 index 00000000000..169dd54bb1c --- /dev/null +++ b/javaInstrumentation.gradle.kts @@ -0,0 +1,61 @@ +/* + * 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. + */ + +allprojects { + afterEvaluate { + configureJavaInstrumentation() + } +} + +// Hide window of instrumentation tasks +val headlessOldValue: String? = System.setProperty("java.awt.headless", "true") +logger.info("Setting java.awt.headless=true, old value was $headlessOldValue") + +/** + * Configures instrumentation for all JavaCompile tasks in project + */ +fun Project.configureJavaInstrumentation() { + if (plugins.hasPlugin("org.gradle.java")) { + val javaInstrumentator by configurations.creating + dependencies { + javaInstrumentator(intellijDep()) { + includeJars("javac2", "jdom", "asm-all", rootProject = rootProject) + } + } + + tasks.withType { + doLast { + instrumentClasses(javaInstrumentator.asPath) + } + } + } +} + +fun JavaCompile.instrumentClasses(instrumentatorClasspath: String) { + ant.withGroovyBuilder { + "taskdef"( + "name" to "instrumentIdeaExtensions", + "classpath" to instrumentatorClasspath, + "loaderref" to "java2.loader", + "classname" to "com.intellij.ant.InstrumentIdeaExtensions" + ) + } + + val sourceSet = project.sourceSets.single { it.compileJavaTaskName == name } + + val javaSourceDirectories = sourceSet.allJava.sourceDirectories.filter { it.exists() } + + ant.withGroovyBuilder { + javaSourceDirectories.forEach { directory -> + "instrumentIdeaExtensions"( + "srcdir" to directory, + "destdir" to destinationDir, + "classpath" to classpath.asPath, + "includeantruntime" to false, + "instrumentNotNull" to true + ) + } + } +} \ No newline at end of file