diff --git a/java/compiler/javac2/src/com/intellij/ant/ClassFilterAnnotationRegexp.java b/java/compiler/javac2/src/com/intellij/ant/ClassFilterAnnotationRegexp.java
new file mode 100644
index 000000000000..bb69d806b570
--- /dev/null
+++ b/java/compiler/javac2/src/com/intellij/ant/ClassFilterAnnotationRegexp.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-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 com.intellij.ant;
+
+import org.apache.tools.ant.types.RegularExpression;
+
+/**
+ * A pattern which is used to skip NotNull assertion instrumentation on classes that have at least one annotation matching this pattern.
+ *
+ * Example usage:
+ *
+ *
+ *
+ *
+ */
+public class ClassFilterAnnotationRegexp extends RegularExpression {
+}
diff --git a/java/compiler/javac2/src/com/intellij/ant/Javac2.java b/java/compiler/javac2/src/com/intellij/ant/Javac2.java
index e5b8aee7130a..d41e5dc70ebd 100644
--- a/java/compiler/javac2/src/com/intellij/ant/Javac2.java
+++ b/java/compiler/javac2/src/com/intellij/ant/Javac2.java
@@ -25,10 +25,8 @@ import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Javac;
import org.apache.tools.ant.types.Path;
-import org.jetbrains.org.objectweb.asm.ClassReader;
-import org.jetbrains.org.objectweb.asm.ClassVisitor;
-import org.jetbrains.org.objectweb.asm.ClassWriter;
-import org.jetbrains.org.objectweb.asm.Opcodes;
+import org.apache.tools.ant.util.regexp.Regexp;
+import org.jetbrains.org.objectweb.asm.*;
import java.io.*;
import java.net.MalformedURLException;
@@ -40,6 +38,7 @@ public class Javac2 extends Javac {
private ArrayList myFormFiles;
private List myNestedFormPathList;
private boolean instrumentNotNull = true;
+ private List myClassFilterAnnotationRegexpList = new ArrayList(0);
public Javac2() {
}
@@ -75,6 +74,16 @@ public class Javac2 extends Javac {
this.instrumentNotNull = instrumentNotNull;
}
+ /**
+ * Allows to specify patterns of annotation class names to skip NotNull instrumentation on classes which have at least one
+ * annotation matching at least one of the given patterns
+ *
+ * @param regexp the regular expression for JVM internal name (slash-separated) of annotations
+ */
+ public void add(final ClassFilterAnnotationRegexp regexp) {
+ myClassFilterAnnotationRegexpList.add(regexp.getRegexp(getProject()));
+ }
+
/**
* The overridden setter method that warns about unsupported option.
*
@@ -425,8 +434,8 @@ public class Javac2 extends Javac {
ClassReader reader = new ClassReader(inputStream);
int version = getClassFileVersion(reader);
-
- if (version >= Opcodes.V1_5) {
+
+ if (version >= Opcodes.V1_5 && !shouldBeSkippedByAnnotationPattern(reader)) {
ClassWriter writer = new InstrumenterClassWriter(getAsmClassWriterFlags(version), finder);
if (NotNullVerifyingInstrumenter.processClassFile(reader, writer)) {
@@ -471,6 +480,30 @@ public class Javac2 extends Javac {
return classfileVersion[0];
}
+ private boolean shouldBeSkippedByAnnotationPattern(ClassReader reader) {
+ if (myClassFilterAnnotationRegexpList.isEmpty()) {
+ return false;
+ }
+
+ final boolean[] result = new boolean[]{false};
+ reader.accept(new ClassVisitor(Opcodes.ASM5) {
+ public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+ if (!result[0]) {
+ String internalName = Type.getType(desc).getInternalName();
+ for (Regexp regexp : myClassFilterAnnotationRegexpList) {
+ if (regexp.matches(internalName)) {
+ result[0] = true;
+ break;
+ }
+ }
+ }
+ return null;
+ }
+ }, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
+
+ return result[0];
+ }
+
private void fireError(final String message) {
if (failOnError) {
throw new BuildException(message, getLocation());