author | jjg |
Tue, 22 Nov 2016 15:57:32 -0800 | |
changeset 42269 | 24a766b7c106 |
parent 41932 | b23b4712933b |
child 42822 | a84956e7ee4d |
permissions | -rw-r--r-- |
36526 | 1 |
/* |
2 |
* Copyright (c) 2015, 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. |
|
8 |
* |
|
9 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
10 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
11 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
12 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
13 |
* accompanied this code). |
|
14 |
* |
|
15 |
* You should have received a copy of the GNU General Public License version |
|
16 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
17 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
18 |
* |
|
19 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
20 |
* or visit www.oracle.com if you need additional information or have any |
|
21 |
* questions. |
|
22 |
*/ |
|
23 |
||
24 |
/** |
|
25 |
* @test |
|
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
26 |
* @summary Test --add-modules and --limit-modules; also test the "enabled" modules. |
36526 | 27 |
* @library /tools/lib |
28 |
* @modules |
|
29 |
* jdk.compiler/com.sun.tools.javac.api |
|
30 |
* jdk.compiler/com.sun.tools.javac.code |
|
31 |
* jdk.compiler/com.sun.tools.javac.main |
|
32 |
* jdk.compiler/com.sun.tools.javac.model |
|
33 |
* jdk.compiler/com.sun.tools.javac.processing |
|
34 |
* jdk.compiler/com.sun.tools.javac.util |
|
35 |
* jdk.jdeps/com.sun.tools.javap |
|
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
36 |
* @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask toolbox.JavaTask ModuleTestBase |
36526 | 37 |
* @run main AddLimitMods |
38 |
*/ |
|
39 |
||
40 |
import java.io.File; |
|
41 |
import java.nio.file.Files; |
|
42 |
import java.nio.file.Path; |
|
37848
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
43 |
import java.util.AbstractMap.SimpleEntry; |
36526 | 44 |
import java.util.ArrayList; |
45 |
import java.util.Arrays; |
|
46 |
import java.util.Collections; |
|
47 |
import java.util.HashSet; |
|
48 |
import java.util.LinkedHashMap; |
|
49 |
import java.util.List; |
|
50 |
import java.util.Map; |
|
51 |
import java.util.Map.Entry; |
|
52 |
import java.util.Objects; |
|
53 |
import java.util.Set; |
|
54 |
||
55 |
import javax.annotation.processing.AbstractProcessor; |
|
56 |
import javax.annotation.processing.RoundEnvironment; |
|
57 |
import javax.annotation.processing.SupportedAnnotationTypes; |
|
58 |
import javax.annotation.processing.SupportedOptions; |
|
59 |
import javax.lang.model.SourceVersion; |
|
60 |
import javax.lang.model.element.ModuleElement; |
|
61 |
import javax.lang.model.element.TypeElement; |
|
62 |
||
63 |
import com.sun.tools.javac.code.Symbol.ClassSymbol; |
|
64 |
import com.sun.tools.javac.code.Symtab; |
|
65 |
import com.sun.tools.javac.model.JavacElements; |
|
66 |
import com.sun.tools.javac.processing.JavacProcessingEnvironment; |
|
67 |
import com.sun.tools.javac.util.Context; |
|
68 |
||
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
69 |
import toolbox.JarTask; |
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
70 |
import toolbox.JavacTask; |
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
71 |
import toolbox.JavaTask; |
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
72 |
import toolbox.Task; |
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
73 |
|
36526 | 74 |
public class AddLimitMods extends ModuleTestBase { |
75 |
||
76 |
public static void main(String... args) throws Exception { |
|
77 |
AddLimitMods t = new AddLimitMods(); |
|
78 |
t.runTests(); |
|
79 |
} |
|
80 |
||
81 |
@Test |
|
37758 | 82 |
public void testManual(Path base) throws Exception { |
36526 | 83 |
Path moduleSrc = base.resolve("module-src"); |
84 |
Path m1 = moduleSrc.resolve("m1"); |
|
85 |
||
86 |
tb.writeJavaFiles(m1, |
|
87 |
"module m1 { requires m2; requires m3; }"); |
|
88 |
||
89 |
Path m2 = moduleSrc.resolve("m2"); |
|
90 |
||
91 |
tb.writeJavaFiles(m2, |
|
92 |
"module m2 { requires m3; exports m2; }", |
|
93 |
"package m2; public class M2 {}"); |
|
94 |
||
95 |
Path m3 = moduleSrc.resolve("m3"); |
|
96 |
||
97 |
tb.writeJavaFiles(m3, |
|
98 |
"module m3 { exports m3; }", |
|
99 |
"package m3; public class M3 {}"); |
|
100 |
||
101 |
Path modulePath = base.resolve("module-path"); |
|
102 |
||
103 |
Files.createDirectories(modulePath); |
|
104 |
||
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
105 |
new JavacTask(tb) |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
106 |
.options("--module-source-path", moduleSrc.toString()) |
36526 | 107 |
.outdir(modulePath) |
108 |
.files(findJavaFiles(m3)) |
|
109 |
.run() |
|
110 |
.writeAll(); |
|
111 |
||
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
112 |
new JavacTask(tb) |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
113 |
.options("--module-source-path", moduleSrc.toString()) |
36526 | 114 |
.outdir(modulePath) |
115 |
.files(findJavaFiles(m2)) |
|
116 |
.run() |
|
117 |
.writeAll(); |
|
118 |
||
119 |
//real test |
|
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
120 |
new JavacTask(tb) |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
121 |
.options("--module-path", modulePath.toString(), |
40835
6ab9ed1abc46
8162546: change hidden options -Xdebug to --debug, -XshouldStop to --should-stop, and -diags to --diags
vromero
parents:
40308
diff
changeset
|
122 |
"--should-stop:ifNoError=FLOW", |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
123 |
"--limit-modules", "java.base") |
36526 | 124 |
.outdir(modulePath) |
125 |
.files(findJavaFiles(m1)) |
|
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
126 |
.run(Task.Expect.FAIL) |
36526 | 127 |
.writeAll(); |
128 |
||
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
129 |
new JavacTask(tb) |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
130 |
.options("--module-path", modulePath.toString(), |
40835
6ab9ed1abc46
8162546: change hidden options -Xdebug to --debug, -XshouldStop to --should-stop, and -diags to --diags
vromero
parents:
40308
diff
changeset
|
131 |
"--should-stop:ifNoError=FLOW", |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
132 |
"--limit-modules", "java.base", |
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
133 |
"--add-modules", "m2") |
36526 | 134 |
.outdir(modulePath) |
135 |
.files(findJavaFiles(m1)) |
|
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
136 |
.run(Task.Expect.FAIL) |
36526 | 137 |
.writeAll(); |
138 |
||
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
139 |
new JavacTask(tb) |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
140 |
.options("--module-path", modulePath.toString(), |
40835
6ab9ed1abc46
8162546: change hidden options -Xdebug to --debug, -XshouldStop to --should-stop, and -diags to --diags
vromero
parents:
40308
diff
changeset
|
141 |
"--should-stop:ifNoError=FLOW", |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
142 |
"--limit-modules", "java.base", |
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
143 |
"--add-modules", "m2,m3") |
36526 | 144 |
.outdir(modulePath) |
145 |
.files(findJavaFiles(m1)) |
|
146 |
.run() |
|
147 |
.writeAll(); |
|
148 |
||
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
149 |
new JavacTask(tb) |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
150 |
.options("--module-path", modulePath.toString(), |
40835
6ab9ed1abc46
8162546: change hidden options -Xdebug to --debug, -XshouldStop to --should-stop, and -diags to --diags
vromero
parents:
40308
diff
changeset
|
151 |
"--should-stop:ifNoError=FLOW", |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
152 |
"--limit-modules", "m2") |
36526 | 153 |
.outdir(modulePath) |
154 |
.files(findJavaFiles(m1)) |
|
155 |
.run() |
|
156 |
.writeAll(); |
|
157 |
||
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
158 |
new JavacTask(tb) |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
159 |
.options("--module-path", modulePath.toString(), |
40835
6ab9ed1abc46
8162546: change hidden options -Xdebug to --debug, -XshouldStop to --should-stop, and -diags to --diags
vromero
parents:
40308
diff
changeset
|
160 |
"--should-stop:ifNoError=FLOW", |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
161 |
"--limit-modules", "m3") |
36526 | 162 |
.outdir(modulePath) |
163 |
.files(findJavaFiles(m1)) |
|
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
164 |
.run(Task.Expect.FAIL) |
36526 | 165 |
.writeAll(); |
166 |
||
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
167 |
new JavacTask(tb) |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
168 |
.options("--module-path", modulePath.toString(), |
40835
6ab9ed1abc46
8162546: change hidden options -Xdebug to --debug, -XshouldStop to --should-stop, and -diags to --diags
vromero
parents:
40308
diff
changeset
|
169 |
"--should-stop:ifNoError=FLOW", |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
170 |
"--limit-modules", "m3", |
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
171 |
"--add-modules", "m2") |
36526 | 172 |
.outdir(modulePath) |
173 |
.files(findJavaFiles(m1)) |
|
174 |
.run() |
|
175 |
.writeAll(); |
|
176 |
} |
|
177 |
||
178 |
@Test |
|
37849 | 179 |
public void testObservableForUnnamed(Path base) throws Exception { |
37848
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
180 |
Path src = base.resolve("src"); |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
181 |
|
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
182 |
tb.writeJavaFiles(src, |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
183 |
"package test;\n" + |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
184 |
"@javax.annotation.Generated(\"test\")\n" + |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
185 |
"public class Test {\n" + |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
186 |
" com.sun.tools.javac.Main m;\n" + |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
187 |
" javax.xml.bind.JAXBException e;\n" + |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
188 |
"}\n"); |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
189 |
|
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
190 |
Path out = base.resolve("out"); |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
191 |
|
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
192 |
Files.createDirectories(out); |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
193 |
|
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
194 |
for (Entry<String[], String> variant : variants) { |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
195 |
System.err.println("running variant: options=" + Arrays.asList(variant.getKey()) + ", expected log: " + variant.getValue()); |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
196 |
|
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
197 |
List<String> options = new ArrayList<>(); |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
198 |
options.add("-XDrawDiagnostics"); |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
199 |
options.addAll(Arrays.asList(variant.getKey())); |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
200 |
|
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
201 |
String log = new JavacTask(tb) |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
202 |
.options(options.toArray(new String[0])) |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
203 |
.outdir(out) |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
204 |
.files(findJavaFiles(src)) |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
205 |
.run(variant.getValue() == null ? Task.Expect.SUCCESS : Task.Expect.FAIL) |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
206 |
.writeAll() |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
207 |
.getOutput(Task.OutputKind.DIRECT); |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
208 |
|
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
209 |
log = log.replace(System.getProperty("line.separator"), "\n"); |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
210 |
|
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
211 |
if (variant.getValue() != null && !log.equals(variant.getValue())) { |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
212 |
throw new AssertionError(); |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
213 |
} |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
214 |
} |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
215 |
} |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
216 |
|
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
217 |
private static final List<Entry<String[], String>> variants = Arrays.asList( |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
218 |
new SimpleEntry<String[], String>(new String[] {}, |
41932 | 219 |
"Test.java:2:18: compiler.err.doesnt.exist: javax.annotation\n" |
220 |
+ "Test.java:5:19: compiler.err.doesnt.exist: javax.xml.bind\n" |
|
37848
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
221 |
+ "2 errors\n"), |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
222 |
new SimpleEntry<String[], String>(new String[] {"--add-modules", "java.annotations.common,java.xml.bind"}, |
37848
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
223 |
null), |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
224 |
new SimpleEntry<String[], String>(new String[] {"--limit-modules", "java.xml.ws,jdk.compiler"}, |
37848
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
225 |
null), |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
226 |
new SimpleEntry<String[], String>(new String[] {"--add-modules", "ALL-SYSTEM"}, |
37848
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
227 |
null) |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
228 |
); |
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
229 |
|
3c8ff4204d2d
8154956: Module system implementation refresh (4/2016)
alanb
parents:
36994
diff
changeset
|
230 |
@Test |
37758 | 231 |
public void testAllModulePath(Path base) throws Exception { |
36526 | 232 |
if (Files.isDirectory(base)) |
233 |
tb.cleanDirectory(base); |
|
234 |
||
235 |
Path moduleSrc = base.resolve("module-src"); |
|
236 |
Path m1 = moduleSrc.resolve("m1"); |
|
237 |
||
238 |
tb.writeJavaFiles(m1, |
|
239 |
"module m1 { exports api; }", |
|
240 |
"package api; public class Api { }"); |
|
241 |
||
242 |
Path modulePath = base.resolve("module-path"); |
|
243 |
||
244 |
Files.createDirectories(modulePath); |
|
245 |
||
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
246 |
new JavacTask(tb) |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
247 |
.options("--module-source-path", moduleSrc.toString()) |
36526 | 248 |
.outdir(modulePath) |
249 |
.files(findJavaFiles(moduleSrc)) |
|
250 |
.run() |
|
251 |
.writeAll(); |
|
252 |
||
253 |
Path cpSrc = base.resolve("cp-src"); |
|
254 |
tb.writeJavaFiles(cpSrc, "package test; public class Test { api.Api api; }"); |
|
255 |
||
256 |
Path cpOut = base.resolve("cp-out"); |
|
257 |
||
258 |
Files.createDirectories(cpOut); |
|
259 |
||
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
260 |
new JavacTask(tb) |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
261 |
.options("--module-path", modulePath.toString()) |
36526 | 262 |
.outdir(cpOut) |
263 |
.files(findJavaFiles(cpSrc)) |
|
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
264 |
.run(Task.Expect.FAIL) |
36526 | 265 |
.writeAll(); |
266 |
||
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
267 |
new JavacTask(tb) |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
268 |
.options("--module-path", modulePath.toString(), |
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
269 |
"--add-modules", "ALL-MODULE-PATH") |
36526 | 270 |
.outdir(cpOut) |
271 |
.files(findJavaFiles(cpSrc)) |
|
272 |
.run() |
|
273 |
.writeAll(); |
|
274 |
||
275 |
List<String> actual; |
|
276 |
List<String> expected = Arrays.asList( |
|
277 |
"- compiler.err.addmods.all.module.path.invalid", |
|
278 |
"1 error"); |
|
279 |
||
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
280 |
actual = new JavacTask(tb) |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
281 |
.options("--module-source-path", moduleSrc.toString(), |
36526 | 282 |
"-XDrawDiagnostics", |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
283 |
"--add-modules", "ALL-MODULE-PATH") |
36526 | 284 |
.outdir(modulePath) |
285 |
.files(findJavaFiles(moduleSrc)) |
|
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
286 |
.run(Task.Expect.FAIL) |
36526 | 287 |
.writeAll() |
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
288 |
.getOutputLines(Task.OutputKind.DIRECT); |
36526 | 289 |
|
290 |
if (!Objects.equals(actual, expected)) { |
|
291 |
throw new IllegalStateException("incorrect errors; actual=" + actual + "; expected=" + expected); |
|
292 |
} |
|
293 |
||
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
294 |
actual = new JavacTask(tb) |
36526 | 295 |
.options("-Xmodule:java.base", |
296 |
"-XDrawDiagnostics", |
|
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
297 |
"--add-modules", "ALL-MODULE-PATH") |
36526 | 298 |
.outdir(cpOut) |
299 |
.files(findJavaFiles(cpSrc)) |
|
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
300 |
.run(Task.Expect.FAIL) |
36526 | 301 |
.writeAll() |
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
302 |
.getOutputLines(Task.OutputKind.DIRECT); |
36526 | 303 |
|
304 |
if (!Objects.equals(actual, expected)) { |
|
305 |
throw new IllegalStateException("incorrect errors; actual=" + actual + "; expected=" + expected); |
|
306 |
} |
|
307 |
||
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
308 |
actual = new JavacTask(tb, Task.Mode.CMDLINE) |
36526 | 309 |
.options("-source", "8", "-target", "8", |
310 |
"-XDrawDiagnostics", |
|
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
311 |
"--add-modules", "ALL-MODULE-PATH") |
36526 | 312 |
.outdir(cpOut) |
313 |
.files(findJavaFiles(cpSrc)) |
|
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
314 |
.run(Task.Expect.FAIL) |
36526 | 315 |
.writeAll() |
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
316 |
.getOutputLines(Task.OutputKind.DIRECT); |
36526 | 317 |
|
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
318 |
if (!actual.contains("javac: option --add-modules not allowed with target 1.8")) { |
36526 | 319 |
throw new IllegalStateException("incorrect errors; actual=" + actual); |
320 |
} |
|
321 |
||
322 |
tb.writeJavaFiles(cpSrc, "module m1 {}"); |
|
323 |
||
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
324 |
actual = new JavacTask(tb) |
36526 | 325 |
.options("-XDrawDiagnostics", |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
326 |
"--add-modules", "ALL-MODULE-PATH") |
36526 | 327 |
.outdir(cpOut) |
328 |
.files(findJavaFiles(cpSrc)) |
|
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
329 |
.run(Task.Expect.FAIL) |
36526 | 330 |
.writeAll() |
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
331 |
.getOutputLines(Task.OutputKind.DIRECT); |
36526 | 332 |
|
333 |
if (!Objects.equals(actual, expected)) { |
|
334 |
throw new IllegalStateException("incorrect errors; actual=" + actual + "; expected=" + expected); |
|
335 |
} |
|
336 |
} |
|
337 |
||
338 |
@Test |
|
37758 | 339 |
public void testRuntime2Compile(Path base) throws Exception { |
36526 | 340 |
Path classpathSrc = base.resolve("classpath-src"); |
341 |
Path classpathOut = base.resolve("classpath-out"); |
|
342 |
||
343 |
tb.writeJavaFiles(classpathSrc, |
|
344 |
generateCheckAccessibleClass("cp.CP")); |
|
345 |
||
346 |
Files.createDirectories(classpathOut); |
|
347 |
||
41448 | 348 |
System.err.println("Compiling classpath-src files:"); |
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
349 |
new JavacTask(tb) |
36526 | 350 |
.outdir(classpathOut) |
351 |
.files(findJavaFiles(classpathSrc)) |
|
352 |
.run() |
|
353 |
.writeAll() |
|
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
354 |
.getOutput(Task.OutputKind.DIRECT); |
36526 | 355 |
|
356 |
Path automaticSrc = base.resolve("automatic-src"); |
|
357 |
Path automaticOut = base.resolve("automatic-out"); |
|
358 |
||
359 |
tb.writeJavaFiles(automaticSrc, |
|
360 |
generateCheckAccessibleClass("automatic.Automatic")); |
|
361 |
||
362 |
Files.createDirectories(automaticOut); |
|
363 |
||
41448 | 364 |
System.err.println("Compiling automatic-src files:"); |
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
365 |
new JavacTask(tb) |
36526 | 366 |
.outdir(automaticOut) |
367 |
.files(findJavaFiles(automaticSrc)) |
|
368 |
.run() |
|
369 |
.writeAll() |
|
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
370 |
.getOutput(Task.OutputKind.DIRECT); |
36526 | 371 |
|
372 |
Path modulePath = base.resolve("module-path"); |
|
373 |
||
374 |
Files.createDirectories(modulePath); |
|
375 |
||
376 |
Path automaticJar = modulePath.resolve("automatic.jar"); |
|
377 |
||
41448 | 378 |
System.err.println("Creating automatic.jar:"); |
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
379 |
new JarTask(tb, automaticJar) |
36526 | 380 |
.baseDir(automaticOut) |
381 |
.files("automatic/Automatic.class") |
|
382 |
.run(); |
|
383 |
||
384 |
Path moduleSrc = base.resolve("module-src"); |
|
385 |
Path m1 = moduleSrc.resolve("m1"); |
|
386 |
||
387 |
tb.writeJavaFiles(m1, |
|
388 |
"module m1 { exports api; }", |
|
389 |
"package api; public class Api { public void test() { } }"); |
|
390 |
||
41448 | 391 |
System.err.println("Compiling module-src files:"); |
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
392 |
new JavacTask(tb) |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
393 |
.options("--module-source-path", moduleSrc.toString()) |
36526 | 394 |
.outdir(modulePath) |
395 |
.files(findJavaFiles(moduleSrc)) |
|
396 |
.run() |
|
397 |
.writeAll() |
|
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
398 |
.getOutput(Task.OutputKind.DIRECT); |
36526 | 399 |
|
400 |
int index = 0; |
|
401 |
||
402 |
for (String moduleInfo : MODULE_INFO_VARIANTS) { |
|
403 |
for (String[] options : OPTIONS_VARIANTS) { |
|
404 |
index++; |
|
405 |
||
41448 | 406 |
System.err.println("Running check: " + moduleInfo + "; " + Arrays.asList(options)); |
36526 | 407 |
|
408 |
Path m2Runtime = base.resolve(index + "-runtime").resolve("m2"); |
|
409 |
Path out = base.resolve(index + "-runtime").resolve("out").resolve("m2"); |
|
410 |
||
411 |
Files.createDirectories(out); |
|
412 |
||
413 |
StringBuilder testClassNamed = new StringBuilder(); |
|
414 |
||
415 |
testClassNamed.append("package test;\n" + |
|
416 |
"public class Test {\n" + |
|
417 |
" public static void main(String... args) throws Exception {\n"); |
|
418 |
||
419 |
for (Entry<String, String> e : MODULES_TO_CHECK_TO_SAMPLE_CLASS.entrySet()) { |
|
420 |
testClassNamed.append(" System.err.println(\"visible:" + e.getKey() + ":\" + java.lang.reflect.Layer.boot().findModule(\"" + e.getKey() + "\").isPresent());\n"); |
|
421 |
} |
|
422 |
||
423 |
testClassNamed.append(" Class<?> cp = Class.forName(Test.class.getClassLoader().getUnnamedModule(), \"cp.CP\");\n"); |
|
424 |
testClassNamed.append(" cp.getDeclaredMethod(\"runMe\").invoke(null);\n"); |
|
425 |
||
426 |
testClassNamed.append(" Class<?> automatic = Class.forName(java.lang.reflect.Layer.boot().findModule(\"automatic\").get(), \"automatic.Automatic\");\n"); |
|
427 |
testClassNamed.append(" automatic.getDeclaredMethod(\"runMe\").invoke(null);\n"); |
|
428 |
||
429 |
testClassNamed.append(" }\n" + |
|
430 |
"}"); |
|
431 |
||
432 |
tb.writeJavaFiles(m2Runtime, moduleInfo, testClassNamed.toString()); |
|
433 |
||
41448 | 434 |
System.err.println("Compiling " + m2Runtime + " files:"); |
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
435 |
new JavacTask(tb) |
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
436 |
.options("--module-path", modulePath.toString()) |
36526 | 437 |
.outdir(out) |
438 |
.files(findJavaFiles(m2Runtime)) |
|
439 |
.run() |
|
440 |
.writeAll(); |
|
441 |
||
442 |
boolean success; |
|
443 |
String output; |
|
444 |
||
445 |
try { |
|
41448 | 446 |
System.err.println("Running m2/test.Test:"); |
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
447 |
output = new JavaTask(tb) |
36526 | 448 |
.vmOptions(augmentOptions(options, |
449 |
Collections.emptyList(), |
|
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
450 |
"--module-path", modulePath.toString() + File.pathSeparator + out.getParent().toString(), |
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
451 |
"--class-path", classpathOut.toString(), |
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
452 |
"--add-reads", "m2=ALL-UNNAMED,automatic", |
36526 | 453 |
"-m", "m2/test.Test")) |
454 |
.run() |
|
455 |
.writeAll() |
|
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
456 |
.getOutput(Task.OutputKind.STDERR); |
36526 | 457 |
|
458 |
success = true; |
|
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
459 |
} catch (Task.TaskError err) { |
36526 | 460 |
success = false; |
461 |
output = ""; |
|
462 |
} |
|
463 |
||
464 |
Path m2 = base.resolve(String.valueOf(index)).resolve("m2"); |
|
465 |
||
466 |
tb.writeJavaFiles(m2, |
|
467 |
moduleInfo, |
|
468 |
"package test;\n" + |
|
469 |
"public class Test {}\n"); |
|
470 |
||
471 |
List<String> auxOptions = success ? Arrays.asList( |
|
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
472 |
"--processor-path", System.getProperty("test.class.path"), |
36526 | 473 |
"-processor", CheckVisibleModule.class.getName(), |
474 |
"-Aoutput=" + output, |
|
475 |
"-XDaccessInternalAPI=true" |
|
476 |
) : Collections.emptyList(); |
|
41448 | 477 |
|
478 |
System.err.println("Compiling/processing m2 files:"); |
|
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
479 |
new JavacTask(tb) |
36526 | 480 |
.options(augmentOptions(options, |
481 |
auxOptions, |
|
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
482 |
"--module-path", modulePath.toString(), |
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
483 |
"--class-path", classpathOut.toString(), |
40835
6ab9ed1abc46
8162546: change hidden options -Xdebug to --debug, -XshouldStop to --should-stop, and -diags to --diags
vromero
parents:
40308
diff
changeset
|
484 |
"--should-stop:ifNoError=FLOW")) |
36526 | 485 |
.outdir(modulePath) |
486 |
.files(findJavaFiles(m2)) |
|
36778
e04318f39f92
8152897: refactor ToolBox to allow reduced documented dependencies
jjg
parents:
36526
diff
changeset
|
487 |
.run(success ? Task.Expect.SUCCESS : Task.Expect.FAIL) |
36526 | 488 |
.writeAll(); |
489 |
} |
|
490 |
} |
|
491 |
} |
|
492 |
||
493 |
private String generateCheckAccessibleClass(String fqn) { |
|
494 |
String packageName = fqn.substring(0, fqn.lastIndexOf('.')); |
|
495 |
String simpleName = fqn.substring(fqn.lastIndexOf('.') + 1); |
|
496 |
StringBuilder checkClassesAccessible = new StringBuilder(); |
|
497 |
checkClassesAccessible.append("package " + packageName + ";" + |
|
498 |
"public class " + simpleName + " {" + |
|
499 |
" public static void runMe() throws Exception {"); |
|
500 |
for (Entry<String, String> e : MODULES_TO_CHECK_TO_SAMPLE_CLASS.entrySet()) { |
|
501 |
checkClassesAccessible.append("try {"); |
|
502 |
checkClassesAccessible.append("Class.forName(\"" + e.getValue() + "\").newInstance();"); |
|
503 |
checkClassesAccessible.append("System.err.println(\"" + fqn + ":" + e.getKey() + ":true\");"); |
|
504 |
checkClassesAccessible.append("} catch (Exception ex) {"); |
|
505 |
checkClassesAccessible.append("System.err.println(\"" + fqn + ":" + e.getKey() + ":false\");"); |
|
506 |
checkClassesAccessible.append("}"); |
|
507 |
} |
|
508 |
||
509 |
checkClassesAccessible.append(" }\n" + |
|
510 |
"}"); |
|
511 |
||
512 |
return checkClassesAccessible.toString(); |
|
513 |
} |
|
514 |
||
515 |
private static final Map<String, String> MODULES_TO_CHECK_TO_SAMPLE_CLASS = new LinkedHashMap<>(); |
|
516 |
||
517 |
static { |
|
518 |
MODULES_TO_CHECK_TO_SAMPLE_CLASS.put("m1", "api.Api"); |
|
519 |
MODULES_TO_CHECK_TO_SAMPLE_CLASS.put("m2", "test.Test"); |
|
520 |
MODULES_TO_CHECK_TO_SAMPLE_CLASS.put("java.base", "java.lang.Object"); |
|
521 |
}; |
|
522 |
||
523 |
@SupportedAnnotationTypes("*") |
|
524 |
@SupportedOptions("output") |
|
525 |
public static final class CheckVisibleModule extends AbstractProcessor { |
|
526 |
||
527 |
@Override |
|
528 |
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { |
|
529 |
String expected = processingEnv.getOptions().get("output"); |
|
530 |
Set<String> expectedElements = new HashSet<>(Arrays.asList(expected.split(System.getProperty("line.separator")))); |
|
531 |
Context context = ((JavacProcessingEnvironment) processingEnv).getContext(); |
|
532 |
Symtab syms = Symtab.instance(context); |
|
533 |
||
534 |
for (Entry<String, String> e : MODULES_TO_CHECK_TO_SAMPLE_CLASS.entrySet()) { |
|
535 |
String module = e.getKey(); |
|
536 |
ModuleElement mod = processingEnv.getElementUtils().getModuleElement(module); |
|
537 |
String visible = "visible:" + module + ":" + (mod != null); |
|
538 |
||
539 |
if (!expectedElements.contains(visible)) { |
|
540 |
throw new AssertionError("actual: " + visible + "; expected: " + expected); |
|
541 |
} |
|
542 |
||
543 |
JavacElements javacElements = JavacElements.instance(context); |
|
544 |
ClassSymbol unnamedClass = javacElements.getTypeElement(syms.unnamedModule, e.getValue()); |
|
545 |
String unnamed = "cp.CP:" + module + ":" + (unnamedClass != null); |
|
546 |
||
547 |
if (!expectedElements.contains(unnamed)) { |
|
548 |
throw new AssertionError("actual: " + unnamed + "; expected: " + expected); |
|
549 |
} |
|
550 |
||
551 |
ModuleElement automaticMod = processingEnv.getElementUtils().getModuleElement("automatic"); |
|
552 |
ClassSymbol automaticClass = javacElements.getTypeElement(automaticMod, e.getValue()); |
|
553 |
String automatic = "automatic.Automatic:" + module + ":" + (automaticClass != null); |
|
554 |
||
555 |
if (!expectedElements.contains(automatic)) { |
|
556 |
throw new AssertionError("actual: " + automatic + "; expected: " + expected); |
|
557 |
} |
|
558 |
} |
|
559 |
||
560 |
return false; |
|
561 |
} |
|
562 |
||
563 |
@Override |
|
564 |
public SourceVersion getSupportedSourceVersion() { |
|
565 |
return SourceVersion.latest(); |
|
566 |
} |
|
567 |
||
568 |
} |
|
569 |
||
570 |
public String[] augmentOptions(String[] options, List<String> auxOptions, String... baseOptions) { |
|
571 |
List<String> all = new ArrayList<>(); |
|
572 |
||
573 |
all.addAll(Arrays.asList(options)); |
|
574 |
all.addAll(Arrays.asList(baseOptions)); |
|
575 |
all.addAll(auxOptions); |
|
576 |
||
577 |
return all.toArray(new String[0]); |
|
578 |
} |
|
579 |
||
580 |
private static final String[] MODULE_INFO_VARIANTS = { |
|
581 |
"module m2 { exports test; }", |
|
41448 | 582 |
"module m2 { requires m1; exports test; }" |
36526 | 583 |
}; |
584 |
||
585 |
private static final String[][] OPTIONS_VARIANTS = { |
|
40308
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
586 |
{"--add-modules", "automatic"}, |
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
587 |
{"--add-modules", "m1,automatic"}, |
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
588 |
{"--add-modules", "jdk.compiler,automatic"}, |
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
589 |
{"--add-modules", "m1,jdk.compiler,automatic"}, |
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
590 |
{"--add-modules", "ALL-SYSTEM,automatic"}, |
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
591 |
{"--limit-modules", "java.base", "--add-modules", "automatic"}, |
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
592 |
{"--limit-modules", "java.base", "--add-modules", "ALL-SYSTEM,automatic"}, |
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
593 |
{"--limit-modules", "m2", "--add-modules", "automatic"}, |
274367a99f98
8136930: Simplify use of module-system options by custom launchers
jjg
parents:
39601
diff
changeset
|
594 |
{"--limit-modules", "jdk.compiler", "--add-modules", "automatic"}, |
36526 | 595 |
}; |
596 |
} |