JavacTool.java revision 3294:9adfb22ff08f
1/* 2 * Copyright (c) 2005, 2016, 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.file.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 int sep = cls.indexOf('/'); // implicit null check 134 if (sep > 0) { 135 String mod = cls.substring(0, sep); 136 if (!SourceVersion.isName(mod)) 137 throw new IllegalArgumentException("Not a valid module name: " + mod); 138 cls = cls.substring(sep + 1); 139 } 140 if (!SourceVersion.isName(cls)) 141 throw new IllegalArgumentException("Not a valid class name: " + cls); 142 } 143 } 144 145 if (compilationUnits != null) { 146 compilationUnits = ccw.wrapJavaFileObjects(compilationUnits); // implicit null check 147 for (JavaFileObject cu : compilationUnits) { 148 if (cu.getKind() != JavaFileObject.Kind.SOURCE) { 149 String kindMsg = "Compilation unit is not of SOURCE kind: " 150 + "\"" + cu.getName() + "\""; 151 throw new IllegalArgumentException(kindMsg); 152 } 153 } 154 } 155 156 if (diagnosticListener != null) 157 context.put(DiagnosticListener.class, ccw.wrap(diagnosticListener)); 158 159 if (out == null) 160 context.put(Log.outKey, new PrintWriter(System.err, true)); 161 else 162 context.put(Log.outKey, new PrintWriter(out, true)); 163 164 if (fileManager == null) { 165 fileManager = getStandardFileManager(diagnosticListener, null, null); 166 if (fileManager instanceof BaseFileManager) { 167 ((BaseFileManager) fileManager).autoClose = true; 168 } 169 } 170 fileManager = ccw.wrap(fileManager); 171 172 context.put(JavaFileManager.class, fileManager); 173 174 Arguments args = Arguments.instance(context); 175 args.init("javac", options, classes, compilationUnits); 176 return new JavacTaskImpl(context); 177 } catch (PropagatedException ex) { 178 throw ex.getCause(); 179 } catch (ClientCodeException ex) { 180 throw new RuntimeException(ex.getCause()); 181 } 182 } 183 184 @Override @DefinedBy(Api.COMPILER) 185 public int run(InputStream in, OutputStream out, OutputStream err, String... arguments) { 186 if (err == null) 187 err = System.err; 188 for (String argument : arguments) 189 Objects.requireNonNull(argument); 190 return com.sun.tools.javac.Main.compile(arguments, new PrintWriter(err, true)); 191 } 192 193 @Override @DefinedBy(Api.COMPILER) 194 public Set<SourceVersion> getSourceVersions() { 195 return Collections.unmodifiableSet(EnumSet.range(SourceVersion.RELEASE_3, 196 SourceVersion.latest())); 197 } 198 199 @Override @DefinedBy(Api.COMPILER) 200 public int isSupportedOption(String option) { 201 Set<Option> recognizedOptions = Option.getJavacToolOptions(); 202 for (Option o : recognizedOptions) { 203 if (o.matches(option)) 204 return o.hasArg() ? 1 : 0; 205 } 206 return -1; 207 } 208 209} 210