/* * Copyright 2016 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 com.google.errorprone.refaster; import static com.google.common.base.Preconditions.checkArgument; import com.google.common.collect.Iterables; import com.google.errorprone.InvalidCommandLineOptionException; import com.google.errorprone.MaskedClassLoader; import com.sun.tools.javac.api.MultiTaskListener; import com.sun.tools.javac.main.Main; import com.sun.tools.javac.main.Main.Result; import com.sun.tools.javac.util.Context; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.nio.file.FileSystems; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import javax.tools.DiagnosticCollector; import javax.tools.DiagnosticListener; import javax.tools.JavaFileObject; /** * A compiler for Refaster rules that outputs a {@code .analyzer} file containing a compiled * Refaster rule. * * @author lowasser@google.com */ public class RefasterRuleCompiler { /** * Entry point for compiling a Refaster rule to an analyzer. * * @param args the same args which could be passed to javac on the command line */ public static void main(String[] args) { new RefasterRuleCompiler().run(args, new Context()); } private Result run(String[] argv, Context context) { try { argv = prepareCompilation(argv, context); } catch (InvalidCommandLineOptionException e) { System.err.println(e.getMessage()); System.err.flush(); return Result.CMDERR; } try { Result compileResult = new Main( "RefasterRuleCompiler", new PrintWriter(new OutputStreamWriter(System.err, StandardCharsets.UTF_8))) .compile(argv, context); System.err.flush(); return compileResult; } catch (InvalidCommandLineOptionException e) { System.err.println(e.getMessage()); System.err.flush(); return Result.CMDERR; } } private String[] prepareCompilation(String[] argv, Context context) throws InvalidCommandLineOptionException { context.put(DiagnosticListener.class, new DiagnosticCollector<JavaFileObject>()); List<String> newArgs = new ArrayList<>(Arrays.asList(argv)); Iterator<String> itr = newArgs.iterator(); String path = null; while (itr.hasNext()) { if (itr.next().equals("--out")) { itr.remove(); path = itr.next(); itr.remove(); break; } } checkArgument(path != null, "No --out specified"); MaskedClassLoader.preRegisterFileManager(context); MultiTaskListener.instance(context) .add(new RefasterRuleCompilerAnalyzer(context, FileSystems.getDefault().getPath(path))); return Iterables.toArray(newArgs, String.class); } }