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