| // Copyright 2017 The Bazel Authors. 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 com.google.devtools.build.java.turbine.javac; |
| |
| import static com.google.common.collect.ImmutableList.toImmutableList; |
| import static com.google.common.truth.Truth.assertThat; |
| import static java.nio.charset.StandardCharsets.UTF_8; |
| |
| import com.google.common.io.ByteStreams; |
| import com.google.devtools.build.buildjar.jarhelper.JarCreator; |
| import com.google.devtools.build.java.turbine.javac.JavacTurbine.Result; |
| import com.google.turbine.options.TurbineOptions; |
| import java.io.BufferedWriter; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.io.OutputStreamWriter; |
| import java.io.PrintWriter; |
| import java.io.StringWriter; |
| import java.nio.file.Files; |
| import java.nio.file.Path; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Enumeration; |
| import java.util.LinkedHashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.jar.Attributes; |
| import java.util.jar.JarEntry; |
| import java.util.jar.JarFile; |
| import java.util.jar.JarOutputStream; |
| import java.util.jar.Manifest; |
| import org.junit.Before; |
| import org.junit.Rule; |
| import org.junit.rules.TemporaryFolder; |
| import org.objectweb.asm.ClassReader; |
| import org.objectweb.asm.util.Textifier; |
| import org.objectweb.asm.util.TraceClassVisitor; |
| |
| public abstract class AbstractJavacTurbineCompilationTest { |
| |
| @Rule public final TemporaryFolder temp = new TemporaryFolder(); |
| |
| Path sourcedir; |
| List<Path> sources; |
| Path output; |
| Path outputDeps; |
| |
| final TurbineOptions.Builder optionsBuilder = TurbineOptions.builder(); |
| |
| @Before |
| public void setUp() throws IOException { |
| sourcedir = temp.newFolder().toPath(); |
| output = temp.newFile("out.jar").toPath(); |
| outputDeps = temp.newFile("out.jdeps").toPath(); |
| |
| sources = new ArrayList<>(); |
| |
| optionsBuilder |
| .setOutput(output.toString()) |
| .setOutputDeps(outputDeps.toString()) |
| .addAllJavacOpts(Arrays.asList("-source", "8", "-target", "8")) |
| .setTargetLabel("//test"); |
| } |
| |
| protected void addSourceLines(String path, String... lines) throws IOException { |
| Path source = sourcedir.resolve(path); |
| sources.add(source); |
| Files.write(source, Arrays.asList(lines), UTF_8); |
| } |
| |
| protected void compile() throws IOException { |
| optionsBuilder.addSources(sources.stream().map(p -> p.toString()).collect(toImmutableList())); |
| try (JavacTurbine turbine = |
| new JavacTurbine( |
| new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.err, UTF_8))), |
| optionsBuilder.build())) { |
| assertThat(turbine.compile()) |
| .isAnyOf(Result.OK_WITH_FULL_CLASSPATH, Result.OK_WITH_REDUCED_CLASSPATH); |
| } |
| } |
| |
| protected Map<String, byte[]> collectOutputs() throws IOException { |
| return collectFiles(output); |
| } |
| |
| static Map<String, byte[]> collectFiles(Path jar) throws IOException { |
| Map<String, byte[]> files = new LinkedHashMap<>(); |
| try (JarFile jf = new JarFile(jar.toFile())) { |
| Enumeration<JarEntry> entries = jf.entries(); |
| while (entries.hasMoreElements()) { |
| JarEntry entry = entries.nextElement(); |
| files.put(entry.getName(), ByteStreams.toByteArray(jf.getInputStream(entry))); |
| } |
| } |
| return files; |
| } |
| |
| static String textify(byte[] bytes) { |
| StringWriter sw = new StringWriter(); |
| ClassReader cr = new ClassReader(bytes); |
| cr.accept(new TraceClassVisitor(null, new Textifier(), new PrintWriter(sw, true)), 0); |
| return sw.toString(); |
| } |
| |
| protected Path createClassJar(String jarName, Class<?>... classes) throws IOException { |
| Path jarPath = temp.newFile(jarName).toPath(); |
| Manifest manifest = new Manifest(); |
| manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); |
| manifest.getMainAttributes().put(JarCreator.TARGET_LABEL, "//" + jarName); |
| try (OutputStream os = Files.newOutputStream(jarPath); |
| JarOutputStream jos = new JarOutputStream(os, manifest)) { |
| for (Class<?> clazz : classes) { |
| String classFileName = clazz.getName().replace('.', '/') + ".class"; |
| jos.putNextEntry(new JarEntry(classFileName)); |
| try (InputStream is = getClass().getClassLoader().getResourceAsStream(classFileName)) { |
| ByteStreams.copy(is, jos); |
| } |
| } |
| } |
| return jarPath; |
| } |
| } |