Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/jdk.compiler/share/classes/com/sun/tools/sjavac/Source.java
41175 views
1
/*
2
* Copyright (c) 2012, 2021, 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.io.IOException;
30
import java.nio.file.FileSystem;
31
import java.nio.file.FileVisitResult;
32
import java.nio.file.Files;
33
import java.nio.file.Path;
34
import java.nio.file.PathMatcher;
35
import java.nio.file.SimpleFileVisitor;
36
import java.nio.file.attribute.BasicFileAttributes;
37
import java.util.Set;
38
import java.util.Collections;
39
import java.util.List;
40
import java.util.ArrayList;
41
import java.util.Map;
42
import java.util.regex.PatternSyntaxException;
43
44
/** A Source object maintains information about a source file.
45
* For example which package it belongs to and kind of source it is.
46
* The class also knows how to find source files (scanRoot) given include/exclude
47
* patterns and a root.
48
*
49
* <p><b>This is NOT part of any supported API.
50
* If you write code that depends on this, you do so at your own risk.
51
* This code and its internal interfaces are subject to change or
52
* deletion without notice.</b>
53
*/
54
public class Source implements Comparable<Source> {
55
// The package the source belongs to.
56
private Package pkg;
57
// Name of this source file, relative its source root.
58
// For example: java/lang/Object.java
59
// Or if the source file is inside a module:
60
// jdk.base/java/lang/Object.java
61
private String name;
62
// What kind of file is this.
63
private String suffix;
64
// When this source file was last_modified
65
private long lastModified;
66
// The source File.
67
private File file;
68
// If the source is generated.
69
private boolean isGenerated;
70
// If the source is only linked to, not compiled.
71
private boolean linkedOnly;
72
73
@Override
74
public boolean equals(Object o) {
75
return (o instanceof Source source) && name.equals(source.name);
76
}
77
78
@Override
79
public int compareTo(Source o) {
80
return name.compareTo(o.name);
81
}
82
83
@Override
84
public int hashCode() {
85
return name.hashCode();
86
}
87
88
public Source(Module m, String n, File f) {
89
name = n;
90
int dp = n.lastIndexOf(".");
91
if (dp != -1) {
92
suffix = n.substring(dp);
93
} else {
94
suffix = "";
95
}
96
file = f;
97
lastModified = f.lastModified();
98
linkedOnly = false;
99
}
100
101
public Source(Package p, String n, long lm) {
102
pkg = p;
103
name = n;
104
int dp = n.lastIndexOf(".");
105
if (dp != -1) {
106
suffix = n.substring(dp);
107
} else {
108
suffix = "";
109
}
110
file = null;
111
lastModified = lm;
112
linkedOnly = false;
113
int ls = n.lastIndexOf('/');
114
}
115
116
public String name() { return name; }
117
public String suffix() { return suffix; }
118
public Package pkg() { return pkg; }
119
public File file() { return file; }
120
public long lastModified() {
121
return lastModified;
122
}
123
124
public void setPackage(Package p) {
125
pkg = p;
126
}
127
128
public void markAsGenerated() {
129
isGenerated = true;
130
}
131
132
public boolean isGenerated() {
133
return isGenerated;
134
}
135
136
public void markAsLinkedOnly() {
137
linkedOnly = true;
138
}
139
140
public boolean isLinkedOnly() {
141
return linkedOnly;
142
}
143
144
private void save(StringBuilder b) {
145
String CL = linkedOnly?"L":"C";
146
String GS = isGenerated?"G":"S";
147
b.append(GS+" "+CL+" "+name+" "+file.lastModified()+"\n");
148
}
149
// Parse a line that looks like this:
150
// S C /code/alfa/A.java 1357631228000
151
public static Source load(Package lastPackage, String l, boolean isGenerated) {
152
int sp = l.indexOf(' ',4);
153
if (sp == -1) return null;
154
String name = l.substring(4,sp);
155
long last_modified = Long.parseLong(l.substring(sp+1));
156
157
boolean isLinkedOnly = false;
158
if (l.charAt(2) == 'L') {
159
isLinkedOnly = true;
160
} else if (l.charAt(2) == 'C') {
161
isLinkedOnly = false;
162
} else return null;
163
164
Source s = new Source(lastPackage, name, last_modified);
165
s.file = new File(name);
166
if (isGenerated) s.markAsGenerated();
167
if (isLinkedOnly) s.markAsLinkedOnly();
168
return s;
169
}
170
171
public static void saveSources(Map<String,Source> sources, StringBuilder b) {
172
List<String> sorted_sources = new ArrayList<>();
173
for (String key : sources.keySet()) {
174
sorted_sources.add(key);
175
}
176
Collections.sort(sorted_sources);
177
for (String key : sorted_sources) {
178
Source s = sources.get(key);
179
s.save(b);
180
}
181
}
182
183
/**
184
* Recurse into the directory root and find all files matching the excl/incl/exclfiles/inclfiles rules.
185
* Detects the existence of module-info.java files and presumes that the directory it resides in
186
* is the name of the current module.
187
*/
188
public static void scanRoot(File root,
189
Set<String> suffixes,
190
List<String> excludes,
191
List<String> includes,
192
Map<String,Source> foundFiles,
193
Map<String,Module> foundModules,
194
final Module currentModule,
195
boolean permitSourcesWithoutPackage,
196
boolean inGensrc,
197
boolean inLinksrc)
198
throws IOException, ProblemException {
199
200
if (root == null)
201
return;
202
203
FileSystem fs = root.toPath().getFileSystem();
204
205
if (includes.isEmpty()) {
206
includes = Collections.singletonList("**");
207
}
208
209
List<PathMatcher> includeMatchers = createPathMatchers(fs, includes);
210
List<PathMatcher> excludeMatchers = createPathMatchers(fs, excludes);
211
212
Files.walkFileTree(root.toPath(), new SimpleFileVisitor<Path>() {
213
@Override
214
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
215
216
Path relToRoot = root.toPath().relativize(file);
217
218
if (includeMatchers.stream().anyMatch(im -> im.matches(relToRoot))
219
&& excludeMatchers.stream().noneMatch(em -> em.matches(relToRoot))
220
&& suffixes.contains(Util.fileSuffix(file))) {
221
222
// TODO: Test this.
223
Source existing = foundFiles.get(file);
224
if (existing != null) {
225
throw new IOException("You have already added the file "+file+" from "+existing.file().getPath());
226
}
227
existing = currentModule.lookupSource(file.toString());
228
if (existing != null) {
229
230
// Oops, the source is already added, could be ok, could be not, let's check.
231
if (inLinksrc) {
232
// So we are collecting sources for linking only.
233
if (existing.isLinkedOnly()) {
234
// Ouch, this one is also for linking only. Bad.
235
throw new IOException("You have already added the link only file " + file + " from " + existing.file().getPath());
236
}
237
// Ok, the existing source is to be compiled. Thus this link only is redundant
238
// since all compiled are also linked to. Continue to the next source.
239
// But we need to add the source, so that it will be visible to linking,
240
// if not the multi core compile will fail because a JavaCompiler cannot
241
// find the necessary dependencies for its part of the source.
242
foundFiles.put(file.toString(), existing);
243
} else {
244
// We are looking for sources to compile, if we find an existing to be compiled
245
// source with the same name, it is an internal error, since we must
246
// find the sources to be compiled before we find the sources to be linked to.
247
throw new IOException("Internal error: Double add of file " + file + " from " + existing.file().getPath());
248
}
249
250
} else {
251
252
//////////////////////////////////////////////////////////////
253
// Add source
254
Source s = new Source(currentModule, file.toString(), file.toFile());
255
if (inGensrc) {
256
s.markAsGenerated();
257
}
258
if (inLinksrc) {
259
s.markAsLinkedOnly();
260
}
261
String pkg = packageOfJavaFile(root.toPath(), file);
262
pkg = currentModule.name() + ":" + pkg;
263
foundFiles.put(file.toString(), s);
264
currentModule.addSource(pkg, s);
265
//////////////////////////////////////////////////////////////
266
}
267
}
268
269
return FileVisitResult.CONTINUE;
270
}
271
});
272
}
273
274
private static List<PathMatcher> createPathMatchers(FileSystem fs, List<String> patterns) {
275
List<PathMatcher> matchers = new ArrayList<>();
276
for (String pattern : patterns) {
277
try {
278
matchers.add(fs.getPathMatcher("glob:" + pattern));
279
} catch (PatternSyntaxException e) {
280
Log.error("Invalid pattern: " + pattern);
281
throw e;
282
}
283
}
284
return matchers;
285
}
286
287
private static String packageOfJavaFile(Path sourceRoot, Path javaFile) {
288
Path javaFileDir = javaFile.getParent();
289
Path packageDir = sourceRoot.relativize(javaFileDir);
290
List<String> separateDirs = new ArrayList<>();
291
for (Path pathElement : packageDir) {
292
separateDirs.add(pathElement.getFileName().toString());
293
}
294
return String.join(".", separateDirs);
295
}
296
297
@Override
298
public String toString() {
299
return String.format("%s[pkg: %s, name: %s, suffix: %s, file: %s, isGenerated: %b, linkedOnly: %b]",
300
getClass().getSimpleName(),
301
pkg,
302
name,
303
suffix,
304
file,
305
isGenerated,
306
linkedOnly);
307
}
308
}
309
310