Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/langtools/src/share/classes/com/sun/tools/sjavac/Source.java
38899 views
1
/*
2
* Copyright (c) 2012, 2013, 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
26
package com.sun.tools.sjavac;
27
28
import java.io.File;
29
import java.util.Set;
30
import java.util.Collections;
31
import java.util.List;
32
import java.util.ArrayList;
33
import java.util.Map;
34
35
/** A Source object maintains information about a source file.
36
* For example which package it belongs to and kind of source it is.
37
* The class also knows how to find source files (scanRoot) given include/exclude
38
* patterns and a root.
39
*
40
* <p><b>This is NOT part of any supported API.
41
* If you write code that depends on this, you do so at your own
42
* risk. This code and its internal interfaces are subject to change
43
* or deletion without notice.</b></p>
44
*/
45
public class Source implements Comparable<Source> {
46
// The package the source belongs to.
47
private Package pkg;
48
// Name of this source file, relative its source root.
49
// For example: java/lang/Object.java
50
// Or if the source file is inside a module:
51
// jdk.base/java/lang/Object.java
52
private String name;
53
// What kind of file is this.
54
private String suffix;
55
// When this source file was last_modified
56
private long lastModified;
57
// The source File.
58
private File file;
59
// The source root under which file resides.
60
private File root;
61
// If the source is generated.
62
private boolean isGenerated;
63
// If the source is only linked to, not compiled.
64
private boolean linkedOnly;
65
66
@Override
67
public boolean equals(Object o) {
68
return (o instanceof Source) && name.equals(((Source)o).name);
69
}
70
71
@Override
72
public int compareTo(Source o) {
73
return name.compareTo(o.name);
74
}
75
76
@Override
77
public int hashCode() {
78
return name.hashCode();
79
}
80
81
public Source(Module m, String n, File f, File r) {
82
name = n;
83
int dp = n.lastIndexOf(".");
84
if (dp != -1) {
85
suffix = n.substring(dp);
86
} else {
87
suffix = "";
88
}
89
file = f;
90
root = r;
91
lastModified = f.lastModified();
92
linkedOnly = false;
93
}
94
95
public Source(Package p, String n, long lm) {
96
pkg = p;
97
name = n;
98
int dp = n.lastIndexOf(".");
99
if (dp != -1) {
100
suffix = n.substring(dp);
101
} else {
102
suffix = "";
103
}
104
file = null;
105
root = null;
106
lastModified = lm;
107
linkedOnly = false;
108
int ls = n.lastIndexOf('/');
109
}
110
111
public String name() { return name; }
112
public String suffix() { return suffix; }
113
public Package pkg() { return pkg; }
114
public File file() { return file; }
115
public File root() { return root; }
116
public long lastModified() {
117
return lastModified;
118
}
119
120
public void setPackage(Package p) {
121
pkg = p;
122
}
123
124
public void markAsGenerated() {
125
isGenerated = true;
126
}
127
128
public boolean isGenerated() {
129
return isGenerated;
130
}
131
132
public void markAsLinkedOnly() {
133
linkedOnly = true;
134
}
135
136
public boolean isLinkedOnly() {
137
return linkedOnly;
138
}
139
140
private void save(StringBuilder b) {
141
String CL = linkedOnly?"L":"C";
142
String GS = isGenerated?"G":"S";
143
b.append(GS+" "+CL+" "+name+" "+file.lastModified()+"\n");
144
}
145
// Parse a line that looks like this:
146
// S C /code/alfa/A.java 1357631228000
147
static public Source load(Package lastPackage, String l, boolean isGenerated) {
148
int sp = l.indexOf(' ',4);
149
if (sp == -1) return null;
150
String name = l.substring(4,sp);
151
long last_modified = Long.parseLong(l.substring(sp+1));
152
153
boolean isLinkedOnly = false;
154
if (l.charAt(2) == 'L') {
155
isLinkedOnly = true;
156
} else if (l.charAt(2) == 'C') {
157
isLinkedOnly = false;
158
} else return null;
159
160
Source s = new Source(lastPackage, name, last_modified);
161
s.file = new File(name);
162
if (isGenerated) s.markAsGenerated();
163
if (isLinkedOnly) s.markAsLinkedOnly();
164
return s;
165
}
166
167
public static void saveSources(Map<String,Source> sources, StringBuilder b) {
168
List<String> sorted_sources = new ArrayList<String>();
169
for (String key : sources.keySet()) {
170
sorted_sources.add(key);
171
}
172
Collections.sort(sorted_sources);
173
for (String key : sorted_sources) {
174
Source s = sources.get(key);
175
s.save(b);
176
}
177
}
178
179
/**
180
* Recurse into the directory root and find all files matchine the excl/incl/exclfiles/inclfiles rules.
181
* Detects the existence of module-info.java files and presumes that the directory it resides in
182
* is the name of the current module.
183
*/
184
static public void scanRoot(File root,
185
Set<String> suffixes,
186
List<String> excludes, List<String> includes,
187
List<String> excludeFiles, List<String> includeFiles,
188
Map<String,Source> foundFiles,
189
Map<String,Module> foundModules,
190
Module currentModule,
191
boolean permitSourcesWithoutPackage,
192
boolean inGensrc,
193
boolean inLinksrc)
194
throws ProblemException {
195
196
if (root == null) return;
197
int root_prefix = root.getPath().length()+1;
198
// This is the root source directory, it must not contain any Java sources files
199
// because we do not allow Java source files without a package.
200
// (Unless of course --permit-sources-without-package has been specified.)
201
// It might contain other source files however, (for -tr and -copy) these will
202
// always be included, since no package pattern can match the root directory.
203
currentModule = addFilesInDir(root, root_prefix, root, suffixes, permitSourcesWithoutPackage,
204
excludeFiles, includeFiles, false,
205
foundFiles, foundModules, currentModule,
206
inGensrc, inLinksrc);
207
208
File[] dirfiles = root.listFiles();
209
for (File d : dirfiles) {
210
if (d.isDirectory()) {
211
// Descend into the directory structure.
212
scanDirectory(d, root_prefix, root, suffixes,
213
excludes, includes, excludeFiles, includeFiles,
214
false, foundFiles, foundModules, currentModule, inGensrc, inLinksrc);
215
}
216
}
217
}
218
219
/**
220
* Test if a path matches any of the patterns given.
221
* The pattern foo.bar matches only foo.bar
222
* The pattern foo.* matches foo.bar and foo.bar.zoo etc
223
*/
224
static private boolean hasMatch(String path, List<String> patterns) {
225
for (String p : patterns) {
226
// Exact match
227
if (p.equals(path)) {
228
return true;
229
}
230
// Single dot the end matches this package and all its subpackages.
231
if (p.endsWith(".*")) {
232
// Remove the wildcard
233
String patprefix = p.substring(0,p.length()-2);
234
// Does the path start with the pattern prefix?
235
if (path.startsWith(patprefix)) {
236
// If the path has the same length as the pattern prefix, then it is a match.
237
// If the path is longer, then make sure that
238
// the next part of the path starts with a dot (.) to prevent
239
// wildcard matching in the middle of a package name.
240
if (path.length()==patprefix.length() || path.charAt(patprefix.length())=='.') {
241
return true;
242
}
243
}
244
}
245
}
246
return false;
247
}
248
249
/**
250
* Matches patterns with the asterisk first. */
251
// The pattern foo/bar.java only matches foo/bar.java
252
// The pattern */bar.java matches foo/bar.java and zoo/bar.java etc
253
static private boolean hasFileMatch(String path, List<String> patterns) {
254
path = Util.normalizeDriveLetter(path);
255
for (String p : patterns) {
256
// Exact match
257
if (p.equals(path)) {
258
return true;
259
}
260
// Single dot the end matches this package and all its subpackages.
261
if (p.startsWith("*")) {
262
// Remove the wildcard
263
String patsuffix = p.substring(1);
264
// Does the path start with the pattern prefix?
265
if (path.endsWith(patsuffix)) {
266
return true;
267
}
268
}
269
}
270
return false;
271
}
272
273
/**
274
* Add the files in the directory, assuming that the file has not been excluded.
275
* Returns a fresh Module object, if this was a dir with a module-info.java file.
276
*/
277
static private Module addFilesInDir(File dir, int rootPrefix, File root,
278
Set<String> suffixes, boolean allow_javas,
279
List<String> excludeFiles, List<String> includeFiles, boolean all,
280
Map<String,Source> foundFiles,
281
Map<String,Module> foundModules,
282
Module currentModule,
283
boolean inGensrc,
284
boolean inLinksrc)
285
throws ProblemException
286
{
287
for (File f : dir.listFiles()) {
288
if (f.isFile()) {
289
boolean should_add =
290
(excludeFiles == null || excludeFiles.isEmpty() || !hasFileMatch(f.getPath(), excludeFiles))
291
&& (includeFiles == null || includeFiles.isEmpty() || hasFileMatch(f.getPath(), includeFiles));
292
293
if (should_add) {
294
if (!allow_javas && f.getName().endsWith(".java")) {
295
throw new ProblemException("No .java files are allowed in the source root "+dir.getPath()+
296
", please remove "+f.getName());
297
}
298
// Extract the file name relative the root.
299
String fn = f.getPath().substring(rootPrefix);
300
// Extract the package name.
301
int sp = fn.lastIndexOf(File.separatorChar);
302
String pkg = "";
303
if (sp != -1) {
304
pkg = fn.substring(0,sp).replace(File.separatorChar,'.');
305
}
306
// Is this a module-info.java file?
307
if (fn.endsWith("module-info.java")) {
308
// Aha! We have recursed into a module!
309
if (!currentModule.name().equals("")) {
310
throw new ProblemException("You have an extra module-info.java inside a module! Please remove "+fn);
311
}
312
String module_name = fn.substring(0,fn.length()-16);
313
currentModule = new Module(module_name, f.getPath());
314
foundModules.put(module_name, currentModule);
315
}
316
// Extract the suffix.
317
int dp = fn.lastIndexOf(".");
318
String suffix = "";
319
if (dp > 0) {
320
suffix = fn.substring(dp);
321
}
322
// Should the file be added?
323
if (all || suffixes.contains(suffix)) {
324
Source of = foundFiles.get(f.getPath());
325
if (of != null) {
326
throw new ProblemException("You have already added the file "+fn+" from "+of.file().getPath());
327
}
328
of = currentModule.lookupSource(f.getPath());
329
if (of != null) {
330
// Oups, the source is already added, could be ok, could be not, lets check.
331
if (inLinksrc) {
332
// So we are collecting sources for linking only.
333
if (of.isLinkedOnly()) {
334
// Ouch, this one is also for linking only. Bad.
335
throw new ProblemException("You have already added the link only file "+fn+" from "+of.file().getPath());
336
}
337
// Ok, the existing source is to be compiled. Thus this link only is redundant
338
// since all compiled are also linked to. Continue to the next source.
339
// But we need to add the source, so that it will be visible to linking,
340
// if not the multi core compile will fail because a JavaCompiler cannot
341
// find the necessary dependencies for its part of the source.
342
foundFiles.put(f.getPath(), of);
343
continue;
344
} else {
345
// We are looking for sources to compile, if we find an existing to be compiled
346
// source with the same name, it is an internal error, since we must
347
// find the sources to be compiled before we find the sources to be linked to.
348
throw new ProblemException("Internal error: Double add of file "+fn+" from "+of.file().getPath());
349
}
350
}
351
Source s = new Source(currentModule, f.getPath(), f, root);
352
if (inGensrc) s.markAsGenerated();
353
if (inLinksrc) {
354
s.markAsLinkedOnly();
355
}
356
pkg = currentModule.name()+":"+pkg;
357
foundFiles.put(f.getPath(), s);
358
currentModule.addSource(pkg, s);
359
}
360
}
361
}
362
}
363
return currentModule;
364
}
365
366
private static boolean gurka = false;
367
368
static private void scanDirectory(File dir, int rootPrefix, File root,
369
Set<String> suffixes,
370
List<String> excludes, List<String> includes,
371
List<String> excludeFiles, List<String> includeFiles, boolean all,
372
Map<String,Source> foundFiles,
373
Map<String,Module> foundModules,
374
Module currentModule, boolean inGensrc, boolean inLinksrc)
375
throws ProblemException {
376
377
String pkg_name = "";
378
// Remove the root prefix from the dir path, and replace file separator with dots
379
// to get the package name.
380
if (dir.getPath().length() > rootPrefix) {
381
pkg_name = dir.getPath().substring(rootPrefix).replace(File.separatorChar,'.');
382
}
383
// Should this package directory be included and not excluded?
384
if (all || ((includes==null || includes.isEmpty() || hasMatch(pkg_name, includes)) &&
385
(excludes==null || excludes.isEmpty() || !hasMatch(pkg_name, excludes)))) {
386
// Add the source files.
387
currentModule = addFilesInDir(dir, rootPrefix, root, suffixes, true, excludeFiles, includeFiles, all,
388
foundFiles, foundModules, currentModule, inGensrc, inLinksrc);
389
}
390
391
for (File d : dir.listFiles()) {
392
if (d.isDirectory()) {
393
// Descend into the directory structure.
394
scanDirectory(d, rootPrefix, root, suffixes,
395
excludes, includes, excludeFiles, includeFiles, all,
396
foundFiles, foundModules, currentModule, inGensrc, inLinksrc);
397
}
398
}
399
}
400
}
401
402