1818 */
1919package org .codehaus .groovy .tools .javac ;
2020
21- import groovy .lang .GroovyClassLoader ;
2221import groovy .lang .GroovyObject ;
2322import org .apache .groovy .io .StringBuilderWriter ;
2423import org .codehaus .groovy .GroovyBugError ;
2524import org .codehaus .groovy .control .CompilationUnit ;
2625import org .codehaus .groovy .control .CompilerConfiguration ;
2726import org .codehaus .groovy .control .messages .ExceptionMessage ;
2827import org .codehaus .groovy .control .messages .SimpleMessage ;
29- import org .codehaus .groovy .runtime .DefaultGroovyMethods ;
3028
3129import java .io .File ;
3230import java .io .IOException ;
31+ import java .io .Writer ;
3332import java .net .URISyntaxException ;
3433import java .net .URL ;
3534import java .net .URLClassLoader ;
3635import java .nio .charset .Charset ;
37- import java .security .CodeSource ;
38- import java .security .PrivilegedAction ;
3936import java .util .ArrayList ;
40- import java .util .Collections ;
4137import java .util .HashSet ;
4238import java .util .List ;
4339import java .util .Locale ;
4440import java .util .Map ;
41+ import java .util .Objects ;
4542import java .util .Set ;
46- import java .util .stream .Collectors ;
47-
48- import static org .codehaus .groovy .control .CompilerConfiguration .MEM_STUB ;
4943
5044public class JavacJavaCompiler implements JavaCompiler {
5145
52- private static final Locale DEFAULT_LOCALE = Locale .ENGLISH ;
5346 private final CompilerConfiguration config ;
54- private final Charset charset ;
5547
56- public JavacJavaCompiler (CompilerConfiguration config ) {
57- this .config = config ;
58- this .charset = Charset .forName (config .getSourceEncoding ());
48+ public JavacJavaCompiler (final CompilerConfiguration config ) {
49+ this .config = Objects .requireNonNull (config );
5950 }
6051
6152 @ Override
62- public void compile (List <String > files , CompilationUnit cu ) {
53+ public void compile (final List <String > files , final CompilationUnit cu ) {
6354 List <String > javacParameters = makeParameters (cu .getClassLoader ());
64- StringBuilderWriter javacOutput = new StringBuilderWriter ();
55+ var javacOutput = new StringBuilderWriter ();
6556 int javacReturnValue = 0 ;
6657 try {
6758 boolean successful = doCompileWithSystemJavaCompiler (cu , files , javacParameters , javacOutput );
6859 if (!successful ) {
6960 javacReturnValue = 1 ;
7061 }
7162 } catch (IllegalArgumentException e ) {
72- javacReturnValue = 2 ; // any of the options are invalid
63+ javacReturnValue = 2 ; // invalid options
7364 cu .getErrorCollector ().addFatalError (new ExceptionMessage (e , true , cu ));
7465 } catch (IOException e ) {
7566 javacReturnValue = 1 ;
@@ -79,130 +70,138 @@ public void compile(List<String> files, CompilationUnit cu) {
7970 }
8071
8172 if (javacReturnValue != 0 ) {
82- switch (javacReturnValue ) {
83- case 1 : addJavacError ( "Compile error during compilation with javac." , cu , javacOutput ); break ;
84- case 2 : addJavacError ( "Invalid commandline usage for javac." , cu , javacOutput ); break ;
85- default : addJavacError ( "unexpected return value by javac." , cu , javacOutput ); break ;
86- }
73+ addJavacError ( switch (javacReturnValue ) {
74+ case 1 -> "Compile error during compilation with javac." ;
75+ case 2 -> "Invalid commandline usage for javac." ;
76+ default -> "unexpected return value by javac." ;
77+ }, javacOutput . toString (), cu );
8778 } else {
88- // print warnings if any
89- System .out .print (javacOutput );
79+ System .out .print (javacOutput ); // print errors/warnings
9080 }
9181 }
9282
93- private boolean doCompileWithSystemJavaCompiler (CompilationUnit cu , List <String > files , List <String > javacParameters , StringBuilderWriter javacOutput ) throws IOException {
83+ private boolean doCompileWithSystemJavaCompiler (final CompilationUnit cu , final List <String > files , final List <String > javacParameters , final Writer javacOutput ) throws IOException {
84+ Locale locale = Locale .ENGLISH ;
85+ Charset charset = Charset .forName (config .getSourceEncoding ());
9486 javax .tools .JavaCompiler compiler = javax .tools .ToolProvider .getSystemJavaCompiler ();
95- try (javax .tools .StandardJavaFileManager fileManager = compiler .getStandardFileManager (null , DEFAULT_LOCALE , charset )) {
87+ try (javax .tools .StandardJavaFileManager fileManager = compiler .getStandardFileManager (null , locale , charset )) {
9688 Set <javax .tools .JavaFileObject > compilationUnitSet = cu .getJavaCompilationUnitSet (); // java stubs already added
9789
98- Map <String , Object > options = this . config .getJointCompilationOptions ();
99- if (!Boolean .TRUE .equals (options .get (MEM_STUB ))) {
90+ Map <String , Object > options = config .getJointCompilationOptions ();
91+ if (!Boolean .TRUE .equals (options .get (CompilerConfiguration . MEM_STUB ))) {
10092 // clear the java stubs in the source set of Java compilation
10193 compilationUnitSet = new HashSet <>();
10294
10395 // use sourcepath to specify the root directory of java stubs
104- javacParameters .add ("-sourcepath" );
105- final File stubDir = (File ) options .get ("stubDir" );
106- if (null == stubDir ) {
107- throw new GroovyBugError ("stubDir is not specified" );
96+ if (options .get ("stubDir" ) instanceof File stubDir ) {
97+ javacParameters .add ("-sourcepath" );
98+ javacParameters .add (stubDir .getAbsolutePath ());
99+ } else {
100+ throw new GroovyBugError ("stubDir not specified" );
108101 }
109- javacParameters .add (stubDir .getAbsolutePath ());
110102 }
111103
112104 // add java source files to compile
113105 fileManager .getJavaFileObjectsFromFiles (
114- files .stream ().map (File ::new ).collect ( Collectors . toList () )
106+ files .stream ().map (File ::new ).toList ()
115107 ).forEach (compilationUnitSet ::add );
116108
117109 javax .tools .JavaCompiler .CompilationTask compilationTask = compiler .getTask (
118110 javacOutput ,
119111 fileManager ,
120112 null ,
121113 javacParameters ,
122- Collections . emptyList () ,
114+ null ,
123115 compilationUnitSet
124116 );
125- compilationTask .setLocale (DEFAULT_LOCALE );
117+ compilationTask .setLocale (locale );
126118
127119 return compilationTask .call ();
128120 }
129121 }
130122
131- private static void addJavacError (String header , CompilationUnit cu , StringBuilderWriter msg ) {
132- if (msg != null ) {
133- header = header + "\n " + msg .getBuilder ().toString ();
123+ private static void addJavacError (final String head , final String text , final CompilationUnit unit ) {
124+ String message ;
125+ if (text != null && !text .trim ().isEmpty ()) {
126+ message = head + "\n " + text ;
134127 } else {
135- header = header +
128+ message = head +
136129 "\n This javac version does not support compile(String[],PrintWriter), " +
137130 "so no further details of the error are available. The message error text " +
138131 "should be found on System.err.\n " ;
139132 }
140- cu .getErrorCollector ().addFatalError (new SimpleMessage (header , cu ));
133+ unit .getErrorCollector ().addFatalError (new SimpleMessage (message , unit ));
141134 }
142135
143- private List <String > makeParameters (GroovyClassLoader parentClassLoader ) {
144- Map <String , Object > options = config .getJointCompilationOptions ();
136+ private List <String > makeParameters (final ClassLoader classLoader ) {
145137 List <String > params = new ArrayList <>();
146138
147- File target = config .getTargetDirectory ();
148- if (target == null ) target = new File ("." );
139+ File targetDir = config .getTargetDirectory ();
140+ if (targetDir == null ) targetDir = new File ("." );
149141
150142 params .add ("-d" );
151- params .add (target .getAbsolutePath ());
143+ params .add (targetDir .getAbsolutePath ());
144+
145+ Map <String , Object > options = config .getJointCompilationOptions ();
146+ boolean classpath = false ;
152147
153- String [] flags = (String []) options .get ("flags" );
154- if (flags != null ) {
148+ if (options .get ("flags" ) instanceof String [] flags ) {
155149 for (String flag : flags ) {
150+ if (flag == null ) continue ;
151+
156152 params .add ("-" + flag );
157153 }
158154 }
159155
160- boolean hadClasspath = false ;
161- String [] namedValues = (String []) options .get ("namedValues" );
162- if (namedValues != null ) {
156+ if (options .get ("namedValues" ) instanceof String [] namedValues ) {
163157 for (int i = 0 , n = namedValues .length ; i < n ; i += 2 ) {
164- String name = namedValues [i ];
165- if ("classpath" .equals (name )) hadClasspath = true ;
158+ var name = namedValues [i ];
159+ if (name == null ) continue ;
160+ if (!classpath ) classpath = isClasspathParameter (name );
161+
166162 params .add ("-" + name );
167163 params .add (namedValues [i + 1 ]);
168164 }
169165 }
170166
171167 // append classpath if not already defined
172- if (!hadClasspath ) {
173- // add all classpaths that compilation unit sees
168+ if (!classpath ) {
169+ // add class paths of compilation unit
174170 List <String > paths = new ArrayList <>(config .getClasspath ());
175- ClassLoader loader = parentClassLoader ;
176- while (loader != null ) {
177- if (loader instanceof URLClassLoader ) {
178- for (URL u : ((URLClassLoader ) loader ).getURLs ()) {
171+ for (ClassLoader loader = classLoader ; loader != null ; loader = loader .getParent ()) {
172+ if (loader instanceof URLClassLoader ucl ) {
173+ for (URL u : ucl .getURLs ()) {
179174 try {
180175 paths .add (new File (u .toURI ()).getPath ());
181176 } catch (URISyntaxException ignore ) {
182177 }
183178 }
184179 }
185- loader = loader .getParent ();
186180 }
187181
188182 try {
189- CodeSource codeSource = getCodeSource ();
190- if (codeSource != null ) {
183+ var codeSource = getCodeSource ();
184+ if (codeSource != null ) { // add class path of groovy runtime
191185 paths .add (new File (codeSource .getLocation ().toURI ()).getPath ());
192186 }
193187 } catch (URISyntaxException ignore ) {
194188 }
195189
196190 params .add ("-classpath" );
197- params .add (DefaultGroovyMethods .join (( Iterable < String >) paths , File .pathSeparator ));
191+ params .add (String .join (File .pathSeparator , paths ));
198192 }
199193
200194 return params ;
201195 }
202196
197+ private static boolean isClasspathParameter (final String param ) {
198+ return param .equals ("cp" ) || param .equals ("classpath" ) || param .equals ("-class-path" );
199+ }
200+
203201 @ SuppressWarnings ("removal" ) // TODO a future Groovy version should perform the operation not as a privileged action
204- private CodeSource getCodeSource () {
205- return java .security .AccessController .doPrivileged (
206- (PrivilegedAction <CodeSource >) () -> GroovyObject .class .getProtectionDomain ().getCodeSource ());
202+ private static java .security .CodeSource getCodeSource () {
203+ return java .security .AccessController .doPrivileged ((java .security .PrivilegedAction <java .security .CodeSource >) () ->
204+ GroovyObject .class .getProtectionDomain ().getCodeSource ()
205+ );
207206 }
208207}
0 commit comments