29 import java.util.HashMap; |
29 import java.util.HashMap; |
30 import java.util.Iterator; |
30 import java.util.Iterator; |
31 import java.util.Map; |
31 import java.util.Map; |
32 import java.util.NoSuchElementException; |
32 import java.util.NoSuchElementException; |
33 import java.util.Set; |
33 import java.util.Set; |
|
34 import java.util.function.Function; |
34 |
35 |
35 import javax.tools.JavaFileManager; |
36 import javax.tools.JavaFileManager; |
36 import javax.tools.JavaFileManager.Location; |
37 import javax.tools.JavaFileManager.Location; |
37 import javax.tools.JavaFileObject; |
38 import javax.tools.JavaFileObject; |
38 import javax.tools.JavaFileObject.Kind; |
39 import javax.tools.JavaFileObject.Kind; |
39 import javax.tools.StandardLocation; |
40 import javax.tools.StandardLocation; |
40 |
41 |
|
42 import com.sun.tools.javac.code.Symbol.Completer; |
41 import com.sun.tools.javac.code.Symbol.CompletionFailure; |
43 import com.sun.tools.javac.code.Symbol.CompletionFailure; |
42 import com.sun.tools.javac.code.Symbol.ModuleSymbol; |
44 import com.sun.tools.javac.code.Symbol.ModuleSymbol; |
|
45 import com.sun.tools.javac.jvm.ModuleNameReader; |
|
46 import com.sun.tools.javac.jvm.ModuleNameReader.BadClassFile; |
43 import com.sun.tools.javac.resources.CompilerProperties.Errors; |
47 import com.sun.tools.javac.resources.CompilerProperties.Errors; |
44 import com.sun.tools.javac.resources.CompilerProperties.Fragments; |
48 import com.sun.tools.javac.resources.CompilerProperties.Fragments; |
|
49 import com.sun.tools.javac.util.Assert; |
45 import com.sun.tools.javac.util.Context; |
50 import com.sun.tools.javac.util.Context; |
46 import com.sun.tools.javac.util.JCDiagnostic; |
51 import com.sun.tools.javac.util.JCDiagnostic; |
47 import com.sun.tools.javac.util.JCDiagnostic.Fragment; |
52 import com.sun.tools.javac.util.JCDiagnostic.Fragment; |
48 import com.sun.tools.javac.util.List; |
53 import com.sun.tools.javac.util.List; |
49 import com.sun.tools.javac.util.ListBuffer; |
54 import com.sun.tools.javac.util.ListBuffer; |
50 import com.sun.tools.javac.util.Log; |
55 import com.sun.tools.javac.util.Log; |
51 import com.sun.tools.javac.util.Name; |
56 import com.sun.tools.javac.util.Name; |
52 import com.sun.tools.javac.util.Names; |
57 import com.sun.tools.javac.util.Names; |
53 import com.sun.tools.javac.util.StringUtils; |
|
54 |
58 |
55 import static com.sun.tools.javac.code.Kinds.Kind.*; |
59 import static com.sun.tools.javac.code.Kinds.Kind.*; |
56 |
60 |
57 /** |
61 /** |
58 * This class provides operations to locate module definitions |
62 * This class provides operations to locate module definitions |
81 /** Access to files |
85 /** Access to files |
82 */ |
86 */ |
83 private final JavaFileManager fileManager; |
87 private final JavaFileManager fileManager; |
84 |
88 |
85 private final JCDiagnostic.Factory diags; |
89 private final JCDiagnostic.Factory diags; |
|
90 |
|
91 private ModuleNameReader moduleNameReader; |
|
92 |
|
93 public ModuleInfoSourceFileCompleter sourceFileCompleter; |
86 |
94 |
87 /** Get the ModuleFinder instance for this invocation. */ |
95 /** Get the ModuleFinder instance for this invocation. */ |
88 public static ModuleFinder instance(Context context) { |
96 public static ModuleFinder instance(Context context) { |
89 ModuleFinder instance = context.get(moduleFinderKey); |
97 ModuleFinder instance = context.get(moduleFinderKey); |
90 if (instance == null) |
98 if (instance == null) |
180 } |
188 } |
181 } |
189 } |
182 return list; |
190 return list; |
183 } |
191 } |
184 |
192 |
|
193 private boolean inFindSingleModule; |
|
194 |
185 public ModuleSymbol findSingleModule() { |
195 public ModuleSymbol findSingleModule() { |
186 try { |
196 try { |
187 JavaFileObject src_fo = getModuleInfoFromLocation(StandardLocation.SOURCE_PATH, Kind.SOURCE); |
197 JavaFileObject src_fo = getModuleInfoFromLocation(StandardLocation.SOURCE_PATH, Kind.SOURCE); |
188 JavaFileObject class_fo = getModuleInfoFromLocation(StandardLocation.CLASS_OUTPUT, Kind.CLASS); |
198 JavaFileObject class_fo = getModuleInfoFromLocation(StandardLocation.CLASS_OUTPUT, Kind.CLASS); |
189 JavaFileObject fo = (src_fo == null) ? class_fo |
199 JavaFileObject fo = (src_fo == null) ? class_fo |
192 |
202 |
193 ModuleSymbol msym; |
203 ModuleSymbol msym; |
194 if (fo == null) { |
204 if (fo == null) { |
195 msym = syms.unnamedModule; |
205 msym = syms.unnamedModule; |
196 } else { |
206 } else { |
197 // Note: the following may trigger a re-entrant call to Modules.enter |
207 switch (fo.getKind()) { |
198 // msym = new ModuleSymbol(); |
208 case SOURCE: |
199 // ClassSymbol info = new ClassSymbol(Flags.MODULE, names.module_info, msym); |
209 if (!inFindSingleModule) { |
200 // info.modle = msym; |
210 try { |
201 // info.classfile = fo; |
211 inFindSingleModule = true; |
202 // info.members_field = WriteableScope.create(info); |
212 // Note: the following will trigger a re-entrant call to Modules.enter |
203 // msym.module_info = info; |
213 msym = sourceFileCompleter.complete(fo); |
204 msym = ModuleSymbol.create(null, names.module_info); |
214 msym.module_info.classfile = fo; |
205 msym.module_info.classfile = fo; |
215 } finally { |
206 msym.completer = sym -> classFinder.fillIn(msym.module_info); |
216 inFindSingleModule = false; |
207 // // TODO: should we do the following here, or as soon as we find the name in |
217 } |
208 // // the source or class file? |
218 } else { |
209 // // Consider the case when the class/source path module shadows one on the |
219 //the module-info.java does not contain a module declaration, |
210 // // module source path |
220 //avoid infinite recursion: |
211 // if (syms.modules.get(msym.name) != null) { |
221 msym = syms.unnamedModule; |
212 // // error: module already defined |
222 } |
213 // System.err.println("ERROR: module already defined: " + msym); |
223 break; |
214 // } else { |
224 case CLASS: |
215 // syms.modules.put(msym.name, msym); |
225 Name name; |
216 // } |
226 try { |
|
227 name = names.fromString(readModuleName(fo)); |
|
228 } catch (BadClassFile | IOException ex) { |
|
229 //fillIn will report proper errors: |
|
230 name = names.error; |
|
231 } |
|
232 msym = syms.enterModule(name); |
|
233 msym.module_info.classfile = fo; |
|
234 msym.completer = Completer.NULL_COMPLETER; |
|
235 classFinder.fillIn(msym.module_info); |
|
236 break; |
|
237 default: |
|
238 Assert.error(); |
|
239 msym = syms.unnamedModule; |
|
240 break; |
|
241 } |
217 } |
242 } |
218 |
243 |
219 msym.classLocation = StandardLocation.CLASS_OUTPUT; |
244 msym.classLocation = StandardLocation.CLASS_OUTPUT; |
220 return msym; |
245 return msym; |
221 |
246 |
222 } catch (IOException e) { |
247 } catch (IOException e) { |
223 throw new Error(e); // FIXME |
248 throw new Error(e); // FIXME |
224 } |
249 } |
|
250 } |
|
251 |
|
252 private String readModuleName(JavaFileObject jfo) throws IOException, ModuleNameReader.BadClassFile { |
|
253 if (moduleNameReader == null) |
|
254 moduleNameReader = new ModuleNameReader(); |
|
255 return moduleNameReader.readModuleName(jfo); |
225 } |
256 } |
226 |
257 |
227 private JavaFileObject getModuleInfoFromLocation(Location location, Kind kind) throws IOException { |
258 private JavaFileObject getModuleInfoFromLocation(Location location, Kind kind) throws IOException { |
228 if (!fileManager.hasLocation(location)) |
259 if (!fileManager.hasLocation(location)) |
229 return null; |
260 return null; |