JavacTool.java revision 2837:1e3266d870d6
1/* 2 * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.tools.javac.api; 27 28import java.io.InputStream; 29import java.io.OutputStream; 30import java.io.OutputStreamWriter; 31import java.io.PrintWriter; 32import java.io.Writer; 33import java.nio.charset.Charset; 34import java.util.Collections; 35import java.util.EnumSet; 36import java.util.Locale; 37import java.util.Objects; 38import java.util.Set; 39 40import javax.lang.model.SourceVersion; 41import javax.tools.*; 42 43import com.sun.source.util.JavacTask; 44import com.sun.tools.javac.file.JavacFileManager; 45import com.sun.tools.javac.main.Arguments; 46import com.sun.tools.javac.main.Option; 47import com.sun.tools.javac.util.BaseFileManager; 48import com.sun.tools.javac.util.ClientCodeException; 49import com.sun.tools.javac.util.Context; 50import com.sun.tools.javac.util.DefinedBy; 51import com.sun.tools.javac.util.DefinedBy.Api; 52import com.sun.tools.javac.util.Log; 53import com.sun.tools.javac.util.PropagatedException; 54 55/** 56 * TODO: describe com.sun.tools.javac.api.Tool 57 * 58 * <p><b>This is NOT part of any supported API. 59 * If you write code that depends on this, you do so at your own 60 * risk. This code and its internal interfaces are subject to change 61 * or deletion without notice.</b></p> 62 * 63 * @author Peter von der Ah\u00e9 64 */ 65public final class JavacTool implements JavaCompiler { 66 /** 67 * Constructor used by service provider mechanism. The recommended way to 68 * obtain an instance of this class is by using {@link #create} or the 69 * service provider mechanism. 70 * @see javax.tools.JavaCompiler 71 * @see javax.tools.ToolProvider 72 * @see #create 73 */ 74 @Deprecated 75 public JavacTool() {} 76 77 /** 78 * Static factory method for creating new instances of this tool. 79 * @return new instance of this tool 80 */ 81 public static JavacTool create() { 82 return new JavacTool(); 83 } 84 85 @Override @DefinedBy(Api.COMPILER) 86 public JavacFileManager getStandardFileManager( 87 DiagnosticListener<? super JavaFileObject> diagnosticListener, 88 Locale locale, 89 Charset charset) { 90 Context context = new Context(); 91 context.put(Locale.class, locale); 92 if (diagnosticListener != null) 93 context.put(DiagnosticListener.class, diagnosticListener); 94 PrintWriter pw = (charset == null) 95 ? new PrintWriter(System.err, true) 96 : new PrintWriter(new OutputStreamWriter(System.err, charset), true); 97 context.put(Log.outKey, pw); 98 return new JavacFileManager(context, true, charset); 99 } 100 101 @Override @DefinedBy(Api.COMPILER) 102 public JavacTask getTask(Writer out, 103 JavaFileManager fileManager, 104 DiagnosticListener<? super JavaFileObject> diagnosticListener, 105 Iterable<String> options, 106 Iterable<String> classes, 107 Iterable<? extends JavaFileObject> compilationUnits) { 108 Context context = new Context(); 109 return getTask(out, fileManager, diagnosticListener, 110 options, classes, compilationUnits, 111 context); 112 } 113 114 /* Internal version of getTask, allowing context to be provided. */ 115 public JavacTask getTask(Writer out, 116 JavaFileManager fileManager, 117 DiagnosticListener<? super JavaFileObject> diagnosticListener, 118 Iterable<String> options, 119 Iterable<String> classes, 120 Iterable<? extends JavaFileObject> compilationUnits, 121 Context context) 122 { 123 try { 124 ClientCodeWrapper ccw = ClientCodeWrapper.instance(context); 125 126 if (options != null) { 127 for (String option : options) 128 Objects.requireNonNull(option); 129 } 130 131 if (classes != null) { 132 for (String cls : classes) 133 if (!SourceVersion.isName(cls)) // implicit null check 134 throw new IllegalArgumentException("Not a valid class name: " + cls); 135 } 136 137 if (compilationUnits != null) { 138 compilationUnits = ccw.wrapJavaFileObjects(compilationUnits); // implicit null check 139 for (JavaFileObject cu : compilationUnits) { 140 if (cu.getKind() != JavaFileObject.Kind.SOURCE) { 141 String kindMsg = "Compilation unit is not of SOURCE kind: " 142 + "\"" + cu.getName() + "\""; 143 throw new IllegalArgumentException(kindMsg); 144 } 145 } 146 } 147 148 if (diagnosticListener != null) 149 context.put(DiagnosticListener.class, ccw.wrap(diagnosticListener)); 150 151 if (out == null) 152 context.put(Log.outKey, new PrintWriter(System.err, true)); 153 else 154 context.put(Log.outKey, new PrintWriter(out, true)); 155 156 if (fileManager == null) { 157 fileManager = getStandardFileManager(diagnosticListener, null, null); 158 if (fileManager instanceof BaseFileManager) { 159 ((BaseFileManager) fileManager).autoClose = true; 160 } 161 } 162 fileManager = ccw.wrap(fileManager); 163 164 context.put(JavaFileManager.class, fileManager); 165 166 Arguments args = Arguments.instance(context); 167 args.init("javac", options, classes, compilationUnits); 168 return new JavacTaskImpl(context); 169 } catch (PropagatedException ex) { 170 throw ex.getCause(); 171 } catch (ClientCodeException ex) { 172 throw new RuntimeException(ex.getCause()); 173 } 174 } 175 176 @Override @DefinedBy(Api.COMPILER) 177 public int run(InputStream in, OutputStream out, OutputStream err, String... arguments) { 178 if (err == null) 179 err = System.err; 180 for (String argument : arguments) 181 Objects.requireNonNull(argument); 182 return com.sun.tools.javac.Main.compile(arguments, new PrintWriter(err, true)); 183 } 184 185 @Override @DefinedBy(Api.COMPILER) 186 public Set<SourceVersion> getSourceVersions() { 187 return Collections.unmodifiableSet(EnumSet.range(SourceVersion.RELEASE_3, 188 SourceVersion.latest())); 189 } 190 191 @Override @DefinedBy(Api.COMPILER) 192 public int isSupportedOption(String option) { 193 Set<Option> recognizedOptions = Option.getJavacToolOptions(); 194 for (Option o : recognizedOptions) { 195 if (o.matches(option)) 196 return o.hasArg() ? 1 : 0; 197 } 198 return -1; 199 } 200 201} 202