Skip to content

Commit 62a5cde

Browse files
committed
[GR-41408] Report correct URL of LLVM reference manual, depending on version.
PullRequest: graal/13043
2 parents b11f838 + 7cff715 commit 62a5cde

File tree

10 files changed

+199
-7
lines changed

10 files changed

+199
-7
lines changed

sdk/src/org.graalvm.home.test/src/org/graalvm/home/test/VersionTest.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -195,6 +195,25 @@ public void testCompare() {
195195
}
196196
}
197197

198+
@Test
199+
public void testFormat() {
200+
assertFormat("%d.%d", "19.3", "19.3");
201+
assertFormat("%d.%d", "22.3.0.1", "22.3");
202+
assertFormat("%d.%d.%d", "22.3-dev", "22.3.0");
203+
assertFormat("%4$d", "22.3.0.2", "2");
204+
assertFormat("%[R%d.%d]%[Sdev]", "22.3.0.1", "22.3");
205+
assertFormat("%[R%d.%d]%[Sdev]", "22.3-dev", "dev");
206+
assertFormat("%[2XX]", "22.3", "XX");
207+
assertFormat("%[2XX]", "23.0", "");
208+
assertFormat("%%[R%d.%%d]", "23.0", "%[R23.%d]");
209+
}
210+
211+
private static void assertFormat(String format, String version, String expected) {
212+
Version v = Version.parse(version);
213+
String result = v.format(format);
214+
assertEquals(expected, result);
215+
}
216+
198217
private static void assertNPE(Runnable v) {
199218
try {
200219
v.run();

sdk/src/org.graalvm.home/snapshot.sigtest

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ meth public boolean isRelease()
3737
meth public boolean isSnapshot()
3838
meth public int compareTo(org.graalvm.home.Version)
3939
meth public int hashCode()
40+
meth public java.lang.String format(java.lang.String)
4041
meth public java.lang.String toString()
4142
meth public static org.graalvm.home.Version getCurrent()
4243
meth public static org.graalvm.home.Version parse(java.lang.String)

sdk/src/org.graalvm.home/src/org/graalvm/home/Version.java

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -250,6 +250,94 @@ public String toString() {
250250
return b.toString();
251251
}
252252

253+
private String processFormat(String format) {
254+
StringBuilder ret = new StringBuilder(format.length());
255+
int idx = 0;
256+
while (idx < format.length()) {
257+
char ch = format.charAt(idx++);
258+
if (ch == '%') {
259+
ch = format.charAt(idx++);
260+
if (ch == '[') {
261+
ch = format.charAt(idx++);
262+
boolean include = false;
263+
switch (ch) {
264+
case 'R':
265+
include = isRelease();
266+
break;
267+
case 'S':
268+
include = isSnapshot();
269+
break;
270+
default:
271+
if ('0' <= ch && ch <= '9') {
272+
int num = ch - '0';
273+
include = versions.length >= num;
274+
}
275+
}
276+
int start = idx;
277+
idx = format.indexOf(']', start);
278+
if (idx < 0) {
279+
idx = format.length();
280+
}
281+
if (include) {
282+
ret.append(format.substring(start, idx));
283+
}
284+
idx++; // skip closing ]
285+
} else {
286+
ret.append('%');
287+
ret.append(ch);
288+
}
289+
} else {
290+
ret.append(ch);
291+
}
292+
}
293+
return ret.toString();
294+
}
295+
296+
/**
297+
* Format the GraalVM version with a custom format string.
298+
* <p>
299+
* The format string can contain any of the standard conversions of {@link java.util.Formatter}.
300+
* At least four version components (possibly zero) are available as formatter arguments.
301+
* <p>
302+
* In addition to the standard conversions, these special conversions are available:
303+
* <ul>
304+
* <li>{@code "%[R...]"} includes a given part only if {@link #isRelease}
305+
* <li>{@code "%[S...]"} includes a given part only if {@link #isSnapshot}
306+
* <li>{@code "%[<digit>...]"} includes a given part only if the version contains at least
307+
* {@code <digit>} non-zero version components ({@code <digit>} can be 0 to 9)
308+
* </ul>
309+
*
310+
* <h3>Examples:</h3>
311+
*
312+
* <pre>
313+
* Version.parse("22.3.0.1").format("%d.%d"); // returns "22.3"
314+
* Version.parse("22.3.0.1").format("%4$d"); // returns "1"
315+
* Version.parse("22.3.0.1").format("%[R%d.%d]%[Sdev]"); // returns "22.3"
316+
* Version.parse("22.3.0.1").format("%[2XX]"); // returns "XX"
317+
* Version.parse("23.0-dev").format("%3$d"); // returns "0"
318+
* Version.parse("23.0-dev").format("%[R%d.%d]%[Sdev]"); // returns "dev"
319+
* Version.parse("23.0-dev").format("%[2XX]"); // returns ""
320+
* </pre>
321+
*
322+
* @since 23.0
323+
*/
324+
public String format(String format) {
325+
int len = versions.length;
326+
if (len < 4) {
327+
len = 4;
328+
}
329+
Object[] args = new Object[len];
330+
int i = 0;
331+
for (int v : versions) {
332+
args[i++] = v;
333+
}
334+
for (; i < len; i++) {
335+
args[i] = 0;
336+
}
337+
338+
return String.format(processFormat(format), args);
339+
}
340+
253341
/**
254342
* Parses a GraalVM version from its String raw format. Throws {@link IllegalArgumentException}
255343
* if the passed string is not a valid GraalVM version.

sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/LLVMLanguage.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@
9696
byteMimeTypes = {LLVMLanguage.LLVM_BITCODE_MIME_TYPE, LLVMLanguage.LLVM_ELF_SHARED_MIME_TYPE, LLVMLanguage.LLVM_ELF_EXEC_MIME_TYPE, LLVMLanguage.LLVM_MACHO_MIME_TYPE,
9797
LLVMLanguage.LLVM_MS_DOS_MIME_TYPE}, //
9898
fileTypeDetectors = LLVMFileDetector.class, services = {Toolchain.class}, version = LLVMConfig.VERSION, contextPolicy = TruffleLanguage.ContextPolicy.SHARED, //
99-
website = "https://www.graalvm.org/22.1/reference-manual/llvm/")
99+
website = "https://www.graalvm.org/${graalvm-website-version}/reference-manual/llvm/")
100100
@ProvidedTags({StandardTags.StatementTag.class, StandardTags.CallTag.class, StandardTags.RootTag.class, StandardTags.RootBodyTag.class, DebuggerTags.AlwaysHalt.class})
101101
public class LLVMLanguage extends TruffleLanguage<LLVMContext> {
102102

truffle/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ This changelog summarizes major changes between Truffle versions relevant to lan
66
* GR-38526 Added `TruffleLanguage.Env#isSocketIOAllowed()`. The method returns true if access to network sockets is allowed.
77
* GR-41634 Added `TruffleLanguage.Env#isFileIOAllowed()`. The method returns true if access to files is allowed.
88
* Deprecated `TruffleLanguage.Env#isIOAllowed()`. To migrate, use `TruffleLanguage.Env#isFileIOAllowed()`.
9+
* GR-41408 Added `Version.format(String)`, to support formatting the version using a custom format string, e.g. for use in URLs.
10+
* GR-41408 Added `${graalvm-version}` and `${graalvm-website-version}` substitutions for the `website` property of language and instrument registrations.
911

1012
* GR-41034 Added `TruffleInstrument.Env.getTruffleFile(TruffleContext, ...)` methods to allow reading a truffle file from a specific context without being entered. Deprecated `TruffleInstrument.Env.getTruffleFile(...)` methods that do not take the `TruffleContext`.
1113

truffle/src/com.oracle.truffle.api.instrumentation/src/com/oracle/truffle/api/instrumentation/TruffleInstrument.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
import java.util.concurrent.atomic.AtomicBoolean;
6666
import java.util.function.Consumer;
6767

68+
import org.graalvm.home.Version;
6869
import org.graalvm.options.OptionDescriptor;
6970
import org.graalvm.options.OptionDescriptors;
7071
import org.graalvm.options.OptionValues;
@@ -1310,6 +1311,16 @@ Class<?>[] services() default {
13101311
/**
13111312
* A link to a website with more information about the instrument. Will be shown in the help
13121313
* text of GraalVM launchers.
1314+
* <p>
1315+
* The link can contain the following substitutions:
1316+
* <dl>
1317+
* <dt>{@code ${graalvm-version}}</dt>
1318+
* <dd>the current GraalVM version. Optionally, a format string can be provided for the
1319+
* version using {@code ${graalvm-version:format}}. See {@link Version#format}.
1320+
* <dt>{@code ${graalvm-website-version}}</dt>
1321+
* <dd>the current GraalVM version in a format suitable for links to the GraalVM reference
1322+
* manual. The exact format may change without notice.</dd>
1323+
* </dl>
13131324
*
13141325
* @since 22.1.0
13151326
*/

truffle/src/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/polyglot/LanguageSPITest.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -135,6 +135,7 @@
135135
import com.oracle.truffle.api.test.polyglot.LanguageSPITestLanguage.LanguageContext;
136136
import com.oracle.truffle.tck.tests.TruffleTestAssumptions;
137137
import com.oracle.truffle.tck.tests.ValueAssert;
138+
import org.graalvm.home.Version;
138139

139140
public class LanguageSPITest {
140141

@@ -3181,6 +3182,27 @@ public void testInheritedVersionLanguage() {
31813182
context.close();
31823183
}
31833184

3185+
static final String WEBSITE_TEST = "SPIWebsiteLanguage";
3186+
3187+
@TruffleLanguage.Registration(id = WEBSITE_TEST, name = "", website = "https://graalvm.org/test/${graalvm-website-version}")
3188+
public static class WebsiteLanguage extends ProxyLanguage {
3189+
3190+
public WebsiteLanguage() {
3191+
wrapper = false;
3192+
}
3193+
}
3194+
3195+
@Test
3196+
public void testWebsiteLanguage() {
3197+
TruffleTestAssumptions.assumeWeakEncapsulation();
3198+
3199+
Context context = Context.create();
3200+
context.initialize(WEBSITE_TEST);
3201+
final Engine engine = context.getEngine();
3202+
assertEquals(Version.getCurrent().format("https://graalvm.org/test/%[R%d.%d]%[Sdev]"), engine.getLanguages().get(WEBSITE_TEST).getWebsite());
3203+
context.close();
3204+
}
3205+
31843206
@SuppressWarnings("serial")
31853207
static class TestError extends RuntimeException {
31863208
}

truffle/src/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
import java.util.function.Predicate;
7575
import java.util.logging.Level;
7676

77+
import org.graalvm.home.Version;
7778
import org.graalvm.options.OptionCategory;
7879
import org.graalvm.options.OptionDescriptor;
7980
import org.graalvm.options.OptionDescriptors;
@@ -483,8 +484,18 @@ String[] dependentLanguages() default {
483484
boolean needsAllEncodings() default false;
484485

485486
/**
486-
* A link to a website with more information about the instrument. Will be shown in the help
487+
* A link to a website with more information about the language. Will be shown in the help
487488
* text of GraalVM launchers.
489+
* <p>
490+
* The link can contain the following substitutions:
491+
* <dl>
492+
* <dt>{@code ${graalvm-version}}</dt>
493+
* <dd>the current GraalVM version. Optionally, a format string can be provided for the
494+
* version using {@code ${graalvm-version:format}}. See {@link Version#format}.
495+
* <dt>{@code ${graalvm-website-version}}</dt>
496+
* <dd>the current GraalVM version in a format suitable for links to the GraalVM reference
497+
* manual. The exact format may change without notice.</dd>
498+
* </dl>
488499
*
489500
* @since 22.1.0
490501
* @return URL for language website.

truffle/src/com.oracle.truffle.polyglot/src/com/oracle/truffle/polyglot/PolyglotInstrument.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,6 @@ public String getVersion() {
249249
}
250250

251251
public String getWebsite() {
252-
return cache.getWebsite();
252+
return PolyglotLanguage.websiteSubstitutions(cache.getWebsite());
253253
}
254254
}

truffle/src/com.oracle.truffle.polyglot/src/com/oracle/truffle/polyglot/PolyglotLanguage.java

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
5555
import com.oracle.truffle.api.nodes.LanguageInfo;
5656
import com.oracle.truffle.polyglot.PolyglotLocals.LocalLocation;
57+
import org.graalvm.home.Version;
5758

5859
final class PolyglotLanguage implements com.oracle.truffle.polyglot.PolyglotImpl.VMObject {
5960

@@ -266,7 +267,44 @@ boolean assertCorrectEngine() {
266267
return true;
267268
}
268269

270+
static String websiteSubstitutions(String template) {
271+
if (template.indexOf('$') < 0) {
272+
return template;
273+
}
274+
275+
StringBuilder ret = new StringBuilder();
276+
int i = 0;
277+
while (i < template.length()) {
278+
char ch = template.charAt(i);
279+
if (ch == '$' && template.charAt(i + 1) == '{') {
280+
int end = template.indexOf('}', i + 2);
281+
if (end >= 0) {
282+
String[] cmd = template.substring(i + 2, end).split(":", 2);
283+
Version v = Version.getCurrent();
284+
switch (cmd[0]) {
285+
case "graalvm-version":
286+
if (cmd.length == 1) {
287+
ret.append(v);
288+
} else {
289+
ret.append(v.format(cmd[1]));
290+
}
291+
break;
292+
case "graalvm-website-version":
293+
ret.append(v.format("%[R%d.%d]%[Sdev]"));
294+
break;
295+
}
296+
i = end + 1;
297+
continue;
298+
}
299+
}
300+
301+
ret.append(ch);
302+
i++;
303+
}
304+
return ret.toString();
305+
}
306+
269307
String getWebsite() {
270-
return cache.getWebsite();
308+
return websiteSubstitutions(cache.getWebsite());
271309
}
272310
}

0 commit comments

Comments
 (0)