Remove class2greylist from frameworks/base.
It's moving to a new home under art/tools, since it is needed by
branches which don't include frameworks/base.
Bug: 110868826
Test: Build master-art branch
Change-Id: Ice8324db52ae1e7e2ac6734e45874a66de935c9a
diff --git a/tools/hiddenapi/class2greylist/Android.bp b/tools/hiddenapi/class2greylist/Android.bp
deleted file mode 100644
index 7b1233b..0000000
--- a/tools/hiddenapi/class2greylist/Android.bp
+++ /dev/null
@@ -1,33 +0,0 @@
-//
-// Copyright (C) 2018 The Android Open Source Project
-//
-// 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.
-//
-
-java_library_host {
- name: "class2greylistlib",
- srcs: ["src/**/*.java"],
- static_libs: [
- "commons-cli-1.2",
- "apache-bcel",
- ],
-}
-
-java_binary_host {
- name: "class2greylist",
- manifest: "src/class2greylist.mf",
- static_libs: [
- "class2greylistlib",
- ],
-}
-
diff --git a/tools/hiddenapi/class2greylist/src/class2greylist.mf b/tools/hiddenapi/class2greylist/src/class2greylist.mf
deleted file mode 100644
index ea3a3d9..0000000
--- a/tools/hiddenapi/class2greylist/src/class2greylist.mf
+++ /dev/null
@@ -1 +0,0 @@
-Main-Class: com.android.class2greylist.Class2Greylist
diff --git a/tools/hiddenapi/class2greylist/src/com/android/class2greylist/AnnotationVisitor.java b/tools/hiddenapi/class2greylist/src/com/android/class2greylist/AnnotationVisitor.java
deleted file mode 100644
index 6685752..0000000
--- a/tools/hiddenapi/class2greylist/src/com/android/class2greylist/AnnotationVisitor.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * 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.android.class2greylist;
-
-import org.apache.bcel.Const;
-import org.apache.bcel.classfile.AnnotationEntry;
-import org.apache.bcel.classfile.DescendingVisitor;
-import org.apache.bcel.classfile.ElementValuePair;
-import org.apache.bcel.classfile.EmptyVisitor;
-import org.apache.bcel.classfile.Field;
-import org.apache.bcel.classfile.FieldOrMethod;
-import org.apache.bcel.classfile.JavaClass;
-import org.apache.bcel.classfile.Method;
-
-import java.util.Locale;
-
-/**
- * Visits a JavaClass instance and pulls out all members annotated with a
- * specific annotation. The signatures of such members are passed to {@link
- * Status#greylistEntry(String)}. Any errors result in a call to {@link
- * Status#error(String)}.
- *
- * If the annotation has a property "expectedSignature" the generated signature
- * will be verified against the one specified there. If it differs, an error
- * will be generated.
- */
-public class AnnotationVisitor extends EmptyVisitor {
-
- private static final String EXPECTED_SIGNATURE = "expectedSignature";
-
- private final JavaClass mClass;
- private final String mAnnotationType;
- private final Status mStatus;
- private final DescendingVisitor mDescendingVisitor;
-
- public AnnotationVisitor(JavaClass clazz, String annotation, Status d) {
- mClass = clazz;
- mAnnotationType = annotation;
- mStatus = d;
- mDescendingVisitor = new DescendingVisitor(clazz, this);
- }
-
- public void visit() {
- mStatus.debug("Visit class %s", mClass.getClassName());
- mDescendingVisitor.visit();
- }
-
- private static String getClassDescriptor(JavaClass clazz) {
- // JavaClass.getName() returns the Java-style name (with . not /), so we must fetch
- // the original class name from the constant pool.
- return clazz.getConstantPool().getConstantString(
- clazz.getClassNameIndex(), Const.CONSTANT_Class);
- }
-
- @Override
- public void visitMethod(Method method) {
- visitMember(method, "L%s;->%s%s");
- }
-
- @Override
- public void visitField(Field field) {
- visitMember(field, "L%s;->%s:%s");
- }
-
- private void visitMember(FieldOrMethod member, String signatureFormatString) {
- JavaClass definingClass = (JavaClass) mDescendingVisitor.predecessor();
- mStatus.debug("Visit member %s : %s", member.getName(), member.getSignature());
- for (AnnotationEntry a : member.getAnnotationEntries()) {
- if (mAnnotationType.equals(a.getAnnotationType())) {
- mStatus.debug("Method has annotation %s", mAnnotationType);
- String signature = String.format(Locale.US, signatureFormatString,
- getClassDescriptor(definingClass), member.getName(), member.getSignature());
- for (ElementValuePair property : a.getElementValuePairs()) {
- switch (property.getNameString()) {
- case EXPECTED_SIGNATURE:
- String expected = property.getValue().stringifyValue();
- if (!signature.equals(expected)) {
- error(definingClass, member,
- "Expected signature does not match generated:\n"
- + "Expected: %s\n"
- + "Generated: %s", expected, signature);
- }
- break;
- }
- }
- mStatus.greylistEntry(signature);
- }
- }
- }
-
- private void error(JavaClass clazz, FieldOrMethod member, String message, Object... args) {
- StringBuilder error = new StringBuilder();
- error.append(clazz.getSourceFileName())
- .append(": ")
- .append(clazz.getClassName())
- .append(".")
- .append(member.getName())
- .append(": ")
- .append(String.format(Locale.US, message, args));
-
- mStatus.error(error.toString());
- }
-
-}
diff --git a/tools/hiddenapi/class2greylist/src/com/android/class2greylist/Class2Greylist.java b/tools/hiddenapi/class2greylist/src/com/android/class2greylist/Class2Greylist.java
deleted file mode 100644
index 008bf70..0000000
--- a/tools/hiddenapi/class2greylist/src/com/android/class2greylist/Class2Greylist.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * 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.android.class2greylist;
-
-import org.apache.commons.cli.CommandLine;
-import org.apache.commons.cli.CommandLineParser;
-import org.apache.commons.cli.GnuParser;
-import org.apache.commons.cli.HelpFormatter;
-import org.apache.commons.cli.OptionBuilder;
-import org.apache.commons.cli.Options;
-import org.apache.commons.cli.ParseException;
-import org.apache.commons.cli.PatternOptionBuilder;
-
-import java.io.IOException;
-
-/**
- * Build time tool for extracting a list of members from jar files that have the @UsedByApps
- * annotation, for building the greylist.
- */
-public class Class2Greylist {
-
- private static final String ANNOTATION_TYPE = "Landroid/annotation/UnsupportedAppUsage ;";
-
- public static void main(String[] args) {
- Options options = new Options();
- options.addOption(OptionBuilder
- .withLongOpt("debug")
- .hasArgs(0)
- .withDescription("Enable debug")
- .create("d"));
- options.addOption(OptionBuilder
- .withLongOpt("help")
- .hasArgs(0)
- .withDescription("Show this help")
- .create("h"));
-
- CommandLineParser parser = new GnuParser();
- CommandLine cmd;
-
- try {
- cmd = parser.parse(options, args);
- } catch (ParseException e) {
- System.err.println(e.getMessage());
- help(options);
- return;
- }
- if (cmd.hasOption('h')) {
- help(options);
- }
-
- String[] jarFiles = cmd.getArgs();
- if (jarFiles.length == 0) {
- System.err.println("Error: no jar files specified.");
- help(options);
- }
-
- Status status = new Status(cmd.hasOption('d'));
-
- for (String jarFile : jarFiles) {
- status.debug("Processing jar file %s", jarFile);
- try {
- JarReader reader = new JarReader(status, jarFile);
- reader.stream().forEach(clazz -> new AnnotationVisitor(
- clazz, ANNOTATION_TYPE, status).visit());
- reader.close();
- } catch (IOException e) {
- status.error(e);
- }
- }
- if (status.ok()) {
- System.exit(0);
- } else {
- System.exit(1);
- }
-
- }
-
- private static void help(Options options) {
- new HelpFormatter().printHelp(
- "class2greylist path/to/classes.jar [classes2.jar ...]",
- "Extracts greylist entries from classes jar files given",
- options, null, true);
- System.exit(1);
- }
-}
diff --git a/tools/hiddenapi/class2greylist/src/com/android/class2greylist/JarReader.java b/tools/hiddenapi/class2greylist/src/com/android/class2greylist/JarReader.java
deleted file mode 100644
index f3a9d0b..0000000
--- a/tools/hiddenapi/class2greylist/src/com/android/class2greylist/JarReader.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * 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.android.class2greylist;
-
-import org.apache.bcel.classfile.ClassParser;
-import org.apache.bcel.classfile.JavaClass;
-
-import java.io.IOException;
-import java.util.Objects;
-import java.util.stream.Stream;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-/**
- * Reads {@link JavaClass} members from a zip/jar file, providing a stream of them for processing.
- * Any errors are reported via {@link Status#error(Throwable)}.
- */
-public class JarReader {
-
- private final Status mStatus;
- private final String mFileName;
- private final ZipFile mZipFile;
-
- public JarReader(Status s, String filename) throws IOException {
- mStatus = s;
- mFileName = filename;
- mZipFile = new ZipFile(mFileName);
- }
-
- private JavaClass openZipEntry(ZipEntry e) {
- try {
- mStatus.debug("Reading %s from %s", e.getName(), mFileName);
- return new ClassParser(mZipFile.getInputStream(e), e.getName()).parse();
- } catch (IOException ioe) {
- mStatus.error(ioe);
- return null;
- }
- }
-
-
- public Stream<JavaClass> stream() {
- return mZipFile.stream()
- .filter(zipEntry -> zipEntry.getName().endsWith(".class"))
- .map(zipEntry -> openZipEntry(zipEntry))
- .filter(Objects::nonNull);
- }
-
- public void close() throws IOException {
- mZipFile.close();
- }
-}
diff --git a/tools/hiddenapi/class2greylist/src/com/android/class2greylist/Status.java b/tools/hiddenapi/class2greylist/src/com/android/class2greylist/Status.java
deleted file mode 100644
index d707898..0000000
--- a/tools/hiddenapi/class2greylist/src/com/android/class2greylist/Status.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * 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.android.class2greylist;
-
-import java.util.Locale;
-
-public class Status {
-
- // Highlight "Error:" in red.
- private static final String ERROR = "\u001B[31mError: \u001B[0m";
-
- private final boolean mDebug;
- private boolean mHasErrors;
-
- public Status(boolean debug) {
- mDebug = debug;
- }
-
- public void debug(String msg, Object... args) {
- if (mDebug) {
- System.err.println(String.format(Locale.US, msg, args));
- }
- }
-
- public void error(Throwable t) {
- System.err.print(ERROR);
- t.printStackTrace(System.err);
- mHasErrors = true;
- }
-
- public void error(String message) {
- System.err.print(ERROR);
- System.err.println(message);
- mHasErrors = true;
- }
-
- public void greylistEntry(String signature) {
- System.out.println(signature);
- }
-
- public boolean ok() {
- return !mHasErrors;
- }
-}
diff --git a/tools/hiddenapi/class2greylist/test/Android.mk b/tools/hiddenapi/class2greylist/test/Android.mk
deleted file mode 100644
index 23f4156..0000000
--- a/tools/hiddenapi/class2greylist/test/Android.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2018 The Android Open Source Project
-#
-# 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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-# Only compile source java files in this apk.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_MODULE := class2greylisttest
-
-LOCAL_STATIC_JAVA_LIBRARIES := class2greylistlib truth-host-prebuilt mockito-host junit-host
-
-# tag this module as a cts test artifact
-LOCAL_COMPATIBILITY_SUITE := general-tests
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-# Build the test APKs using their own makefiles
-include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
diff --git a/tools/hiddenapi/class2greylist/test/AndroidTest.xml b/tools/hiddenapi/class2greylist/test/AndroidTest.xml
deleted file mode 100644
index 66bb6344..0000000
--- a/tools/hiddenapi/class2greylist/test/AndroidTest.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2018 The Android Open Source Project
-
- 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.
--->
-<configuration description="class2greylist tests">
- <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
- <option name="jar" value="class2greylisttest.jar" />
- <option name="runtime-hint" value="1m" />
- </test>
-</configuration>
\ No newline at end of file
diff --git a/tools/hiddenapi/class2greylist/test/src/com/android/javac/AnnotationVisitorTest.java b/tools/hiddenapi/class2greylist/test/src/com/android/javac/AnnotationVisitorTest.java
deleted file mode 100644
index 2d97218..0000000
--- a/tools/hiddenapi/class2greylist/test/src/com/android/javac/AnnotationVisitorTest.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * 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.android.javac;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.MockitoAnnotations.initMocks;
-
-import com.android.class2greylist.Status;
-import com.android.class2greylist.AnnotationVisitor;
-
-import com.google.common.base.Joiner;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-
-import java.io.IOException;
-
-public class AnnotationVisitorTest {
-
- private static final String ANNOTATION = "Lannotation/Anno;";
-
- private Javac mJavac;
- @Mock
- private Status mStatus;
-
- @Before
- public void setup() throws IOException {
- initMocks(this);
- mJavac = new Javac();
- mJavac.addSource("annotation.Anno", Joiner.on('\n').join(
- "package annotation;",
- "import static java.lang.annotation.RetentionPolicy.CLASS;",
- "import java.lang.annotation.Retention;",
- "import java.lang.annotation.Target;",
- "@Retention(CLASS)",
- "public @interface Anno {",
- " String expectedSignature() default \"\";",
- "}"));
- }
-
- private void assertNoErrors() {
- verify(mStatus, never()).error(any(Throwable.class));
- verify(mStatus, never()).error(any(String.class));
- }
-
- @Test
- public void testGreylistMethod() throws IOException {
- mJavac.addSource("a.b.Class", Joiner.on('\n').join(
- "package a.b;",
- "import annotation.Anno;",
- "public class Class {",
- " @Anno",
- " public void method() {}",
- "}"));
- assertThat(mJavac.compile()).isTrue();
-
- new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), ANNOTATION, mStatus)
- .visit();
-
- assertNoErrors();
- ArgumentCaptor<String> greylist = ArgumentCaptor.forClass(String.class);
- verify(mStatus, times(1)).greylistEntry(greylist.capture());
- assertThat(greylist.getValue()).isEqualTo("La/b/Class;->method()V");
- }
-
- @Test
- public void testGreylistConstructor() throws IOException {
- mJavac.addSource("a.b.Class", Joiner.on('\n').join(
- "package a.b;",
- "import annotation.Anno;",
- "public class Class {",
- " @Anno",
- " public Class() {}",
- "}"));
- assertThat(mJavac.compile()).isTrue();
-
- new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), ANNOTATION, mStatus)
- .visit();
-
- assertNoErrors();
- ArgumentCaptor<String> greylist = ArgumentCaptor.forClass(String.class);
- verify(mStatus, times(1)).greylistEntry(greylist.capture());
- assertThat(greylist.getValue()).isEqualTo("La/b/Class;-><init>()V");
- }
-
- @Test
- public void testGreylistField() throws IOException {
- mJavac.addSource("a.b.Class", Joiner.on('\n').join(
- "package a.b;",
- "import annotation.Anno;",
- "public class Class {",
- " @Anno",
- " public int i;",
- "}"));
- assertThat(mJavac.compile()).isTrue();
-
- new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), ANNOTATION, mStatus)
- .visit();
-
- assertNoErrors();
- ArgumentCaptor<String> greylist = ArgumentCaptor.forClass(String.class);
- verify(mStatus, times(1)).greylistEntry(greylist.capture());
- assertThat(greylist.getValue()).isEqualTo("La/b/Class;->i:I");
- }
-
- @Test
- public void testGreylistMethodExpectedSignature() throws IOException {
- mJavac.addSource("a.b.Class", Joiner.on('\n').join(
- "package a.b;",
- "import annotation.Anno;",
- "public class Class {",
- " @Anno(expectedSignature=\"La/b/Class;->method()V\")",
- " public void method() {}",
- "}"));
- assertThat(mJavac.compile()).isTrue();
-
- new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), ANNOTATION, mStatus)
- .visit();
-
- assertNoErrors();
- ArgumentCaptor<String> greylist = ArgumentCaptor.forClass(String.class);
- verify(mStatus, times(1)).greylistEntry(greylist.capture());
- assertThat(greylist.getValue()).isEqualTo("La/b/Class;->method()V");
- }
-
- @Test
- public void testGreylistMethodExpectedSignatureWrong() throws IOException {
- mJavac.addSource("a.b.Class", Joiner.on('\n').join(
- "package a.b;",
- "import annotation.Anno;",
- "public class Class {",
- " @Anno(expectedSignature=\"La/b/Class;->nomethod()V\")",
- " public void method() {}",
- "}"));
- assertThat(mJavac.compile()).isTrue();
-
- new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), ANNOTATION, mStatus)
- .visit();
-
- verify(mStatus, times(1)).error(any(String.class));
- }
-
- @Test
- public void testGreylistInnerClassMethod() throws IOException {
- mJavac.addSource("a.b.Class", Joiner.on('\n').join(
- "package a.b;",
- "import annotation.Anno;",
- "public class Class {",
- " public class Inner {",
- " @Anno",
- " public void method() {}",
- " }",
- "}"));
- assertThat(mJavac.compile()).isTrue();
-
- new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class$Inner"), ANNOTATION,
- mStatus).visit();
-
- assertNoErrors();
- ArgumentCaptor<String> greylist = ArgumentCaptor.forClass(String.class);
- verify(mStatus, times(1)).greylistEntry(greylist.capture());
- assertThat(greylist.getValue()).isEqualTo("La/b/Class$Inner;->method()V");
- }
-
- @Test
- public void testMethodNotGreylisted() throws IOException {
- mJavac.addSource("a.b.Class", Joiner.on('\n').join(
- "package a.b;",
- "public class Class {",
- " public void method() {}",
- "}"));
- assertThat(mJavac.compile()).isTrue();
-
- new AnnotationVisitor(mJavac.getCompiledClass("a.b.Class"), ANNOTATION, mStatus)
- .visit();
-
- assertNoErrors();
- verify(mStatus, never()).greylistEntry(any(String.class));
- }
-
-}
diff --git a/tools/hiddenapi/class2greylist/test/src/com/android/javac/Javac.java b/tools/hiddenapi/class2greylist/test/src/com/android/javac/Javac.java
deleted file mode 100644
index 202f412..0000000
--- a/tools/hiddenapi/class2greylist/test/src/com/android/javac/Javac.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * 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.android.javac;
-
-import com.google.common.io.Files;
-
-import org.apache.bcel.classfile.ClassParser;
-import org.apache.bcel.classfile.JavaClass;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Locale;
-
-import javax.tools.DiagnosticCollector;
-import javax.tools.JavaCompiler;
-import javax.tools.JavaFileObject;
-import javax.tools.SimpleJavaFileObject;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.StandardLocation;
-import javax.tools.ToolProvider;
-
-/**
- * Helper class for compiling snippets of Java source and providing access to the resulting class
- * files.
- */
-public class Javac {
-
- private final JavaCompiler mJavac;
- private final StandardJavaFileManager mFileMan;
- private final List<JavaFileObject> mCompilationUnits;
- private final File mClassOutDir;
-
- public Javac() throws IOException {
- mJavac = ToolProvider.getSystemJavaCompiler();
- mFileMan = mJavac.getStandardFileManager(null, Locale.US, null);
- mClassOutDir = Files.createTempDir();
- mFileMan.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(mClassOutDir));
- mFileMan.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(mClassOutDir));
- mCompilationUnits = new ArrayList<>();
- }
-
- private String classToFileName(String classname) {
- return classname.replace('.', '/');
- }
-
- public Javac addSource(String classname, String contents) {
- JavaFileObject java = new SimpleJavaFileObject(URI.create(
- String.format("string:///%s.java", classToFileName(classname))),
- JavaFileObject.Kind.SOURCE
- ){
- @Override
- public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
- return contents;
- }
- };
- mCompilationUnits.add(java);
- return this;
- }
-
- public boolean compile() {
- JavaCompiler.CompilationTask task = mJavac.getTask(
- null,
- mFileMan,
- null,
- null,
- null,
- mCompilationUnits);
- return task.call();
- }
-
- public InputStream getClassFile(String classname) throws IOException {
- Iterable<? extends JavaFileObject> objs = mFileMan.getJavaFileObjects(
- new File(mClassOutDir, String.format("%s.class", classToFileName(classname))));
- if (!objs.iterator().hasNext()) {
- return null;
- }
- return objs.iterator().next().openInputStream();
- }
-
- public JavaClass getCompiledClass(String classname) throws IOException {
- return new ClassParser(getClassFile(classname),
- String.format("%s.class", classToFileName(classname))).parse();
- }
-}