Skip to content

Commit

Permalink
Moved Eclipse-specific annotation support into jdt package, added pro…
Browse files Browse the repository at this point in the history
…cessAnnotations() to Parser, implemented javac annotation processing.

	Change on 2016/12/22 by tball <tball@google.com>

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=142780132
  • Loading branch information
tomball committed Dec 28, 2016
1 parent 83e257f commit f740d2f
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 39 deletions.
2 changes: 1 addition & 1 deletion translator/Makefile
Expand Up @@ -192,6 +192,7 @@ JAVA_SOURCES = \
javac/TreeConverter.java \ javac/TreeConverter.java \
jdt/AbstractBinding.java \ jdt/AbstractBinding.java \
jdt/AbstractTypeBinding.java \ jdt/AbstractTypeBinding.java \
jdt/AnnotationPreProcessor.java \
jdt/BindingConverter.java \ jdt/BindingConverter.java \
jdt/GeneratedMethodBinding.java \ jdt/GeneratedMethodBinding.java \
jdt/GeneratedPackageBinding.java \ jdt/GeneratedPackageBinding.java \
Expand Down Expand Up @@ -222,7 +223,6 @@ JAVA_SOURCES = \
jdt/JdtWildcardType.java \ jdt/JdtWildcardType.java \
jdt/StringName.java \ jdt/StringName.java \
jdt/TreeConverter.java \ jdt/TreeConverter.java \
pipeline/AnnotationPreProcessor.java \
pipeline/BuildClosureQueue.java \ pipeline/BuildClosureQueue.java \
pipeline/FileProcessor.java \ pipeline/FileProcessor.java \
pipeline/GenerationBatch.java \ pipeline/GenerationBatch.java \
Expand Down
Expand Up @@ -19,7 +19,6 @@
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.devtools.j2objc.Options.TimingLevel; import com.google.devtools.j2objc.Options.TimingLevel;
import com.google.devtools.j2objc.pipeline.AnnotationPreProcessor;
import com.google.devtools.j2objc.pipeline.GenerationBatch; import com.google.devtools.j2objc.pipeline.GenerationBatch;
import com.google.devtools.j2objc.pipeline.InputFilePreprocessor; import com.google.devtools.j2objc.pipeline.InputFilePreprocessor;
import com.google.devtools.j2objc.pipeline.ProcessingContext; import com.google.devtools.j2objc.pipeline.ProcessingContext;
Expand Down Expand Up @@ -101,10 +100,10 @@ public static void run(List<String> fileArgs, Options options) {
return; return;
} }


AnnotationPreProcessor preProcessor = new AnnotationPreProcessor(options); Parser.ProcessingResult processingResult = parser.processAnnotations(fileArgs, inputs);
List<ProcessingContext> generatedInputs = preProcessor.process(fileArgs, inputs); List<ProcessingContext> generatedInputs = processingResult.getGeneratedSources();
inputs.addAll(generatedInputs); // Ensure all generatedInputs are at end of input list. inputs.addAll(generatedInputs); // Ensure all generatedInputs are at end of input list.
preProcessorTempDir = preProcessor.getTemporaryDirectory(); preProcessorTempDir = processingResult.getSourceOutputDirectory();
if (ErrorUtil.errorCount() > 0) { if (ErrorUtil.errorCount() > 0) {
return; return;
} }
Expand Down
Expand Up @@ -25,6 +25,8 @@
import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Names; import com.sun.tools.javac.util.Names;
import java.io.Closeable;
import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
Expand All @@ -35,7 +37,7 @@
import javax.tools.DiagnosticCollector; import javax.tools.DiagnosticCollector;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;


