diff options
author | Damien Martin-Guillerez <dmarting@google.com> | 2015-03-10 12:32:21 +0000 |
---|---|---|
committer | Damien Martin-Guillerez <dmarting@google.com> | 2015-03-10 16:13:29 +0100 |
commit | c513e114a0a5f97891433b80bf442c5e9acaf22b (patch) | |
tree | d3c1bb107bd3e7900f328235d0451bf87af990a7 | |
parent | a5a11203aa75729bd0b3a29a22a63977ee2267a0 (diff) |
Open-source ijar's tests
--
MOS_MIGRATED_REVID=88210083
32 files changed, 2478 insertions, 1 deletions
diff --git a/src/java_tools/buildjar/BUILD b/src/java_tools/buildjar/BUILD index d467e66bf9..4384cdd45b 100644 --- a/src/java_tools/buildjar/BUILD +++ b/src/java_tools/buildjar/BUILD @@ -117,6 +117,10 @@ java_library( name = "BazelJavaCompiler", srcs = ["java/com/google/devtools/build/java/bazel/BazelJavaCompiler.java"], data = ["//tools/defaults:java_langtools"], + visibility = [ + "//src:__subpackages__", + "//third_party/ijar:__subpackages__", + ], deps = [ ":JavaBuilderConfig", ":JavaLangtools", diff --git a/third_party/BUILD b/third_party/BUILD index ae72fdcd4d..86d6b28c36 100644 --- a/third_party/BUILD +++ b/third_party/BUILD @@ -120,6 +120,11 @@ java_import( ], ) +java_import( + name = "asm", + jars = ["asm/asm-5.0.3.jar"], +) + config_setting( name = "windows_mingw", values = {"compiler": "windows_mingw"}, diff --git a/third_party/README.md b/third_party/README.md index c1e992df26..9bdd67147b 100644 --- a/third_party/README.md +++ b/third_party/README.md @@ -136,3 +136,10 @@ Testing * Version: 1.3 * License: New BSD License + +[asm](https://asm.ow2.org) +----- + +* Version: 5.0.3 +* License: 3-clause revised BSD + diff --git a/third_party/asm/LICENSE b/third_party/asm/LICENSE new file mode 100644 index 0000000000..23ea440b63 --- /dev/null +++ b/third_party/asm/LICENSE @@ -0,0 +1,31 @@ +******************************************************************************* +* ASM: a very small and fast Java bytecode manipulation framework +* Copyright (c) 2000-2011 INRIA, France Telecom +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* 3. Neither the name of the copyright holders nor the names of its +* contributors may be used to endorse or promote products derived from +* this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +******************************************************************************* + +This directory contains the documentation of the product. diff --git a/third_party/asm/asm-5.0.3.jar b/third_party/asm/asm-5.0.3.jar Binary files differnew file mode 100644 index 0000000000..da5b23e156 --- /dev/null +++ b/third_party/asm/asm-5.0.3.jar diff --git a/third_party/ijar/BUILD b/third_party/ijar/BUILD index 6f6659f0d4..3c1e141403 100644 --- a/third_party/ijar/BUILD +++ b/third_party/ijar/BUILD @@ -1,4 +1,10 @@ -package(default_visibility = ["//src:__pkg__"]) +package( + default_visibility = [ + "//src:__pkg__", + "//third_party/ijar:__subpackages__", + ], +) + licenses(["notice"]) # Apache 2.0 cc_binary( diff --git a/third_party/ijar/test/A.java b/third_party/ijar/test/A.java new file mode 100644 index 0000000000..45c6b8fe13 --- /dev/null +++ b/third_party/ijar/test/A.java @@ -0,0 +1,71 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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. + + +import java.io.IOException; +import java.lang.annotation.*; + +class A { + + // Exercise removal of class initializers: + static { } + + // Exercise removal of private members: + private String privateField; + + protected int protectedField; + + // Exercise ConstantValue annotation + public static final long L1 = 123L; + + // Exercise removal of private members: + private void privateMethod() { + System.err.println("foofoofoofoo"); + } + + // Exercise Signature annotation: + protected <T> T protectedMethod(T t) { return t; } + + // Exercise Deprecated annotation: + @Deprecated + // Exercise Exceptions annotation: + public void deprecatedMethod() throws IOException {} + + // Exercise retention of private inner classes: + private class PrivateInner {} + + // Exercise InnerClasses attribute: + public class PublicInner {} + + public @interface MyAnnotation { + // Exercise BaseTypeElementValue: + String a() default "foo"; + + // Exercise EnumTypeElementValue: + ElementType b() default ElementType.METHOD; + + // Exercise ClassTypeElementValue: + Class<?> c() default String.class; + + // Exercise ArrayTypeElementValue: + String[] d() default { "foo", "bar" }; + + // Exercise AnnotationTypeElementValue: + Deprecated e() default @Deprecated; + } + + @Retention(RetentionPolicy.RUNTIME) + public @interface RuntimeAnnotation {} + +} diff --git a/third_party/ijar/test/AnnotatedClass.java b/third_party/ijar/test/AnnotatedClass.java new file mode 100644 index 0000000000..2a1535708c --- /dev/null +++ b/third_party/ijar/test/AnnotatedClass.java @@ -0,0 +1,38 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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. + +/** + * A heavily annotated class used for testing. + */ +@Annotations.RuntimeInvisible +@Annotations.RuntimeVisible +final class AnnotatedClass { + @Annotations.RuntimeInvisible + @Annotations.RuntimeVisible + String field; + + @Annotations.RuntimeInvisible + @Annotations.RuntimeVisible + private AnnotatedClass() {} + + @Annotations.RuntimeInvisible + @Annotations.RuntimeVisible + public static void publicStaticMethod( + @Annotations.RuntimeInvisible @Annotations.RuntimeVisible String param) { + @Annotations.RuntimeInvisible + @Annotations.RuntimeVisible + String local = "Hello " + param + "!"; + System.out.println(local); + } +} diff --git a/third_party/ijar/test/Annotations.java b/third_party/ijar/test/Annotations.java new file mode 100644 index 0000000000..a4fff58fc7 --- /dev/null +++ b/third_party/ijar/test/Annotations.java @@ -0,0 +1,38 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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. + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotations used for testing. + */ +final class Annotations { + private Annotations() {} + + @Target({ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.FIELD, + ElementType.LOCAL_VARIABLE, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE}) + @interface RuntimeInvisible {} + + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.FIELD, + ElementType.LOCAL_VARIABLE, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE}) + @interface RuntimeVisible {} + + @Target(ElementType.PARAMETER) + public @interface ParametersOnlyAnnotation { + } +} diff --git a/third_party/ijar/test/B.java b/third_party/ijar/test/B.java new file mode 100644 index 0000000000..c1a946016f --- /dev/null +++ b/third_party/ijar/test/B.java @@ -0,0 +1,51 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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. + + +import java.io.IOException; + +public class B extends A { + + B() { + // Will trigger compile error if Signature attr is missing. + String str = protectedMethod("foo"); + + try { + deprecatedMethod(); // <-- triggers deprecation warning; checked by + // .sh script. + } catch (IOException e) { // Will trigger compile error if Exceptions + // annotation is discarded. + } + + l(A.L1); // <-- should be a compile-time ConstantValue; checked by .sh. + + new PublicInner(); + } + + @MyAnnotation + void l(long l) {} + + @RuntimeAnnotation + public int k; + + public static void main(String[] args) throws Exception { + // Regression test for bug #1210750. + if (!Class.forName("B").getField("k").isAnnotationPresent(RuntimeAnnotation.class)) { + throw new AssertionError("RuntimeAnnotation got lost!"); + } + + System.err.println("B.main() OK"); + } + +} diff --git a/third_party/ijar/test/BUILD b/third_party/ijar/test/BUILD new file mode 100644 index 0000000000..cb17830fc8 --- /dev/null +++ b/third_party/ijar/test/BUILD @@ -0,0 +1,105 @@ +package(default_visibility = ["//visibility:__pkg__"]) + +licenses(["notice"]) # Apache License 2.0 + +exports_files(["LICENSE"]) + +sh_test( + name = "ijar_test", + size = "large", + srcs = ["ijar_test.sh"], + args = [ + "$(JAVAC)", + "$(JAVA)", + "$(JAVABASE)/bin/jar", + "$(JAVABASE)/bin/javap", + "$(location //third_party/ijar)", + "$(location //tools/jdk:langtools)", + # We assume unzip and zip to be on the path + "unzip", + "zip", + ], + data = [ + "//third_party/ijar", + "A.java", + "B.java", + "Object.java", + "WellCompressed1.java", + "WellCompressed2.java", + ":libtypeannotations2.jar", + "TypeAnnotationTest2.java", + # invokedynamic/ClassWithLambda.java, compiled with javac8 + ":libinvokedynamic.jar", + # Intentionally bad test JAR: file count in central directory + # wrong. + "libwrongcentraldir.jar", + "//tools/defaults:jdk", + "//tools/jdk:langtools", + ], +) + +java_library( + name = "invokedynamic", + testonly = 1, + srcs = ["invokedynamic/ClassWithLambda.java"], + javacopts = ["-source 8 -target 8"], +) + +# For testing purposes: a class which exposes a private nested class in +# public API, classes with annotations and a class with different forms of +# deprecations markers +java_library( + name = "ijar_testlib", + srcs = [ + "AnnotatedClass.java", + "Annotations.java", + "DeprecatedParts.java", + "DumbClass.java", + "EnclosingMethod.java", + "PrivateMembersClass.java", + ], +) + +# For testing purposes: an interface jar (ijar) which includes the +# interface view of the various test class from above. +genrule( + name = "interface_ijar_testlib", + srcs = [":ijar_testlib"], + outs = ["interface_ijar_testlib.jar"], + cmd = "$(location //third_party/ijar) $< $@", + tools = ["//third_party/ijar"], +) + +java_library( + name = "typeannotations2", + srcs = glob(["typeannotations2/**/*.java"]), + javacopts = ["-source 8 -target 8"], +) + +java_test( + name = "IjarTests", + size = "small", + srcs = [ + "IjarTests.java", + "StripVerifyingVisitor.java", + ], + args = ["IjarTests"], + data = [ + "PrivateNestedClass.java", + "UseDeprecatedParts.java", + "UseRestrictedAnnotation.java", + "package-info.java", + ":interface_ijar_testlib", + ], + deps = [ + "//src/java_tools/buildjar:BazelJavaCompiler", + "//third_party:asm", + "//third_party:junit4", + ], +) + +test_suite( + name = "all_tests", + testonly = 1, + visibility = ["//visibility:public"], +) diff --git a/third_party/ijar/test/DeprecatedParts.java b/third_party/ijar/test/DeprecatedParts.java new file mode 100644 index 0000000000..1cbed27835 --- /dev/null +++ b/third_party/ijar/test/DeprecatedParts.java @@ -0,0 +1,93 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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. + +/** + * A class with various deprecated parts used for testing. + */ +@SuppressWarnings("dep-ann") +final class DeprecatedParts { + @Deprecated + public static String deprecatedViaAnnotationStaticField = "hi"; + + /** + * @deprecated Marked deprecated for test. + */ + public static String deprecatedViaJavadocStaticField = "hi"; + + @Deprecated + public String deprecatedViaAnnotationField = "hi"; + + /** + * @deprecated Marked deprecated for test. + */ + public String deprecatedViaJavadocField = "hi"; + + @Deprecated + public void deprecatedViaAnnotationMethod() { + } + + /** + * @deprecated Marked deprecated for test. + */ + public void deprecatedViaJavadocMethod() { + } + + // Note: @Deprecated can be applied to parameters, but the compiler doesn't seem to use it + + @Deprecated + public static void deprecatedViaAnnotationStaticMethod() { + } + + /** + * @deprecated Marked deprecated for test. + */ + public static void deprecatedViaJavadocStaticMethod() { + } + + @Deprecated + public @interface DeprecatedViaAnnotationAnnotation {} + + /** + * @deprecated Marked deprecated for test. + */ + public @interface DeprecatedViaJavadocAnnotation {} + + @Deprecated + public static class DeprecatedViaAnnotationClass {} + + /** + * @deprecated Marked deprecated to exercise preservation of deprecation. + */ + public static class DeprecatedViaJavadocClass {} + + public static class DeprecatedViaAnnotationConstructor { + @Deprecated + public DeprecatedViaAnnotationConstructor() {} + } + + public static class DeprecatedViaJavadocConstructor { + /** + * @deprecated Marked deprecated for test. + */ + public DeprecatedViaJavadocConstructor() {} + } + + @Deprecated + public interface DeprecatedViaAnnotationInterface {} + + /** + * @deprecated Marked deprecated for test. + */ + public interface DeprecatedViaJavadocInterface {} +} diff --git a/third_party/ijar/test/DumbClass.java b/third_party/ijar/test/DumbClass.java new file mode 100644 index 0000000000..4b685f943d --- /dev/null +++ b/third_party/ijar/test/DumbClass.java @@ -0,0 +1,24 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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. + +/** + * For testing purposes: a "dumb" class in that it exposes a private + * inner class in public API. + */ +class DumbClass<V> { + public Inner inner; + private class Inner { + V v; + } +} diff --git a/third_party/ijar/test/EnclosingMethod.java b/third_party/ijar/test/EnclosingMethod.java new file mode 100644 index 0000000000..1684d7a3bf --- /dev/null +++ b/third_party/ijar/test/EnclosingMethod.java @@ -0,0 +1,39 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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. + +import java.util.concurrent.Callable; + +/** + * For testing purposes, an anonymous inner class that requires an + * EnclosingMethod attribute in its class file. + */ +class EnclosingMethod { + class Inner { + public <T> T run(Callable<T> callable) { + try { + return callable.call(); + } catch (Exception ex) { + return null; + } + } + + private <T> Callable<T> asCallable(final Callable<T> callableToWrap) { + return new Callable<T>() { + @Override public T call() throws Exception { + return Inner.this.run(callableToWrap); + } + }; + } + } +}
\ No newline at end of file diff --git a/third_party/ijar/test/IjarTests.java b/third_party/ijar/test/IjarTests.java new file mode 100644 index 0000000000..0448b33b71 --- /dev/null +++ b/third_party/ijar/test/IjarTests.java @@ -0,0 +1,194 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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. + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.fail; + +import com.google.devtools.build.java.bazel.BazelJavaCompiler; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import org.objectweb.asm.ClassReader; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.Enumeration; +import java.util.Locale; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.RoundEnvironment; +import javax.lang.model.element.TypeElement; +import javax.tools.Diagnostic; +import javax.tools.DiagnosticCollector; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.StandardLocation; +import javax.tools.ToolProvider; + +/** + * JUnit tests for ijar tool. + */ +@RunWith(JUnit4.class) +public class IjarTests { + + private static File getTmpDir() { + String tmpdir = System.getenv("TEST_TMPDIR"); + if (tmpdir == null) { + // Fall back on the system temporary directory + tmpdir = System.getProperty("java.io.tmpdir"); + } + if (tmpdir == null) { + fail("TEST_TMPDIR environment variable is not set!"); + } + return new File(tmpdir); + } + + DiagnosticCollector<JavaFileObject> diagnostics; + + private JavaCompiler.CompilationTask makeCompilationTask(String... files) throws IOException { + JavaCompiler compiler = BazelJavaCompiler.newInstance(); + StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); + fileManager.setLocation(StandardLocation.CLASS_PATH, + Arrays.asList(new File("third_party/ijar/test/interface_ijar_testlib.jar"))); + fileManager.setLocation(StandardLocation.CLASS_OUTPUT, + Arrays.asList(getTmpDir())); + diagnostics = new DiagnosticCollector<JavaFileObject>(); + return compiler.getTask(null, + fileManager, + diagnostics, + Arrays.asList("-Xlint:deprecation"), // used for deprecation tests + null, + fileManager.getJavaFileObjects(files)); + } + + /** + * Test that the ijar tool preserves private nested classes as they + * may be exposed through public API. This test relies on an + * interface jar provided through the build rule + * :interface_ijar_testlib and the Java source file + * PrivateNestedClass.java. + */ + @Test + public void testPrivateNestedClass() throws IOException { + if (!makeCompilationTask("third_party/ijar/test/PrivateNestedClass.java").call()) { + fail(getFailedCompilationMessage()); + } + } + + /** + * Test that the ijar tool preserves annotations, especially @Target + * meta-annotation. + */ + @Test + public void testRestrictedAnnotations() throws IOException { + assertFalse(makeCompilationTask("third_party/ijar/test/UseRestrictedAnnotation.java").call()); + } + + /** + * Test that the ijar tool preserves private nested classes as they + * may be exposed through public API. This test relies on an + * interface jar provided through the build rule + * :interface_ijar_testlib and the Java source file + * PrivateNestedClass.java. + */ + @Test + public void testDeprecatedParts() throws IOException { + if (!makeCompilationTask("third_party/ijar/test/UseDeprecatedParts.java").call()) { + fail(getFailedCompilationMessage()); + } + int deprecatedWarningCount = 0; + for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) { + if ((diagnostic.getKind() == Diagnostic.Kind.MANDATORY_WARNING) && + // Java 6: + (diagnostic.getMessage(Locale.ENGLISH).startsWith("[deprecation]") || + // Java 7: + diagnostic.getMessage(Locale.ENGLISH).contains("has been deprecated"))) { + deprecatedWarningCount++; + } + } + assertEquals(16, deprecatedWarningCount); + } + + /** + * Test that the ijar tool preserves EnclosingMethod attributes and doesn't + * prevent annotation processors from accessing all the elements in a package. + */ + @Test + public void testEnclosingMethod() throws IOException { + JavaCompiler.CompilationTask task = makeCompilationTask("third_party/ijar/test/package-info.java"); + task.setProcessors(Arrays.asList(new AbstractProcessor() { + @Override + public Set<String> getSupportedAnnotationTypes() { + return Collections.singleton("*"); + } + + @Override + public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { + roundEnv.getElementsAnnotatedWith(java.lang.Override.class); + return true; + } + })); + if (!task.call()) { + fail(getFailedCompilationMessage()); + } + } + + @Test + public void testVerifyStripping() throws Exception { + ZipFile zip = new ZipFile("third_party/ijar/test/interface_ijar_testlib.jar"); + Enumeration<? extends ZipEntry> entries = zip.entries(); + while (entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + ClassReader reader = new ClassReader(zip.getInputStream(entry)); + StripVerifyingVisitor verifier = new StripVerifyingVisitor(); + + reader.accept(verifier, 0); + + if (verifier.errors.size() > 0) { + StringBuilder builder = new StringBuilder(); + builder.append("Verification of "); + builder.append(entry.getName()); + builder.append(" failed: "); + for (String msg : verifier.errors) { + builder.append(msg); + builder.append("\t"); + } + fail(builder.toString()); + } + } + } + + private String getFailedCompilationMessage() { + StringBuilder builder = new StringBuilder(); + builder.append("Build failed unexpectedly"); + for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) { + builder.append(String.format( + "\t%s line %d column %d: %s", + diagnostic.getKind().toString(), + diagnostic.getLineNumber(), + diagnostic.getColumnNumber(), + diagnostic.getMessage(Locale.ENGLISH))); + } + return builder.toString(); + } +} diff --git a/third_party/ijar/test/Object.java b/third_party/ijar/test/Object.java new file mode 100644 index 0000000000..93b508886a --- /dev/null +++ b/third_party/ijar/test/Object.java @@ -0,0 +1,18 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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 java.lang; + +class Object { +} diff --git a/third_party/ijar/test/PrivateMembersClass.java b/third_party/ijar/test/PrivateMembersClass.java new file mode 100644 index 0000000000..0f4ecaf71d --- /dev/null +++ b/third_party/ijar/test/PrivateMembersClass.java @@ -0,0 +1,51 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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. + +/** + * A class with many private parts. Used for testing. + */ +final class PrivateMembersClass { + private String privateField; + + private PrivateMembersClass() {} + + public static void main() { + privateStaticMethod(); + } + + private static void privateStaticMethod() { + new PrivateMembersClass().privateMethod(); + } + + private void privateMethod() { + new PrivateInnerClass().print(); + new PrivateStaticInnerClass().print(); + } + + private class PrivateInnerClass { + void print() { + System.out.println("private inner"); + } + } + + private static class PrivateStaticInnerClass { + void print() { + System.out.println("private static inner"); + } + } + + private interface PrivateInnerInterface {} + + private @interface PrivateInnerAnnotation {} +} diff --git a/third_party/ijar/test/PrivateNestedClass.java b/third_party/ijar/test/PrivateNestedClass.java new file mode 100644 index 0000000000..4459d5cd5f --- /dev/null +++ b/third_party/ijar/test/PrivateNestedClass.java @@ -0,0 +1,20 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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. + +/** + * For testing purposes: a client of DumbClass. + */ +class PrivateNestedClass { + static { Object o = new DumbClass<String>().inner; } +} diff --git a/third_party/ijar/test/StripVerifyingVisitor.java b/third_party/ijar/test/StripVerifyingVisitor.java new file mode 100644 index 0000000000..0045018625 --- /dev/null +++ b/third_party/ijar/test/StripVerifyingVisitor.java @@ -0,0 +1,223 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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. + +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.Attribute; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; + +import java.util.ArrayList; +import java.util.List; + +/** + * A {@code ClassVisitor} that checks that ijar did its job. + */ +final class StripVerifyingVisitor extends ClassVisitor { + public List<String> errors = new ArrayList<String>(); + private String className; + + public StripVerifyingVisitor() { + super(Opcodes.ASM4); + } + + @Override public void visit( + int version, + int access, + String name, + String signature, + String superName, + String[] interfaces) { + className = name; + if ((access & Opcodes.ACC_PRIVATE) != 0) { + errors.add(String.format("Private class found %s", className)); + } + } + + @Override public void visitSource(String source, String debug) { + errors.add(String.format("Source entry found %s %s", source, debug)); + } + + @Override public void visitOuterClass(String owner, String name, String desc) { + // Always okay. + } + + @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { + // Always okay. + return null; + } + + @Override public void visitAttribute(Attribute attr) { + // Just assume this is okay. + } + + @Override public void visitInnerClass( + String name, + String outerName, + String innerName, + int access) { + // Always okay + // TODO(bazel-team): verify removal of leftover inner classes once implemented + // TODO(bazel-team): verify removal of private inner classes once implemented + } + + @Override public FieldVisitor visitField( + int access, + String name, + String desc, + String signature, + Object value) { + if ((access & Opcodes.ACC_PRIVATE) != 0) { + errors.add(String.format("Private field %s found in %s", name, className)); + } + // We need to go deeper. + return new StripVerifyingFieldVisitor(errors, className, name); + } + + @Override public MethodVisitor visitMethod( + int access, + String name, + String desc, + String signature, + String[] exceptions) { + if ((access & Opcodes.ACC_PRIVATE) != 0) { + errors.add(String.format("Private method %s found in %s", name, className)); + } + // We need to go deeper. + return new StripVerifyingMethodVisitor(errors, className, name); + } + + @Override public void visitEnd() { + // Always okay. + } + + private static class StripVerifyingFieldVisitor extends FieldVisitor { + private final List<String> errors; + private final String className; + private final String fieldName; + + StripVerifyingFieldVisitor(List<String> errors, String className, String fieldName) { + super(Opcodes.ASM4); + this.errors = errors; + this.className = className; + this.fieldName = fieldName; + } + + @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { + // Always okay. + return null; + } + + @Override public void visitAttribute(Attribute attr) { + // Just assume this is okay. + } + + @Override public void visitEnd() { + // Always okay. + } + } + + private static class StripVerifyingMethodVisitor extends MethodVisitor { + private final List<String> errors; + private final String className; + private final String methodName; + + StripVerifyingMethodVisitor(List<String> errors, String className, String methodName) { + super(Opcodes.ASM4); + this.errors = errors; + this.className = className; + this.methodName = methodName; + } + + @Override public AnnotationVisitor visitAnnotationDefault() { + // Always okay. + return null; + } + + @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { + // Always okay. + return null; + } + + @Override public AnnotationVisitor visitParameterAnnotation( + int parameter, + String desc, + boolean visible) { + // Always okay. + return null; + } + + @Override public void visitAttribute(Attribute attr) { + // Just assume this is okay. + } + + @Override public void visitCode() { + errors.add(String.format("Code found for method %s of %s", methodName, className)); + } + + @Override public void visitEnd() {} + + // We ignore all details about code segments. Presumably we already logged an error about code + // existing at all. + + @Override public void visitFrame( + int type, + int nLocal, + Object[] local, + int nStack, + Object[] stack) {} + + @Override public void visitInsn(int opcode) {} + + @Override public void visitIntInsn(int opcode, int operand) {} + + @Override public void visitVarInsn(int opcode, int var) {} + + @Override public void visitTypeInsn(int opcode, String type) {} + + @Override public void visitFieldInsn(int opcode, String owner, String name, String desc) {} + + @Override public void visitMethodInsn(int opcode, String owner, String name, String desc) {} + + @Override public void visitJumpInsn(int opcode, Label label) {} + + @Override public void visitLabel(Label label) {} + + @Override public void visitLdcInsn(Object cst) {} + + @Override public void visitIincInsn(int var, int increment) {} + + @Override public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {} + + @Override public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {} + + @Override public void visitMultiANewArrayInsn(String desc, int dims) {} + + @Override public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {} + + @Override public void visitLocalVariable( + String name, + String desc, + String signature, + Label start, + Label end, + int index) {} + + @Override public void visitLineNumber(int line, Label start) {} + + @Override public void visitMaxs(int maxStack, int maxLocals) {} + } +} diff --git a/third_party/ijar/test/TypeAnnotationTest2.java b/third_party/ijar/test/TypeAnnotationTest2.java new file mode 100644 index 0000000000..a539790085 --- /dev/null +++ b/third_party/ijar/test/TypeAnnotationTest2.java @@ -0,0 +1,19 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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. + +public class TypeAnnotationTest2 { + void m(Object o) { + Util.castNullable(null); + } +} diff --git a/third_party/ijar/test/UseDeprecatedParts.java b/third_party/ijar/test/UseDeprecatedParts.java new file mode 100644 index 0000000000..024a5816c0 --- /dev/null +++ b/third_party/ijar/test/UseDeprecatedParts.java @@ -0,0 +1,48 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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. + +/** + * A class that uses deprecated things for testing. + */ +final class UseDeprecatedParts { + @DeprecatedParts.DeprecatedViaAnnotationAnnotation String annotatedField1; + @DeprecatedParts.DeprecatedViaJavadocAnnotation String annotatedField2; + + static final DeprecatedParts.DeprecatedViaAnnotationConstructor dummyField1 = + new DeprecatedParts.DeprecatedViaAnnotationConstructor(); + static final DeprecatedParts.DeprecatedViaJavadocConstructor dummyField2 = + new DeprecatedParts.DeprecatedViaJavadocConstructor (); + + public static void dummyMethod() { + System.out.println(DeprecatedParts.deprecatedViaAnnotationStaticField); + System.out.println(DeprecatedParts.deprecatedViaJavadocStaticField); + + System.out.println(new DeprecatedParts().deprecatedViaAnnotationField); + System.out.println(new DeprecatedParts().deprecatedViaJavadocField); + + new DeprecatedParts().deprecatedViaAnnotationMethod(); + new DeprecatedParts().deprecatedViaJavadocMethod(); + + DeprecatedParts.deprecatedViaAnnotationStaticMethod(); + DeprecatedParts.deprecatedViaJavadocStaticMethod(); + } + + class Class1 extends DeprecatedParts.DeprecatedViaAnnotationClass {} + + class Class2 extends DeprecatedParts.DeprecatedViaJavadocClass {} + + interface Interface1 extends DeprecatedParts.DeprecatedViaAnnotationInterface {} + + interface Interface2 extends DeprecatedParts.DeprecatedViaJavadocInterface {} +} diff --git a/third_party/ijar/test/UseRestrictedAnnotation.java b/third_party/ijar/test/UseRestrictedAnnotation.java new file mode 100644 index 0000000000..fcdb83ad2d --- /dev/null +++ b/third_party/ijar/test/UseRestrictedAnnotation.java @@ -0,0 +1,22 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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. + +/** + * Incorrect use of RestrictedAnnotation. Used for testing. + */ +public class UseRestrictedAnnotation { + @Annotations.ParametersOnlyAnnotation + public void m() { + } +} diff --git a/third_party/ijar/test/WellCompressed1.java b/third_party/ijar/test/WellCompressed1.java new file mode 100644 index 0000000000..7fc90f7556 --- /dev/null +++ b/third_party/ijar/test/WellCompressed1.java @@ -0,0 +1,505 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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. + +/** + * For testing purposes: a class that can be really well compressed. + * + * This class should be at least one page (4K) longer when uncompressed than + * when compressed to trigger "ijar segmentation fault" bug. + */ +class WellCompressed1 { + private WellCompressed1() {} + public static final String DATA = " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " "; +} diff --git a/third_party/ijar/test/WellCompressed2.java b/third_party/ijar/test/WellCompressed2.java new file mode 100644 index 0000000000..ffb292f049 --- /dev/null +++ b/third_party/ijar/test/WellCompressed2.java @@ -0,0 +1,316 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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. + +public class WellCompressed2 { + public final static String DATA_001 = " " + + " " + + " "; + public final static String DATA_002 = " " + + " " + + " "; + public final static String DATA_003 = " " + + " " + + " "; + public final static String DATA_004 = " " + + " " + + " "; + public final static String DATA_005 = " " + + " " + + " "; + public final static String DATA_006 = " " + + " " + + " "; + public final static String DATA_007 = " " + + " " + + " "; + public final static String DATA_008 = " " + + " " + + " "; + public final static String DATA_009 = " " + + " " + + " "; + public final static String DATA_010 = " " + + " " + + " "; + public final static String DATA_011 = " " + + " " + + " "; + public final static String DATA_012 = " " + + " " + + " "; + public final static String DATA_013 = " " + + " " + + " "; + public final static String DATA_014 = " " + + " " + + " "; + public final static String DATA_015 = " " + + " " + + " "; + public final static String DATA_016 = " " + + " " + + " "; + public final static String DATA_017 = " " + + " " + + " "; + public final static String DATA_018 = " " + + " " + + " "; + public final static String DATA_019 = " " + + " " + + " "; + public final static String DATA_020 = " " + + " " + + " "; + public final static String DATA_021 = " " + + " " + + " "; + public final static String DATA_022 = " " + + " " + + " "; + public final static String DATA_023 = " " + + " " + + " "; + public final static String DATA_024 = " " + + " " + + " "; + public final static String DATA_025 = " " + + " " + + " "; + public final static String DATA_026 = " " + + " " + + " "; + public final static String DATA_027 = " " + + " " + + " "; + public final static String DATA_028 = " " + + " " + + " "; + public final static String DATA_029 = " " + + " " + + " "; + public final static String DATA_030 = " " + + " " + + " "; + public final static String DATA_031 = " " + + " " + + " "; + public final static String DATA_032 = " " + + " " + + " "; + public final static String DATA_033 = " " + + " " + + " "; + public final static String DATA_034 = " " + + " " + + " "; + public final static String DATA_035 = " " + + " " + + " "; + public final static String DATA_036 = " " + + " " + + " "; + public final static String DATA_037 = " " + + " " + + " "; + public final static String DATA_038 = " " + + " " + + " "; + public final static String DATA_039 = " " + + " " + + " "; + public final static String DATA_040 = " " + + " " + + " "; + public final static String DATA_041 = " " + + " " + + " "; + public final static String DATA_042 = " " + + " " + + " "; + public final static String DATA_043 = " " + + " " + + " "; + public final static String DATA_044 = " " + + " " + + " "; + public final static String DATA_045 = " " + + " " + + " "; + public final static String DATA_046 = " " + + " " + + " "; + public final static String DATA_047 = " " + + " " + + " "; + public final static String DATA_048 = " " + + " " + + " "; + public final static String DATA_049 = " " + + " " + + " "; + public final static String DATA_050 = " " + + " " + + " "; + public final static String DATA_051 = " " + + " " + + " "; + public final static String DATA_052 = " " + + " " + + " "; + public final static String DATA_053 = " " + + " " + + " "; + public final static String DATA_054 = " " + + " " + + " "; + public final static String DATA_055 = " " + + " " + + " "; + public final static String DATA_056 = " " + + " " + + " "; + public final static String DATA_057 = " " + + " " + + " "; + public final static String DATA_058 = " " + + " " + + " "; + public final static String DATA_059 = " " + + " " + + " "; + public final static String DATA_060 = " " + + " " + + " "; + public final static String DATA_061 = " " + + " " + + " "; + public final static String DATA_062 = " " + + " " + + " "; + public final static String DATA_063 = " " + + " " + + " "; + public final static String DATA_064 = " " + + " " + + " "; + public final static String DATA_065 = " " + + " " + + " "; + public final static String DATA_066 = " " + + " " + + " "; + public final static String DATA_067 = " " + + " " + + " "; + public final static String DATA_068 = " " + + " " + + " "; + public final static String DATA_069 = " " + + " " + + " "; + public final static String DATA_070 = " " + + " " + + " "; + public final static String DATA_071 = " " + + " " + + " "; + public final static String DATA_072 = " " + + " " + + " "; + public final static String DATA_073 = " " + + " " + + " "; + public final static String DATA_074 = " " + + " " + + " "; + public final static String DATA_075 = " " + + " " + + " "; + public final static String DATA_076 = " " + + " " + + " "; + public final static String DATA_077 = " " + + " " + + " "; + public final static String DATA_078 = " " + + " " + + " "; + public final static String DATA_079 = " " + + " " + + " "; + public final static String DATA_080 = " " + + " " + + " "; + public final static String DATA_081 = " " + + " " + + " "; + public final static String DATA_082 = " " + + " " + + " "; + public final static String DATA_083 = " " + + " " + + " "; + public final static String DATA_084 = " " + + " " + + " "; + public final static String DATA_085 = " " + + " " + + " "; + public final static String DATA_086 = " " + + " " + + " "; + public final static String DATA_087 = " " + + " " + + " "; + public final static String DATA_088 = " " + + " " + + " "; + public final static String DATA_089 = " " + + " " + + " "; + public final static String DATA_090 = " " + + " " + + " "; + public final static String DATA_091 = " " + + " " + + " "; + public final static String DATA_092 = " " + + " " + + " "; + public final static String DATA_093 = " " + + " " + + " "; + public final static String DATA_094 = " " + + " " + + " "; + public final static String DATA_095 = " " + + " " + + " "; + public final static String DATA_096 = " " + + " " + + " "; + public final static String DATA_097 = " " + + " " + + " "; + public final static String DATA_098 = " " + + " " + + " "; + public final static String DATA_099 = " " + + " " + + " "; + public final static String DATA_100 = " " + + " " + + " "; +} diff --git a/third_party/ijar/test/ijar_test.sh b/third_party/ijar/test/ijar_test.sh new file mode 100755 index 0000000000..9869969adf --- /dev/null +++ b/third_party/ijar/test/ijar_test.sh @@ -0,0 +1,417 @@ +#!/bin/bash -eu +# +# Copyright 2015 Google Inc. All rights reserved. +# 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 + +# TODO(bazel-team): this file is bloated, we should factor it. + +#### Inputs + +## TEST_TMPDIR +if [ -z "${TEST_TMPDIR:-}" ]; then + TEST_TMPDIR="$(mktemp -d ${TMPDIR:-/tmp}/ijar-test.XXXXXXXX)" + trap "rm -fr ${TEST_TMPDIR}" EXIT +fi + +## Mac OS X stat and MD5 +PLATFORM="$(uname -s | tr 'A-Z' 'a-z')" +if [[ "$PLATFORM" = "darwin" ]]; then + function statfmt() { + stat -f "%z" $1 + } + MD5SUM=/sbin/md5 +else + function statfmt() { + stat -c "%s" $1 + } + MD5SUM=md5sum +fi + +## Tools +JAVAC=$1 +JAVA=$2 +JAR=$3 +JAVAP=$4 +IJAR=$TEST_SRCDIR/$5 +LANGTOOLS8=$TEST_SRCDIR/$6 +UNZIP=$7 +ZIP=$8 + +IJAR_SRCDIR=$(dirname ${IJAR}) +A_JAR=$TEST_TMPDIR/A.jar +A_INTERFACE_JAR=$TEST_TMPDIR/A-interface.jar +A_ZIP_JAR=$TEST_TMPDIR/A_zip.jar +A_ZIP_INTERFACE_JAR=$TEST_TMPDIR/A_zip-interface.jar +W_JAR=$TEST_TMPDIR/W.jar +BOTTLES_JAR=$TEST_TMPDIR/bottles.jar +JAR_WRONG_CENTRAL_DIR=$IJAR_SRCDIR/test/libwrongcentraldir.jar +IJAR_WRONG_CENTRAL_DIR=$TEST_TMPDIR/wrongcentraldir_interface.jar +OBJECT_JAVA=$IJAR_SRCDIR/test/Object.java +OBJECT_JAR=$TEST_TMPDIR/object.jar +OBJECT_IJAR=$TEST_TMPDIR/object_interface.jar +TYPEANN2_JAR=$IJAR_SRCDIR/test/libtypeannotations2.jar +TYPEANN2_IJAR=$TEST_TMPDIR/typeannotations2_interface.jar +TYPEANN2_JAVA=$IJAR_SRCDIR/test/TypeAnnotationTest2.java +INVOKEDYNAMIC_JAR=$IJAR_SRCDIR/test/libinvokedynamic.jar +INVOKEDYNAMIC_IJAR=$TEST_TMPDIR/invokedynamic_interface.jar + +#### Testing framework +# Print message in "$1" then exit with status "$2" +die () { + # second argument is optional, defaulting to 1 + local status_code=${2:-1} + # Stop capturing stdout/stderr, and dump captured output + if [ "$CAPTURED_STD_ERR" -ne 0 ]; then + restore_outputs + cat "${TEST_TMPDIR}/captured.err" 1>&2 + fi + + if [ -n "${1-}" ] ; then + echo "$1" 1>&2 + fi + if [ x"$status_code" != x -a x"$status_code" != x"0" ]; then + exit "$status_code" + else + exit 1 + fi +} + +# Die if "$1" == "$2", print $3 as death reason +check_ne () { + if [ "$1" = "$2" ]; then + die "Check failed: '$1' != '$2' ${3:+ ($3)}" + fi +} + +# Die if "$1" != "$2", print $3 as death reason +check_eq () { + if [ ! "$1" = "$2" ]; then + die "Check failed: '$1' = '$2' ${3:+ ($3)}" + fi +} + +CAPTURED_STD_ERR="${CAPTURED_STD_ERR:-0}" + +capture_test_stderr () { + exec 6>&2 # Save stderr as fd 6 + exec 7>"${TEST_TMPDIR}/captured.err" + exec 2>&7 + CAPTURED_STD_ERR=1 +} + +restore_outputs () { + if [ "$CAPTURED_STD_ERR" -ne 0 ] ; then + exec 2>&6 + fi +} + +recapture_outputs () { + if [ "$CAPTURED_STD_ERR" -ne 0 ] ; then + exec 2>&7 + fi +} + +#### Setup + +# set_file_length FILE SIZE +# +# Sets the file size for FILE, truncating if necessary, creating a +# sparse file if possible, preserving original contents if they fit. +function set_file_length() { + perl -e 'open(FH, ">>$ARGV[0]") && truncate(FH, $ARGV[1]) or die $!' "$@" && + [[ "$(statfmt $1)" == "$2" ]] || + die "set_file_length failed" +} + +# grep_test_stderr STRING MESSAGE +# +# Greps the captured stderr text for STRING. If not found, fails with MESSAGE. +grep_test_stderr() { + restore_outputs + [ "$CAPTURED_STD_ERR" -ne 0 ] || \ + die "Must call capture_test_stderr before grep_test_stderr" + grep -c "$1" ${TEST_TMPDIR}/captured.err >/dev/null || \ + die "Check failed: grep -c '$1' ${TEST_TMPDIR}/captured.err ${2:+ ($2)}" + CAPTURED_STD_ERR=0 + recapture_outputs +} + +# check_consistent_file_contents FILE +# +# Checks that all files created with the given filename have identical contents. +expected_output="" +function check_consistent_file_contents() { + local actual="$(cat $1 | ${MD5SUM} | awk '{ print $1; }')" + local filename="$(echo $1 | ${MD5SUM} | awk '{ print $1; }')" + local expected="$actual" + if $(echo "${expected_output}" | grep -q "^${filename} "); then + echo "${expected_output}" | grep -q "^${filename} ${actual}$" || { + ls -l "$1" + die "output file contents differ" + } + else + expected_output="$expected_output$filename $actual +" + fi +} + +# Tests that ijar does not crash when output ijar is bigger than the input jar +rm -fr $TEST_TMPDIR/classes +mkdir -p $TEST_TMPDIR/classes || die "mkdir $TEST_TMPDIR/classes failed" +$JAVAC -g -d $TEST_TMPDIR/classes \ + $IJAR_SRCDIR/test/WellCompressed*.java || + die "javac failed" +$JAR cf $W_JAR -C $TEST_TMPDIR/classes . || die "jar failed" + +W_INTERFACE_JAR=$TEST_TMPDIR/W-interface.jar +$IJAR $W_JAR $W_INTERFACE_JAR || die "ijar failed" + +mkdir -p $TEST_TMPDIR/java/lang +cp $OBJECT_JAVA $TEST_TMPDIR/java/lang/. +$JAVAC $TEST_TMPDIR/java/lang/Object.java || die "javac failed" +$JAR cf $OBJECT_JAR -C $TEST_TMPDIR java/lang/Object.class || die "jar failed" + +# Tests that ijar can handle class bodies longer than 64K +rm -fr $TEST_TMPDIR/classes +mkdir -p $TEST_TMPDIR/classes || die "mkdir $TEST_TMPDIR/classes failed" +# First, generate the input file +BOTTLES_JAVA=$TEST_TMPDIR/BottlesOnTheWall.java +echo "public class BottlesOnTheWall {" > $BOTTLES_JAVA +for i in $(seq 1 16384); do + echo " public int getBottleOnTheWall${i}() { return ${i}; }" >> $BOTTLES_JAVA +done + +echo "}" >> $BOTTLES_JAVA + +$JAVAC -g -d $TEST_TMPDIR/classes $BOTTLES_JAVA || die "javac failed" +BOTTLES_INTERFACE_JAR=$TEST_TMPDIR/bottles-interface.jar + +for flag0 in '' '0'; do + $JAR c"${flag0}"f $BOTTLES_JAR -C $TEST_TMPDIR/classes . || die "jar failed" + $IJAR $BOTTLES_JAR $BOTTLES_INTERFACE_JAR || die "ijar failed" + check_consistent_file_contents $BOTTLES_INTERFACE_JAR +done + +# Compiles A.java, builds A.jar and A-interface.jar +rm -fr $TEST_TMPDIR/classes +mkdir -p $TEST_TMPDIR/classes || die "mkdir $TEST_TMPDIR/classes failed" +$JAVAC -g -d $TEST_TMPDIR/classes $IJAR_SRCDIR/test/A.java || + die "javac failed" + +for flag0 in '' '0'; do +# Ensure input files larger than INITIAL_BUFFER_SIZE work. +# TODO(martinrb): remove maximum .class file size limit (MAX_BUFFER_SIZE) +for size in '' $((1024*1024)) $((15*1024*1024)); do + if [[ -n "$size" ]]; then + for file in $(find $TEST_TMPDIR/classes -name '*.class'); do + set_file_length "$file" "$size" + done + fi + $JAR c"${flag0}"f $A_JAR -C $TEST_TMPDIR/classes . || die "jar failed" + $IJAR $A_JAR $A_INTERFACE_JAR || die "ijar failed." + check_consistent_file_contents $A_INTERFACE_JAR + done +done + +# Creates a huge (3Gb) input jar to test "large file" correctness +set_file_length $TEST_TMPDIR/zeroes.data $((3*1024*1024*1024)) +for flag0 in '' '0'; do + $JAR c"${flag0}"f $A_JAR -C $TEST_TMPDIR zeroes.data -C $TEST_TMPDIR/classes . || die "jar failed" + $IJAR $A_JAR $A_INTERFACE_JAR || die "ijar failed." + check_consistent_file_contents $A_INTERFACE_JAR +done + +# Create an output jar with upper bound on size > 2GB +DIR=$TEST_TMPDIR/ManyLargeClasses +mkdir -p $DIR/classes +for i in $(seq 200); do + printf "class C${i} {}\n" > $DIR/C${i}.java +done +([[ "$JAVAC" =~ ^/ ]] || JAVAC="$PWD/$JAVAC"; cd $DIR && $JAVAC -d classes *.java) +for i in $(seq 200); do + set_file_length $DIR/classes/C${i}.class $((15*1024*1024)) +done +$JAR cf $DIR/ManyLargeClasses.jar -C $DIR/classes . || die "jar failed" +$IJAR $DIR/ManyLargeClasses.jar $DIR/ManyLargeClasses.ijar || die "ijar failed." + +#### Checks + +# Check that ijar can produce class files with a body longer than 64K by +# calling ijar itself on the output file to make sure that it is valid +BOTTLES_INTERFACE_INTERFACE_JAR=$TEST_TMPDIR/bottles-interface-interface.jar +$IJAR $BOTTLES_INTERFACE_JAR $BOTTLES_INTERFACE_INTERFACE_JAR || + die "ijar cannot produce class files with body longer than 64K" + +# Check that the interface jar is bigger than the original jar. +W_JAR_SIZE=$(statfmt $W_JAR) +W_INTERFACE_JAR_SIZE=$(statfmt $W_INTERFACE_JAR) +[[ $W_INTERFACE_JAR_SIZE -gt $W_JAR_SIZE ]] || die "interface jar should be bigger" + +# Check that the number of entries is 5: +# A, A.PrivateInner, A.PublicInner, A.MyAnnotation, +# A.RuntimeAnnotation +# (Note: even private inner classes are retained, so we don't need to change +# the types of members.) +lines=$($JAR tvf $A_INTERFACE_JAR | wc -l) +expected=5 +check_eq $expected $lines "Interface jar should have $expected entries!" + + +# Check that no private class members are found: +lines=$($JAVAP -private -classpath $A_JAR A | grep priv | wc -l) +check_eq 2 $lines "Input jar should have 2 private members!" +lines=$($JAVAP -private -classpath $A_INTERFACE_JAR A | grep priv | wc -l) +check_eq 0 $lines "Interface jar should have no private members!" +lines=$($JAVAP -private -classpath $A_INTERFACE_JAR A | grep clinit | wc -l) +check_eq 0 $lines "Interface jar should have no class initializers!" + + +# Check that no code is found: +lines=$($JAVAP -c -private -classpath $A_JAR A | grep Code: | wc -l) +check_eq 5 $lines "Input jar should have 5 method bodies!" +lines=$($JAVAP -c -private -classpath $A_INTERFACE_JAR A | grep Code: | wc -l) +check_eq 0 $lines "Interface jar should have no method bodies!" + + +# Check that constants from code are no longer present: +$JAVAP -c -private -classpath $A_JAR A | grep -sq foofoofoofoo || + die "Input jar should have code constants!" +$JAVAP -c -private -classpath $A_INTERFACE_JAR A | grep -sq foofoofoofoo && + die "Interface jar should have no code constants!" + + +# Check (important, this!) that the interface jar is still sufficient +# for compiling: +$JAVAC -Xlint -classpath $A_INTERFACE_JAR -g -d $TEST_TMPDIR/classes \ + $IJAR_SRCDIR/test/B.java 2>$TEST_TMPDIR/B.javac.err || + { cat $TEST_TMPDIR/B.javac.err >&2; die "Can't compile B!"; } + + +# Test compilation of B yielded deprecation message: +grep -sq 'deprecatedMethod.*in A has been deprecated' \ + $TEST_TMPDIR/B.javac.err || die "ijar has lost @Deprecated annotation!" + + +# Check idempotence of ijar transformation: +A_INTERFACE_INTERFACE_JAR=$TEST_TMPDIR/A-interface-interface.jar +$IJAR $A_INTERFACE_JAR $A_INTERFACE_INTERFACE_JAR || die "ijar failed." +cmp $A_INTERFACE_JAR $A_INTERFACE_INTERFACE_JAR || + die "ijar transformation is not idempotent" + + +# Check that -interface.jar contains nothing but .class files: +check_eq 0 $($JAR tf $A_INTERFACE_JAR | grep -v \\.class$ | wc -l) \ + "Interface jar should contain only .class files!" + + +# Check that -interface.jar timestamps are all zeros: +check_eq 0 $(TZ=UTC $JAR tvf $A_INTERFACE_JAR | + grep -v 'Fri Nov 30 00:00:00 UTC 1979' | wc -l) \ + "Interface jar contained non-zero timestamps!" + + +# Check that compile-time constants in A are still annotated as such in ijar: +$JAVAP -classpath $TEST_TMPDIR/classes -c B | grep -sq ldc2_w.*123 || + die "ConstantValue not propagated to class B!" + +# Regression test for jar file without classes (javac doesn't like an empty ijar). +>$TEST_TMPDIR/empty +$ZIP $TEST_TMPDIR/noclasses.jar $TEST_TMPDIR/empty >/dev/null 2>&1 +$IJAR $TEST_TMPDIR/noclasses.jar || die "ijar failed" +$UNZIP -qql $TEST_TMPDIR/noclasses-interface.jar 2>/dev/null | grep -q . || + die "noclasses-interface.jar is completely empty!" + $JAVAC -classpath $TEST_TMPDIR/noclasses-interface.jar \ + -d $TEST_TMPDIR/classes \ + $IJAR_SRCDIR/test/A.java || + die "javac noclasses-interface.jar failed" +rm $TEST_TMPDIR/{empty,noclasses.jar,noclasses-interface.jar} + + +# Run the dynamic checks in B.main(). +$JAVA -classpath $TEST_TMPDIR/classes B || exit 1 + +# TODO(bazel-team) test that modifying the source in a non-interface +# changing way results in the same -interface.jar. + +# Check that a jar compressed with zip results in the same interface jar as a +# jar compressed with jar +rm -fr $TEST_TMPDIR/classes +mkdir -p $TEST_TMPDIR/classes || die "mkdir $TEST_TMPDIR/classes failed" +$JAVAC -g -d $TEST_TMPDIR/classes $IJAR_SRCDIR/test/A.java || + die "javac failed" +$JAR cf $A_JAR $TEST_TMPDIR/classes/A.class || die "jar failed" +$ZIP $A_ZIP_JAR $TEST_TMPDIR/classes/A.class || die "zip failed" + +$IJAR $A_JAR $A_INTERFACE_JAR || die "ijar failed" +$IJAR $A_ZIP_JAR $A_ZIP_INTERFACE_JAR || die "ijar failed" +cmp $A_INTERFACE_JAR $A_ZIP_INTERFACE_JAR || \ + die "ijars from jar and zip are different" + + +# Check that a JAR file can be parsed even if the central directory file count +# is wrong +$IJAR $JAR_WRONG_CENTRAL_DIR $IJAR_WRONG_CENTRAL_DIR || die "ijar failed" +IJAR_FILES=$($UNZIP -qql $IJAR_WRONG_CENTRAL_DIR | wc -l | xargs echo) +if [[ $IJAR_FILES != 2 ]]; then + die "ijar removed files" +fi + +# Check that constant pool references used by JSR308 type annotations are +# preserved +$IJAR $TYPEANN2_JAR $TYPEANN2_IJAR || die "ijar failed" +$JAVAP -classpath $TYPEANN2_IJAR -v Util | + grep -sq RuntimeVisibleTypeAnnotations || + die "RuntimeVisibleTypeAnnotations not preserved!" +set -x +cp $TYPEANN2_JAVA $TEST_TMPDIR/TypeAnnotationTest2.java +$JAVAC -J-Xbootclasspath/p:$LANGTOOLS8 $TEST_TMPDIR/TypeAnnotationTest2.java -cp $TYPEANN2_IJAR || + die "javac failed" +set +x + +# Check that ijar works on classes with invokedynamic +$IJAR $INVOKEDYNAMIC_JAR $INVOKEDYNAMIC_IJAR || die "ijar failed" +lines=$($JAVAP -c -private -classpath $INVOKEDYNAMIC_JAR ClassWithLambda | grep Code: | wc -l) +check_eq 4 $lines "Input jar should have 4 method bodies!" +lines=$($JAVAP -c -private -classpath $INVOKEDYNAMIC_IJAR ClassWithLambda | grep Code: | wc -l) +check_eq 0 $lines "Interface jar should have no method bodies!" + +# Check that Object.class can be processed +$IJAR $OBJECT_JAR $OBJECT_IJAR || die "ijar failed" + +# Check that the tool detects and reports a corrupted end of central directory +# record condition +CORRUPTED_JAR=$TEST_TMPDIR/corrupted.jar +# First make the jar one byte longer +cp $JAR_WRONG_CENTRAL_DIR $CORRUPTED_JAR +chmod +w $CORRUPTED_JAR +echo >> $CORRUPTED_JAR +set +e +capture_test_stderr +$IJAR $CORRUPTED_JAR && die "ijar should have failed" +status=$? +set -e +check_ne 0 $status +grep_test_stderr "missing end of central directory record" +restore_outputs +# Then make the jar one byte shorter than the original one +let "NEW_SIZE = `statfmt $CORRUPTED_JAR` - 2" +set_file_length $CORRUPTED_JAR $NEW_SIZE +set +e +capture_test_stderr +$IJAR $CORRUPTED_JAR && die "ijar should have failed" +status=$? +set -e +check_ne 0 $status +grep_test_stderr "missing end of central directory record" +restore_outputs + +echo "PASS" diff --git a/third_party/ijar/test/invokedynamic/ClassWithLambda.java b/third_party/ijar/test/invokedynamic/ClassWithLambda.java new file mode 100644 index 0000000000..f2f71059e4 --- /dev/null +++ b/third_party/ijar/test/invokedynamic/ClassWithLambda.java @@ -0,0 +1,31 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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. + +import java.util.function.Function; + +class ClassWithLambda { + interface Rec extends Function<Rec, Rec> {} + + private static final String HELLO = "Hello World"; + + int hash(Function<String, Integer> hashFunc) { + return hashFunc.apply(HELLO); + } + + void m() { + Rec f = x -> x.apply(x); + + int x = hash(String::hashCode); + } +} diff --git a/third_party/ijar/test/libwrongcentraldir.jar b/third_party/ijar/test/libwrongcentraldir.jar Binary files differnew file mode 100644 index 0000000000..0d86817afe --- /dev/null +++ b/third_party/ijar/test/libwrongcentraldir.jar diff --git a/third_party/ijar/test/package-info.java b/third_party/ijar/test/package-info.java new file mode 100644 index 0000000000..3e122fc5f1 --- /dev/null +++ b/third_party/ijar/test/package-info.java @@ -0,0 +1,15 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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. + +/** Empty package-info */
\ No newline at end of file diff --git a/third_party/ijar/test/typeannotations2/NonNull.java b/third_party/ijar/test/typeannotations2/NonNull.java new file mode 100644 index 0000000000..089e70c5e7 --- /dev/null +++ b/third_party/ijar/test/typeannotations2/NonNull.java @@ -0,0 +1,23 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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. + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE_USE, ElementType.TYPE_PARAMETER }) +public @interface NonNull { +} diff --git a/third_party/ijar/test/typeannotations2/Nullable.java b/third_party/ijar/test/typeannotations2/Nullable.java new file mode 100644 index 0000000000..2f341c00ad --- /dev/null +++ b/third_party/ijar/test/typeannotations2/Nullable.java @@ -0,0 +1,23 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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. + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE_USE, ElementType.TYPE_PARAMETER }) +public @interface Nullable { +} diff --git a/third_party/ijar/test/typeannotations2/Util.java b/third_party/ijar/test/typeannotations2/Util.java new file mode 100644 index 0000000000..baaff4d96a --- /dev/null +++ b/third_party/ijar/test/typeannotations2/Util.java @@ -0,0 +1,19 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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. + +public class Util { + public static <T extends @Nullable Object> @NonNull T castNullable(T value) { + return (@NonNull T) value; + } +} diff --git a/third_party/ijar/test/typeannotations2/java/lang/annotation/ElementType.java b/third_party/ijar/test/typeannotations2/java/lang/annotation/ElementType.java new file mode 100644 index 0000000000..001b8c707a --- /dev/null +++ b/third_party/ijar/test/typeannotations2/java/lang/annotation/ElementType.java @@ -0,0 +1,21 @@ +// Copyright 2015 Google Inc. All rights reserved. +// +// 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 java.lang.annotation; + +/** + * This is stub for the jdk8 ElementType. It allows the test to compile with a + * jdk7 javabase. + */ +public enum ElementType { TYPE_USE, TYPE_PARAMETER; } |