class JavacEnvironment implements ParserEnvironment { class JavacEnvironment implements ParserEnvironment, Closeable {


private final JavacTaskImpl task; private final JavacTaskImpl task;
private final JavacFileManager fileManager; private final JavacFileManager fileManager;
Expand Down Expand Up @@ -137,4 +139,9 @@ public JavacFileManager fileManager() {
public DiagnosticCollector<JavaFileObject> diagnostics() { public DiagnosticCollector<JavaFileObject> diagnostics() {
return diagnostics; return diagnostics;
} }

@Override
public void close() throws IOException {
fileManager.close();
}
} }
Expand Up @@ -19,9 +19,12 @@
import com.google.devtools.j2objc.Options; import com.google.devtools.j2objc.Options;
import com.google.devtools.j2objc.ast.CompilationUnit; import com.google.devtools.j2objc.ast.CompilationUnit;
import com.google.devtools.j2objc.file.InputFile; import com.google.devtools.j2objc.file.InputFile;
import com.google.devtools.j2objc.file.RegularInputFile;
import com.google.devtools.j2objc.pipeline.ProcessingContext;
import com.google.devtools.j2objc.util.ErrorUtil; import com.google.devtools.j2objc.util.ErrorUtil;
import com.google.devtools.j2objc.util.FileUtil; import com.google.devtools.j2objc.util.FileUtil;
import com.google.devtools.j2objc.util.Parser; import com.google.devtools.j2objc.util.Parser;
import com.google.devtools.j2objc.util.PathClassLoader;
import com.google.devtools.j2objc.util.SourceVersion; import com.google.devtools.j2objc.util.SourceVersion;
import com.sun.source.tree.CompilationUnitTree; import com.sun.source.tree.CompilationUnitTree;
import com.sun.tools.javac.api.JavacTaskImpl; import com.sun.tools.javac.api.JavacTaskImpl;
Expand All @@ -32,7 +35,11 @@
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.ServiceLoader;
import javax.annotation.processing.Processor;
import javax.tools.Diagnostic; import javax.tools.Diagnostic;
import javax.tools.Diagnostic.Kind; import javax.tools.Diagnostic.Kind;
import javax.tools.DiagnosticCollector; import javax.tools.DiagnosticCollector;
Expand Down Expand Up @@ -72,8 +79,7 @@ public CompilationUnit parse(InputFile file) {


@Override @Override
public CompilationUnit parse(String mainType, String path, String source) { public CompilationUnit parse(String mainType, String path, String source) {
try { try (JavacEnvironment parserEnv = createEnvironment(path, source)) {
JavacEnvironment parserEnv = createEnvironment(path, source);
JavacTaskImpl task = parserEnv.task(); JavacTaskImpl task = parserEnv.task();
JCTree.JCCompilationUnit unit = (JCTree.JCCompilationUnit) task.parse().iterator().next(); JCTree.JCCompilationUnit unit = (JCTree.JCCompilationUnit) task.parse().iterator().next();
task.analyze(); task.analyze();
Expand All @@ -85,17 +91,6 @@ public CompilationUnit parse(String mainType, String path, String source) {
return null; return null;
} }


private JavacEnvironment createEnvironment(String path, String source) throws IOException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
JavacFileManager fileManager = getFileManager(compiler, diagnostics);
List<JavaFileObject> inputFiles = new ArrayList<>();
inputFiles.add(MemoryFileObject.createJavaFile(path, source));
JavacTaskImpl task = (JavacTaskImpl) compiler.getTask(
null, fileManager, diagnostics, getJavacOptions(), null, inputFiles);
return new JavacEnvironment(task, fileManager, diagnostics);
}

private JavacFileManager getFileManager(JavaCompiler compiler, private JavacFileManager getFileManager(JavaCompiler compiler,
DiagnosticCollector<JavaFileObject> diagnostics) throws IOException { DiagnosticCollector<JavaFileObject> diagnostics) throws IOException {
JavacFileManager fileManager = (JavacFileManager) JavacFileManager fileManager = (JavacFileManager)
Expand All @@ -118,7 +113,7 @@ private void addPaths(Location location, List<String> paths, JavacFileManager fi
fileManager.setLocation(location, filePaths); fileManager.setLocation(location, filePaths);
} }


private List<String> getJavacOptions() { private List<String> getJavacOptions(boolean processAnnotations) {
List<String> javacOptions = new ArrayList<>(); List<String> javacOptions = new ArrayList<>();
String encoding = options.fileUtil().getFileEncoding(); String encoding = options.fileUtil().getFileEncoding();


Expand All @@ -138,7 +133,11 @@ private List<String> getJavacOptions() {
if (lintArgument != null) { if (lintArgument != null) {
javacOptions.add(lintArgument); javacOptions.add(lintArgument);
} }
javacOptions.add("-proc:none"); if (processAnnotations) {
javacOptions.add("-proc:only");
} else {
javacOptions.add("-proc:none");
}


// TODO(tball): this should be in the FileManager, but adding it there // TODO(tball): this should be in the FileManager, but adding it there
// causes annotations to be processed twice, causing a "duplicate unit" // causes annotations to be processed twice, causing a "duplicate unit"
Expand All @@ -160,29 +159,18 @@ public void parseFiles(Collection<String> paths, Handler handler, SourceVersion
for (String path : paths) { for (String path : paths) {
files.add(new File(path)); files.add(new File(path));
} }

try (JavacEnvironment env = createEnvironment(files, null, false)) {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
try (JavacFileManager fileManager = getFileManager(compiler, diagnostics)) {
List<String> javacOptions = getJavacOptions();

Iterable<? extends JavaFileObject> fileObjects = fileManager
.getJavaFileObjectsFromFiles(files);
JavacTaskImpl task = (JavacTaskImpl) compiler.getTask(null, fileManager, diagnostics,
javacOptions, null, fileObjects);
JavacEnvironment env = new JavacEnvironment(task, fileManager, diagnostics);

List<CompilationUnitTree> units = new ArrayList<>(); List<CompilationUnitTree> units = new ArrayList<>();
try { try {
for (CompilationUnitTree unit : task.parse()) { for (CompilationUnitTree unit : env.task().parse()) {
units.add(unit); units.add(unit);
} }
task.analyze(); env.task().analyze();
} catch (IOException e) { } catch (IOException e) {
// Error listener will report errors. // Error listener will report errors.
} }


processDiagnostics(diagnostics); processDiagnostics(env.diagnostics());
if (ErrorUtil.errorCount() == 0) { if (ErrorUtil.errorCount() == 0) {
for (CompilationUnitTree ast : units) { for (CompilationUnitTree ast : units) {
com.google.devtools.j2objc.ast.CompilationUnit unit = TreeConverter com.google.devtools.j2objc.ast.CompilationUnit unit = TreeConverter
Expand All @@ -195,6 +183,31 @@ public void parseFiles(Collection<String> paths, Handler handler, SourceVersion
} }
} }


// Creates a javac environment from a memory source.
private JavacEnvironment createEnvironment(String path, String source) throws IOException {
List<JavaFileObject> inputFiles = new ArrayList<>();
inputFiles.add(MemoryFileObject.createJavaFile(path, source));
return createEnvironment(Collections.emptyList(), inputFiles, false);
}

// Creates a javac environment from a collection of files and/or file objects.
private JavacEnvironment createEnvironment(List<File> files, List<JavaFileObject> fileObjects,
boolean processAnnotations) throws IOException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
JavacFileManager fileManager = getFileManager(compiler, diagnostics);
List<String> javacOptions = getJavacOptions(processAnnotations);
if (fileObjects == null) {
fileObjects = new ArrayList<>();
}
for (JavaFileObject jfo : fileManager.getJavaFileObjectsFromFiles(files)) {
fileObjects.add(jfo);
}
JavacTaskImpl task = (JavacTaskImpl) compiler.getTask(null, fileManager, diagnostics,
javacOptions, null, fileObjects);
return new JavacEnvironment(task, fileManager, diagnostics);
}

private void processDiagnostics(DiagnosticCollector<JavaFileObject> diagnostics) { private void processDiagnostics(DiagnosticCollector<JavaFileObject> diagnostics) {
for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) { for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) {
Kind kind = diagnostic.getKind(); Kind kind = diagnostic.getKind();
Expand Down Expand Up @@ -224,6 +237,60 @@ public Parser.ParseResult parseWithoutBindings(InputFile file, String source) {
} }




@Override
public ProcessingResult processAnnotations(Iterable<String> fileArgs,
List<ProcessingContext> inputs) {
final List<ProcessingContext> generatedInputs = Lists.newArrayList();
PathClassLoader loader = new PathClassLoader(options.fileUtil().getClassPathEntries());
loader.addPaths(options.getProcessorPathEntries());
Iterator<Processor> serviceIterator = ServiceLoader.load(Processor.class, loader).iterator();
if (serviceIterator.hasNext()) {
List<File> inputFiles = new ArrayList<>();
for (ProcessingContext input : inputs) {
inputFiles.add(new File(input.getFile().getPath()));
}
try (JavacEnvironment env = createEnvironment(inputFiles, null, true)) {
List<CompilationUnitTree> units = new ArrayList<>();
try {
for (CompilationUnitTree unit : env.task().parse()) {
units.add(unit);
}
// JavacTaskImpl.enter() parses and runs annotation processing, but
// not type checking and attribution (that's done by analyze()).
env.task().enter();
} catch (IOException e) {
// Error listener will report errors.
}
processDiagnostics(env.diagnostics());
// The source output directory is created and set in createEnvironment().
File sourceOutputDirectory =
env.fileManager().getLocation(StandardLocation.SOURCE_OUTPUT).iterator().next();
collectGeneratedInputs(sourceOutputDirectory, "", generatedInputs);
return new JavacProcessingResult(generatedInputs, sourceOutputDirectory);
} catch (IOException e) {
ErrorUtil.fatalError(e, "javac file manager error");
}
}
// No annotation processors on classpath, or processing errors reported.
return new JavacProcessingResult(generatedInputs, null);
}

private void collectGeneratedInputs(
File dir, String currentRelativePath, List<ProcessingContext> inputs) {
assert dir.exists() && dir.isDirectory();
for (File f : dir.listFiles()) {
String relativeName = currentRelativePath + File.separatorChar + f.getName();
if (f.isDirectory()) {
collectGeneratedInputs(f, relativeName, inputs);
} else {
if (f.getName().endsWith(".java")) {
inputs.add(ProcessingContext.fromFile(
new RegularInputFile(f.getPath(), relativeName), options));
}
}
}
}

private static class JavacParseResult implements Parser.ParseResult { private static class JavacParseResult implements Parser.ParseResult {
private final InputFile file; private final InputFile file;
private String source; private String source;
Expand Down Expand Up @@ -260,4 +327,26 @@ public String toString() {
return unit.toString(); return unit.toString();
} }
} }

private static class JavacProcessingResult implements Parser.ProcessingResult {
private final List<ProcessingContext> generatedSources;
private final File sourceOutputDirectory;

public JavacProcessingResult(List<ProcessingContext> generatedSources,
File sourceOutputDirectory) {
this.generatedSources = generatedSources;
this.sourceOutputDirectory = sourceOutputDirectory;
}

@Override
public List<ProcessingContext> getGeneratedSources() {
return generatedSources;
}

@Override
public File getSourceOutputDirectory() {
return sourceOutputDirectory;
}

}
} }
Expand Up @@ -12,14 +12,15 @@
* limitations under the License. * limitations under the License.
*/ */


package com.google.devtools.j2objc.pipeline; package com.google.devtools.j2objc.jdt;


import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.devtools.j2objc.Options; import com.google.devtools.j2objc.Options;
import com.google.devtools.j2objc.file.RegularInputFile; import com.google.devtools.j2objc.file.RegularInputFile;
import com.google.devtools.j2objc.gen.GenerationUnit; import com.google.devtools.j2objc.gen.GenerationUnit;
import com.google.devtools.j2objc.pipeline.ProcessingContext;
import com.google.devtools.j2objc.util.ErrorUtil; import com.google.devtools.j2objc.util.ErrorUtil;
import com.google.devtools.j2objc.util.FileUtil; import com.google.devtools.j2objc.util.FileUtil;
import com.google.devtools.j2objc.util.PathClassLoader; import com.google.devtools.j2objc.util.PathClassLoader;
Expand Down Expand Up @@ -48,8 +49,7 @@
* and adds any .java files generated by those annotation processors * and adds any .java files generated by those annotation processors
* to the given GenerationBatch. * to the given GenerationBatch.
*/ */
public class AnnotationPreProcessor { class AnnotationPreProcessor {
// TODO(tball): remove class when javac conversion is finished.


private File tmpDirectory; private File tmpDirectory;
private final List<ProcessingContext> generatedInputs = Lists.newArrayList(); private final List<ProcessingContext> generatedInputs = Lists.newArrayList();
Expand Down
Expand Up @@ -19,6 +19,7 @@
import com.google.devtools.j2objc.Options.LintOption; import com.google.devtools.j2objc.Options.LintOption;
import com.google.devtools.j2objc.file.InputFile; import com.google.devtools.j2objc.file.InputFile;
import com.google.devtools.j2objc.file.RegularInputFile; import com.google.devtools.j2objc.file.RegularInputFile;
import com.google.devtools.j2objc.pipeline.ProcessingContext;
import com.google.devtools.j2objc.util.ErrorUtil; import com.google.devtools.j2objc.util.ErrorUtil;
import com.google.devtools.j2objc.util.FileUtil; import com.google.devtools.j2objc.util.FileUtil;
import com.google.devtools.j2objc.util.Parser; import com.google.devtools.j2objc.util.Parser;
Expand Down Expand Up @@ -190,6 +191,24 @@ public void acceptAST(String sourceFilePath, CompilationUnit ast) {
parser.createASTs(pathsArray, getEncodings(pathsArray.length), pathsArray, astRequestor, null); parser.createASTs(pathsArray, getEncodings(pathsArray.length), pathsArray, astRequestor, null);
} }


@Override
public ProcessingResult processAnnotations(Iterable<String> fileArgs,
List<ProcessingContext> inputs) {
AnnotationPreProcessor preProcessor = new AnnotationPreProcessor(options);
final List<ProcessingContext> generatedInputs = preProcessor.process(fileArgs, inputs);
return new Parser.ProcessingResult() {
@Override
public File getSourceOutputDirectory() {
return preProcessor.getTemporaryDirectory();
}

@Override
public List<ProcessingContext> getGeneratedSources() {
return generatedInputs;
}
};
}

@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
private ASTParser newASTParser(boolean resolveBindings, SourceVersion sourceVersion) { private ASTParser newASTParser(boolean resolveBindings, SourceVersion sourceVersion) {
ASTParser parser; ASTParser parser;
Expand Down

0 comments on commit f740d2f

Please sign in to comment.