diff --git a/.vscode/launch.json b/.vscode/launch.json
index ec4586fd25d..aa506d012ad 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -32,6 +32,15 @@
"projectName": "rascal",
"vmArgs": "-Xss80m -Xmx2g -ea"
},
+ {
+ "type": "java",
+ "name": "Launch RascalShell Tutor",
+ "request": "launch",
+ "mainClass": "org.rascalmpl.shell.RascalShell",
+ "projectName": "rascal",
+ "cwd" : "${workspaceFolder}/../rascal-tutor",
+ "vmArgs": "-Xss80m -Xmx2g -ea"
+ },
{
"type": "java",
"name": "Attach RascalShell",
@@ -40,6 +49,14 @@
"hostName": "localhost",
"port": 9001
},
+ {
+ "type": "java",
+ "name": "Attach Mvn Rascal",
+ "request": "attach",
+ "projectName": "rascal-maven-plugin",
+ "hostName": "localhost",
+ "port": 8000
+ },
{
"type": "java",
"name": "Attach Rascal LSP Terminal",
diff --git a/pom.xml b/pom.xml
index 53e3e0672c0..398d5ccc9f1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
org.rascalmpl
rascal
- 0.35.0-RC2-SNAPSHOT
+ 0.35.0-RC8-SNAPSHOT
jar
@@ -32,7 +32,7 @@
org.rascalmpl.shell.RascalShell
2
11
- 0.22.0-RC2
+ 0.25.0-RC2-SNAPSHOT
@@ -116,7 +116,7 @@
org.rascalmpl
rascal-maven-plugin
- ${rascal-maven.version}
+ 0.25.0-RC1
true
${project.build.outputDirectory}
@@ -156,7 +156,7 @@
package
-
+
@@ -366,7 +366,7 @@
io.usethesource
vallang
- 1.0.0-RC3
+ 1.0.0-RC11
org.ow2.asm
diff --git a/src/org/rascalmpl/interpreter/DefaultTestResultListener.java b/src/org/rascalmpl/interpreter/DefaultTestResultListener.java
index d588ab41cb1..fab6d6bed70 100644
--- a/src/org/rascalmpl/interpreter/DefaultTestResultListener.java
+++ b/src/org/rascalmpl/interpreter/DefaultTestResultListener.java
@@ -13,14 +13,11 @@
*******************************************************************************/
package org.rascalmpl.interpreter;
-import java.io.IOException;
import java.io.PrintWriter;
-import org.rascalmpl.exceptions.Throw;
import org.rascalmpl.repl.ReplTextWriter;
import io.usethesource.vallang.ISourceLocation;
-import io.usethesource.vallang.io.StandardTextWriter;
public class DefaultTestResultListener implements ITestResultListener{
private PrintWriter err;
@@ -119,19 +116,7 @@ else if (t != null) {
err.println();
}
err.println("error: " + test + " @ " + ReplTextWriter.valueToString(loc));
- err.println("\t" + t.getMessage());
-
- if (t instanceof Throw) {
- try {
- ((Throw) t).getTrace().prettyPrintedString(err, new StandardTextWriter(true));
- }
- catch (IOException e) {
- // should not happen
- }
- }
- else {
- t.printStackTrace(err);
- }
+ err.println(message);
}
else {
failures++;
diff --git a/src/org/rascalmpl/interpreter/TestEvaluator.java b/src/org/rascalmpl/interpreter/TestEvaluator.java
index 47da78a248c..c555402e864 100644
--- a/src/org/rascalmpl/interpreter/TestEvaluator.java
+++ b/src/org/rascalmpl/interpreter/TestEvaluator.java
@@ -20,12 +20,14 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.Random;
import org.rascalmpl.interpreter.env.ModuleEnvironment;
import org.rascalmpl.interpreter.result.AbstractFunction;
import org.rascalmpl.test.infrastructure.QuickCheck;
import org.rascalmpl.test.infrastructure.QuickCheck.TestResult;
+import org.rascalmpl.test.infrastructure.QuickCheck.UnExpectedExceptionThrownResult;
import io.usethesource.vallang.IBool;
import io.usethesource.vallang.IString;
@@ -117,7 +119,8 @@ private void runTests(ModuleEnvironment env, List tests) {
}
}
catch (Throwable e) {
- return new TestResult(false, e);
+ // TODO: add bound type parameters
+ return new UnExpectedExceptionThrownResult(test.getEnv().getName() + "::" + test.getName(), actuals, Map.of(), args, e);
}
}, env.getRoot().getStore(), tries, maxDepth, maxWidth);
@@ -137,6 +140,7 @@ private void runTests(ModuleEnvironment env, List tests) {
catch(Throwable e){
testResultListener.report(false, test.getName(), test.getAst().getLocation(), e.getMessage(), e);
}
+
eval.getOutPrinter().flush();
eval.getErrorPrinter().flush();
}
diff --git a/src/org/rascalmpl/library/List.rsc b/src/org/rascalmpl/library/List.rsc
index 26a03040a1d..e8c86ba18df 100644
--- a/src/org/rascalmpl/library/List.rsc
+++ b/src/org/rascalmpl/library/List.rsc
@@ -19,7 +19,6 @@ module List
import Exception;
import Map;
-import IO;
@synopsis{Concatenate a list of lists.}
diff --git a/src/org/rascalmpl/library/Location.rsc b/src/org/rascalmpl/library/Location.rsc
index f47e63eb360..1da26a7ec69 100644
--- a/src/org/rascalmpl/library/Location.rsc
+++ b/src/org/rascalmpl/library/Location.rsc
@@ -77,13 +77,17 @@ Strict containment between two locations `inner` and `outer` holds when
}
bool isStrictlyContainedIn(loc inner, loc outer){
+ if(inner == outer){
+ return false;
+ }
if(isSameFile(inner, outer)){
if(inner.offset?){
- return outer.offset? ==> ( inner.offset == outer.offset && inner.offset + inner.length < outer.offset + outer.length
- || inner.offset > outer.offset && inner.offset + inner.length <= outer.offset + outer.length
- );
- } else {
- return inner.offset > 0 && !outer.offset?;
+ if(outer.offset?){
+ return inner.offset == outer.offset && inner.offset + inner.length < outer.offset + outer.length
+ || inner.offset > outer.offset && inner.offset + inner.length <= outer.offset + outer.length;
+ } else {
+ return inner.offset > 0;
+ }
}
}
return false;
@@ -102,7 +106,11 @@ Containment between two locations `inner` and `outer` holds when
bool isContainedIn(loc inner, loc outer){
if(isSameFile(inner, outer)){
if(inner.offset?){
- return outer.offset? ==> (inner.offset >= outer.offset && inner.offset + inner.length <= outer.offset + outer.length);
+ if(outer.offset?){
+ return (inner.offset >= outer.offset && inner.offset + inner.length <= outer.offset + outer.length);
+ } else {
+ return true;
+ }
} else {
return !outer.offset?;
}
diff --git a/src/org/rascalmpl/library/Map.rsc b/src/org/rascalmpl/library/Map.rsc
index c88045522cb..4512649e89f 100644
--- a/src/org/rascalmpl/library/Map.rsc
+++ b/src/org/rascalmpl/library/Map.rsc
@@ -157,7 +157,7 @@ int incr(int x) { return x + 1; }
mapper(("apple": 1, "pear": 2, "orange": 3), prefix, incr);
```
}
-public map[&K, &V] mapper(map[&K, &V] M, &L (&K) F, &W (&V) G)
+public map[&L, &W] mapper(map[&K, &V] M, &L (&K) F, &W (&V) G)
= (F(key) : G(M[key]) | &K key <- M);
diff --git a/src/org/rascalmpl/library/Prelude.java b/src/org/rascalmpl/library/Prelude.java
index 999ee0f41a0..409bb0f93f0 100644
--- a/src/org/rascalmpl/library/Prelude.java
+++ b/src/org/rascalmpl/library/Prelude.java
@@ -1341,8 +1341,8 @@ private void writeFileEnc(ISourceLocation sloc, IString charset, IList V, boolea
else if (elem.getType().isSubtypeOf(RascalValueFactory.Tree)) {
TreeAdapter.yield((IConstructor) elem, out);
}
- else{
- out.append(elem.toString());
+ else {
+ new StandardTextWriter().write(elem, out);
}
}
if (postfix != null) {
diff --git a/src/org/rascalmpl/library/Set.rsc b/src/org/rascalmpl/library/Set.rsc
index 39c8066445a..10e0f819cdd 100644
--- a/src/org/rascalmpl/library/Set.rsc
+++ b/src/org/rascalmpl/library/Set.rsc
@@ -276,7 +276,13 @@ public default (&T <:num) sum({(&T <: num) e, *(&T <: num) r})
@synopsis{Pick an arbitrary element from a set.}
@description{
+This _randomly_ picks one element from a set, unless the set is empty.
+:::warning
+Use ((getSingleFrom)) if you want the element from a singleton set. ((getOneFrom)) will silently
+continue even if there are more element present, which can be a serious threat to the validity of your
+analysis algorithm (arbitrary data is not considered).
+:::
}
@examples{
```rascal-shell
@@ -287,6 +293,16 @@ getOneFrom({"elephant", "zebra", "snake"});
getOneFrom({"elephant", "zebra", "snake"});
```
}
+@benefits{
+* Random sampling can be an effective test input selection strategy.
+}
+@pitfalls{
+* The name ((getOneFrom)) does not convey randomness.
+* ((getOneFrom)) drops all the other elements.
+If you are sure there is only one element and you need it, then use ((getSingleFrom)). It will fail fast if your assumption is wrong.
+* If you need more then one element, then repeatedly calling ((getOneFrom)) will be expensive. Have a look at ((util::Sampling)) for more effective
+sampling utilities.
+}
@javaClass{org.rascalmpl.library.Prelude}
public java &T getOneFrom(set[&T] st);
@@ -294,15 +310,45 @@ public java &T getOneFrom(set[&T] st);
@synopsis{Get "first" element from a set.}
@description{
Get "first" element of a set. Of course, sets are unordered and do not have a first element.
-However, we may assume that sets are internally ordered in some way and this ordering is reproducible.
+However, we could assume that sets are internally ordered in some way and this ordering is reproducible (it's deterministic up to hashing collisions).
Applying `getFirstFrom` on the same set will always returns the same element.
+
+:::warning
+Use ((getSingleFrom)) if you want the element from a singleton set. ((getFirstFrom)) will silently
+continue even if there are more element present, which can be a serious threat to the validity of your
+analysis algorithm (arbitrary data is not considered).
+:::
}
@benefits{
This function helps to make set-based code more deterministic, for instance, for testing purposes.
}
+@pitfalls{
+* The deterministic order is _undefined_. This means it may be stable between runs, but not between releases of Rascal.
+* There are much better ways to iterate over the elements of a set:
+ * Use the `<-` enumerator operator in a `for` loop or a comprehension.
+ * Use list matching
+* ((getFirstFrom)) drops all the other elements
+ * If you are sure there is only one element and you need it, then use ((getSingleFrom)). It will fail fast if your assumption is wrong.
+}
@javaClass{org.rascalmpl.library.Prelude}
public java &T getFirstFrom(set[&T] st);
+@synopsis{Get the only element from a singleton set.}
+@description{
+Get the only element of a singleton set. This fails with a ((CallFailed)) exception when the set is not a singleton.
+}
+@benefits{
+* ((getSingleFrom)) fails _fast_ if the assumption (parameter `st` is a singleton) is not met.
+* If a binary relation `r` is injective (i.e. it models a function where each key only has one value) then all projections `r[key]` should produce singleton values: `{v}`.
+Using ((getSingleFrom)) to get the element out makes sure we fail fast in case our assumptions were wrong, or they have changed.
+* Never use ((getFirstFrom)) or ((takeOneFrom)) if you can use ((getSingleFrom)).
+}
+@pitfalls{
+* ((CallFailed)) exceptions are sometimes hard to diagnose. Look at the stack trace to see that it was ((getSingleFrom))
+that caused it, and then look at the parameter of ((CallFailed)) to see that the set was not a singleton.
+}
+public &T getSingleFrom(set[&T] st) = getFirstFrom(st) when size(st) == 1;
+
// TODO temporary? replacement due to unexplained behaviour of compiler
//public &T getFirstFrom({&T f, *&T _}) = f;
//public &T getFirstFrom(set[&T] _:{}) { throw EmptySet(); }
diff --git a/src/org/rascalmpl/library/lang/java/m3/Core.rsc b/src/org/rascalmpl/library/lang/java/m3/Core.rsc
index 08e21e84d13..fe871c1b9ad 100644
--- a/src/org/rascalmpl/library/lang/java/m3/Core.rsc
+++ b/src/org/rascalmpl/library/lang/java/m3/Core.rsc
@@ -115,7 +115,7 @@ java M3 createM3FromString(loc fileName, str contents, bool errorRecovery = fals
java M3 createM3FromJarClass(loc jarClass, list[loc] classPath = []);
@javaClass{org.rascalmpl.library.lang.java.m3.internal.EclipseJavaCompiler}
-java M3 createM3FromSingleClass(loc jarClass, str className);
+java M3 createM3FromSingleClass(loc jarClass, str className, list[loc] classPath = []);
@javaClass{org.rascalmpl.library.lang.java.m3.internal.EclipseJavaCompiler}
java M3 createM3FromJarFile(loc jarLoc, list[loc] classPath = []);
diff --git a/src/org/rascalmpl/library/lang/java/m3/internal/EclipseJavaCompiler.java b/src/org/rascalmpl/library/lang/java/m3/internal/EclipseJavaCompiler.java
index e01e61451f3..f044df7c7b9 100644
--- a/src/org/rascalmpl/library/lang/java/m3/internal/EclipseJavaCompiler.java
+++ b/src/org/rascalmpl/library/lang/java/m3/internal/EclipseJavaCompiler.java
@@ -67,9 +67,9 @@ public IValue createM3FromJarClass(ISourceLocation jarLoc, IList classPath) {
return createM3FromJarClass(jarLoc, classPath, getM3Store());
}
- public IValue createM3FromSingleClass(ISourceLocation classLoc, IString className) {
+ public IValue createM3FromSingleClass(ISourceLocation classLoc, IString className, IList classpath) {
JarConverter converter = new JarConverter(getM3Store(), new HashMap<>());
- converter.convertJarFile(classLoc, ((IString) className).getValue());
+ converter.convertJarFile(classLoc, ((IString) className).getValue(), classpath);
return converter.getModel(false);
}
diff --git a/src/org/rascalmpl/library/lang/java/m3/internal/JarConverter.java b/src/org/rascalmpl/library/lang/java/m3/internal/JarConverter.java
index 0061d3ee329..d0e59ad8a55 100644
--- a/src/org/rascalmpl/library/lang/java/m3/internal/JarConverter.java
+++ b/src/org/rascalmpl/library/lang/java/m3/internal/JarConverter.java
@@ -132,9 +132,9 @@ public void convertJar(ISourceLocation jar, IList classPath) {
* @param classFile
* @param className
*/
- public void convertJarFile(ISourceLocation classFile, String className) {
+ public void convertJarFile(ISourceLocation classFile, String className, IList classpath) {
loc = classFile;
- createSingleClassM3(className);
+ createSingleClassM3(className, classpath);
}
/**
@@ -172,7 +172,11 @@ private void createM3() {
* and parent packages is triggered.
* @param className
*/
- private void createSingleClassM3(String className) {
+ private void createSingleClassM3(String className, IList classpath) {
+ if (resolver == null) {
+ resolver = new ASMNodeResolver(loc, classpath, typeStore);
+ }
+
String compUnit = className;
ClassReader classReader = resolver.buildClassReader(className);
diff --git a/src/org/rascalmpl/library/lang/rascal/tests/basic/Sets.rsc b/src/org/rascalmpl/library/lang/rascal/tests/basic/Sets.rsc
index 380af2b0340..38e220533bc 100644
--- a/src/org/rascalmpl/library/lang/rascal/tests/basic/Sets.rsc
+++ b/src/org/rascalmpl/library/lang/rascal/tests/basic/Sets.rsc
@@ -121,6 +121,22 @@ test bool tst_takeOneFrom(set[int] S) {
return x in S && x notin S2 && size(S2) == size(S) - 1 && S2 < S;
}
+test bool tst_getSingleFrom(set[int] S) {
+ if ({e} := S) {
+ return getSingleFrom(S) == e;
+ }
+ return true;
+}
+
+test bool tst_getSingleFromExample(str input) {
+ return getSingleFrom({input}) == input;
+}
+
+@expected{CallFailed}
+test bool tst_getSingleFromMore(str input, int i) {
+ getSingleFrom({input, i});
+}
+
test bool tst_toList(set[int] S) = isEmpty(S) || size(S) == size(toList(S)) && all(x <- S, x in toList(S));
test bool tst_toMap(rel[int, int] S) = isEmpty(S) || domain(S) == domain(toMap(S)) && range(S) == {*toMap(S)[k] | k <- toMap(S)};
diff --git a/src/org/rascalmpl/library/lang/rascal/tests/concrete/Issue1913.rsc b/src/org/rascalmpl/library/lang/rascal/tests/concrete/Issue1913.rsc
new file mode 100644
index 00000000000..4690092aa75
--- /dev/null
+++ b/src/org/rascalmpl/library/lang/rascal/tests/concrete/Issue1913.rsc
@@ -0,0 +1,23 @@
+module lang::rascal::tests::concrete::Issue1913
+
+extend lang::std::Layout;
+import IO;
+
+syntax As = "begin" A* as "end";
+
+syntax A = "a" | "b";
+
+test bool issue1913() {
+ A* bs = (As)`begin b a b end`.as;
+
+ As prog = (As)`begin b a a end`;
+
+ prog = visit (prog) {
+ case (As)`begin b end`
+ => (As)`begin end`
+ }
+
+ println(prog);
+ // don't loose a space
+ return "" == "begin b a b a a end";
+}
\ No newline at end of file
diff --git a/src/org/rascalmpl/library/util/Reflective.java b/src/org/rascalmpl/library/util/Reflective.java
index 70c821fa58e..98f50a5a981 100644
--- a/src/org/rascalmpl/library/util/Reflective.java
+++ b/src/org/rascalmpl/library/util/Reflective.java
@@ -433,6 +433,10 @@ public IInteger getFingerprintNode(INode nd){
return values.integer(ToplevelType.getFingerprintNode(nd));
}
+ public IInteger getHashCode(IValue v) {
+ return values.integer(v.hashCode());
+ }
+
public void throwNullPointerException() {
throw new NullPointerException();
}
diff --git a/src/org/rascalmpl/library/util/Reflective.rsc b/src/org/rascalmpl/library/util/Reflective.rsc
index f86ec6058fa..2955befe5d0 100644
--- a/src/org/rascalmpl/library/util/Reflective.rsc
+++ b/src/org/rascalmpl/library/util/Reflective.rsc
@@ -287,6 +287,17 @@ public java int getFingerprint(value val, int arity, bool concretePatterns);
@javaClass{org.rascalmpl.library.util.Reflective}
public java int getFingerprintNode(node nd);
+@synopsis{Get the internal hash code of a value. For the benefit of debugging the Rascal implementation.}
+@description{
+This function is useless for Rascal programmer's as it is a part of the under-the-hood implementation of values.
+You can use a value directly as a lookup key. The internal data-structures probably use this hashCode for
+optimal lookups in `O(log(size))`.
+
+We use this function to diagnose possible performance issues caused by hash collisions.
+}
+@javaClass{org.rascalmpl.library.util.Reflective}
+public java int getHashCode(value v);
+
@synopsis{Throw a raw Java NullPointerException, to help simulate an unexpected exception in test scenarios}
@javaClass{org.rascalmpl.library.util.Reflective}
java void throwNullPointerException();
diff --git a/src/org/rascalmpl/library/vis/Charts.rsc b/src/org/rascalmpl/library/vis/Charts.rsc
index 9c2e5cfc2e0..6d6944aa922 100644
--- a/src/org/rascalmpl/library/vis/Charts.rsc
+++ b/src/org/rascalmpl/library/vis/Charts.rsc
@@ -85,29 +85,29 @@ Content scatterChart(list[str] labels, rel[num x,num y] values ..., str title="S
* the radius is in raw pixels rather than scaled to the chart's axis
}
Content bubbleChart(lrel[num x,num y, num r] v, str title="Scatterplot", ChartAutoColorMode colorMode=\data())
- = content(title, chartServer(chartData(title, v), \type=bubble(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(title, v), \type=bubble(), title=title, colorMode=colorMode, legend=false));
Content bubbleChart(list[str] labels, lrel[num x,num y, num r] values ..., str title="Scatterplots", ChartAutoColorMode colorMode=\data())
- = content(title, chartServer(chartData(labels, values), \type=scatter(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(labels, values), \type=scatter(), title=title, colorMode=colorMode, legend=true));
Content bubbleChart(rel[num x,num y, num r] v, str title="Scatterplot", ChartAutoColorMode colorMode=\data())
- = content(title, chartServer(chartData(title, v), \type=scatter(), title=title, colorMode=colorMode));
-
+ = content(title, chartServer(chartData(title, v), \type=scatter(), title=title, colorMode=colorMode, legend=false));
+
Content bubbleChart(list[str] labels, rel[num x,num y, num r] values ..., str title="Scatterplots", ChartAutoColorMode colorMode=\data())
- = content(title, chartServer(chartData(labels, values), \type=scatter(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(labels, values), \type=scatter(), title=title, colorMode=colorMode, legend=true));
@synopsis{A bar chart from labeled numbers}
Content barChart(rel[str label, num val] values, str title="Bar Chart", ChartAutoColorMode colorMode=\data())
- = content(title, chartServer(chartData(values), \type=\bar(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(values), \type=\bar(), title=title, colorMode=colorMode, legend=false));
Content barChart(lrel[str label, num val] values, str title="Bar Chart", ChartAutoColorMode colorMode=\data())
- = content(title, chartServer(chartData(values), \type=\bar(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(values), \type=\bar(), title=title, colorMode=colorMode, legend=true));
Content barChart(list[str] labels, rel[str label, num val] values..., str title="Bar Chart", ChartAutoColorMode colorMode=\dataset())
- = content(title, chartServer(chartData(labels, values), \type=\bar(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(labels, values), \type=\bar(), title=title, colorMode=colorMode, legend=false));
Content barChart(list[str] labels, lrel[str label, num val] values..., str title="Bar Chart", ChartAutoColorMode colorMode=\dataset())
- = content(title, chartServer(chartData(labels, values), \type=\bar(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(labels, values), \type=\bar(), title=title, colorMode=colorMode, legend=true));
@synopsis{A line chart from labeled numbers}
Content lineChart(rel[str label, num val] values, str title="Line Chart", ChartAutoColorMode colorMode=\dataset())
@@ -117,62 +117,62 @@ Content lineChart(lrel[str label, num val] values, str title="Line Chart", Chart
= content(title, chartServer(chartData(values), \type=\line(), title=title, colorMode=colorMode, legend=false));
Content lineChart(list[str] labels, rel[str label, num val] values..., str title="Line Chart", ChartAutoColorMode colorMode=\dataset())
- = content(title, chartServer(chartData(labels, values), \type=\line(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(labels, values), \type=\line(), title=title, colorMode=colorMode, legend=true));
Content lineChart(list[str] labels, lrel[str label, num val] values..., str title="Line Chart", ChartAutoColorMode colorMode=\dataset())
- = content(title, chartServer(chartData(labels, values), \type=\line(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(labels, values), \type=\line(), title=title, colorMode=colorMode, legend=true));
@synopsis{A polar area chart from labeled numbers}
Content polarAreaChart(rel[str label, num val] values, str title="Polar Area Chart", ChartAutoColorMode colorMode=\data())
- = content(title, chartServer(chartData(values), \type=\polarArea(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(values), \type=\polarArea(), title=title, colorMode=colorMode, legend=false));
Content polarAreaChart(lrel[str label, num val] values, str title="Polar Area Chart", ChartAutoColorMode colorMode=\data())
- = content(title, chartServer(chartData(values), \type=\polarArea(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(values), \type=\polarArea(), title=title, colorMode=colorMode, legend=false));
Content polarAreaChart(list[str] labels, rel[str label, num val] values..., str title="Polar Area Chart", ChartAutoColorMode colorMode=\dataset())
- = content(title, chartServer(chartData(labels, values), \type=\polarArea(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(labels, values), \type=\polarArea(), title=title, colorMode=colorMode, legend=true));
Content polarAreaChart(list[str] labels, lrel[str label, num val] values..., str title="Polar Area Chart", ChartAutoColorMode colorMode=\dataset())
- = content(title, chartServer(chartData(labels, values), \type=\polarArea(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(labels, values), \type=\polarArea(), title=title, colorMode=colorMode, legend=true));
@synopsis{A radar chart from labeled numbers}
Content radarChart(rel[str label, num val] values, str title="Radar Chart", ChartAutoColorMode colorMode=\data())
- = content(title, chartServer(chartData(values), \type=\radar(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(values), \type=\radar(), title=title, colorMode=colorMode, legend=true));
Content radarChart(lrel[str label, num val] values, str title="Radar Chart", ChartAutoColorMode colorMode=\data())
- = content(title, chartServer(chartData(values), \type=\radar(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(values), \type=\radar(), title=title, colorMode=colorMode, legend=true));
Content radarChart(list[str] labels, rel[str label, num val] values..., str title="Radar Chart", ChartAutoColorMode colorMode=\dataset())
- = content(title, chartServer(chartData(labels, values), \type=\radar(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(labels, values), \type=\radar(), title=title, colorMode=colorMode, legend=true));
Content radarChart(list[str] labels, lrel[str label, num val] values..., str title="Radar Chart", ChartAutoColorMode colorMode=\dataset())
- = content(title, chartServer(chartData(labels, values), \type=\radar(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(labels, values), \type=\radar(), title=title, colorMode=colorMode, legend=true));
@synopsis{A pie chart from labeled numbers}
Content pieChart(rel[str label, num val] values, str title="Pie Chart", ChartAutoColorMode colorMode=\data())
- = content(title, chartServer(chartData(values), \type=\pie(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(values), \type=\pie(), title=title, colorMode=colorMode, legend=true));
Content pieChart(lrel[str label, num val] values, str title="Pie Chart", ChartAutoColorMode colorMode=\data())
- = content(title, chartServer(chartData(values), \type=\pie(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(values), \type=\pie(), title=title, colorMode=colorMode, legend=true));
Content pieChart(list[str] labels, rel[str label, num val] values..., str title="Pie Chart", ChartAutoColorMode colorMode=\dataset())
- = content(title, chartServer(chartData(labels, values), \type=\pie(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(labels, values), \type=\pie(), title=title, colorMode=colorMode, legend=true));
Content pieChart(list[str] labels, lrel[str label, num val] values..., str title="Pie Chart", ChartAutoColorMode colorMode=\dataset())
- = content(title, chartServer(chartData(labels, values), \type=\pie(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(labels, values), \type=\pie(), title=title, colorMode=colorMode, legend=true));
@synopsis{A dougnut chart from labeled numbers}
Content doughnutChart(rel[str label, num val] values, str title="Doughnut Chart", ChartAutoColorMode colorMode=\data())
- = content(title, chartServer(chartData(values), \type=\doughnut(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(values), \type=\doughnut(), title=title, colorMode=colorMode, legend=true));
Content doughnutChart(lrel[str label, num val] values, str title="Doughnut Chart", ChartAutoColorMode colorMode=\data())
- = content(title, chartServer(chartData(values), \type=\doughnut(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(values), \type=\doughnut(), title=title, colorMode=colorMode, legend=true));
Content doughnutChart(list[str] labels, rel[str label, num val] values..., str title="Doughnut Chart", ChartAutoColorMode colorMode=\data())
- = content(title, chartServer(chartData(labels, values), \type=\doughnut(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(labels, values), \type=\doughnut(), title=title, colorMode=colorMode, legend=true));
Content doughnutChart(list[str] labels, lrel[str label, num val] values..., str title="Doughnut Chart", ChartAutoColorMode colorMode=\data())
- = content(title, chartServer(chartData(labels, values), \type=\doughnut(), title=title, colorMode=colorMode));
+ = content(title, chartServer(chartData(labels, values), \type=\doughnut(), title=title, colorMode=colorMode, legend=true));
@synopsys{
converts plain data sources into chart.js datasets
@@ -182,6 +182,11 @@ ChartDataSet chartDataSet(str label, rel[num x, num y] r)
label=label
);
+ChartDataSet chartDataSet(str label, map[num x, num y] r)
+ = chartDataSet([point(x,r[x]) | x <- r],
+ label=label
+ );
+
ChartDataSet chartDataSet(str label, rel[num x, num y, num rad] r)
= chartDataSet([point(x,y,r=rad) | <- r],
label=label
@@ -206,7 +211,15 @@ ChartData chartData(rel[str label, num val] v)
datasets=[
chartDataSet([n | <_, n> <- v])
]
- );
+ );
+
+ChartData chartData(map[str label, num val] v)
+ = chartData(
+ labels=[l | l <- v],
+ datasets=[
+ chartDataSet([v[l] | l <- v])
+ ]
+ );
ChartData chartData(lrel[str label, num val] v)
= chartData(
@@ -273,6 +286,13 @@ ChartData chartData(str label, lrel[num x, num y] values)
]
);
+ChartData chartData(str label, map[num x, num y] values)
+ = chartData(
+ datasets=[
+ chartDataSet(label, values)
+ ]
+ );
+
ChartData chartData(str label, lrel[num x, num y, num r] values)
= chartData(
datasets=[
@@ -396,7 +416,7 @@ A chart has a typical default layout that we can reuse for all kinds of chart ty
provides the template and immediately instantiates the client and the server to start displaying the chart
in a browser.
}
-Response(Request) chartServer(ChartData theData, ChartType \type=\bar(), str title="Chart", ChartAutoColorMode colorMode=\data(), bool legend=false, bool animations=false)
+Response(Request) chartServer(ChartData theData, ChartType \type=\bar(), str title="Chart", ChartAutoColorMode colorMode=\data(), bool legend=true, bool animations=false)
= chartServer(
chart(
\type=\type,
diff --git a/src/org/rascalmpl/repl/BaseREPL.java b/src/org/rascalmpl/repl/BaseREPL.java
index 4540685a344..0f9e66f64d6 100755
--- a/src/org/rascalmpl/repl/BaseREPL.java
+++ b/src/org/rascalmpl/repl/BaseREPL.java
@@ -19,7 +19,6 @@
import java.util.concurrent.ConcurrentLinkedQueue;
import org.fusesource.jansi.Ansi;
-import org.fusesource.jansi.Ansi.Color;
import org.rascalmpl.ideservices.IDEServices;
import org.rascalmpl.library.util.PathConfig;
@@ -274,7 +273,7 @@ protected void stackTraceRequested() {
}
private String previousPrompt = "";
- public static final String PRETTY_PROMPT_PREFIX = Ansi.ansi().reset().bold().fg(Color.BLACK).toString();
+ public static final String PRETTY_PROMPT_PREFIX = Ansi.ansi().reset().bold().toString();
public static final String PRETTY_PROMPT_POSTFIX = Ansi.ansi().boldOff().reset().toString();
protected void updatePrompt() {
diff --git a/src/org/rascalmpl/semantics/dynamic/Tree.java b/src/org/rascalmpl/semantics/dynamic/Tree.java
index f69f8c750c5..d1bf20785f9 100644
--- a/src/org/rascalmpl/semantics/dynamic/Tree.java
+++ b/src/org/rascalmpl/semantics/dynamic/Tree.java
@@ -302,6 +302,7 @@ private IList flatten(IList args) {
if (nestedArgs.length() > 0) {
appendPreviousSeparators(args, result, delta, i, previousWasEmpty);
result.appendAll(nestedArgs);
+ previousWasEmpty = false;
}
else {
previousWasEmpty = true;
diff --git a/src/org/rascalmpl/test/infrastructure/QuickCheck.java b/src/org/rascalmpl/test/infrastructure/QuickCheck.java
index 25ba7105bd1..0b9fbd1167b 100644
--- a/src/org/rascalmpl/test/infrastructure/QuickCheck.java
+++ b/src/org/rascalmpl/test/infrastructure/QuickCheck.java
@@ -12,6 +12,7 @@
*/
package org.rascalmpl.test.infrastructure;
+import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
@@ -25,6 +26,7 @@
import io.usethesource.vallang.IString;
import io.usethesource.vallang.IValue;
import io.usethesource.vallang.IValueFactory;
+import io.usethesource.vallang.io.StandardTextWriter;
import io.usethesource.vallang.type.Type;
import io.usethesource.vallang.type.TypeStore;
@@ -196,7 +198,7 @@ public void writeMessage(PrintWriter out) {
}
}
- public class UnExpectedExceptionThrownResult extends TestFailedResult {
+ public static class UnExpectedExceptionThrownResult extends TestFailedResult {
public UnExpectedExceptionThrownResult(String functionName, Type[] actualTypes,
Map tpbindings, IValue[] values, Throwable thrownException) {
@@ -210,16 +212,21 @@ public void writeMessage(PrintWriter out) {
out.println("Exception:");
if (thrownException instanceof Throw) {
out.println(((Throw)thrownException).getMessage());
+ try {
+ ((Throw) thrownException).getTrace().prettyPrintedString(out, new StandardTextWriter(true));
+ }
+ catch (IOException e) {
+ // should not happen
+ }
}
else {
- out.println(thrownException.toString());
+ // out.println(thrownException.toString());
thrownException.printStackTrace(out);
}
}
-
}
- public class ExceptionNotThrownResult extends TestFailedResult {
+ public static class ExceptionNotThrownResult extends TestFailedResult {
public ExceptionNotThrownResult(String functionName, Type[] actualTypes,
Map tpbindings, IValue[] values, String expected) {
super(functionName, "test did not throw '" + expected + "' exception", actualTypes, tpbindings, values);
diff --git a/src/org/rascalmpl/uri/classloaders/SourceLocationClassLoader.java b/src/org/rascalmpl/uri/classloaders/SourceLocationClassLoader.java
index 5459bba761e..307ba73b23b 100644
--- a/src/org/rascalmpl/uri/classloaders/SourceLocationClassLoader.java
+++ b/src/org/rascalmpl/uri/classloaders/SourceLocationClassLoader.java
@@ -160,10 +160,23 @@ public URL getResource(String name) {
public Enumeration getResources(String name) throws IOException {
List result = new ArrayList<>(path.size());
+
for (ClassLoader l : path) {
- Enumeration e = l.getResources(name);
- while (e.hasMoreElements()) {
- result.add(e.nextElement());
+ SearchItem item = new SearchItem(l, name);
+
+ if (stack.contains(item)) {
+ continue;
+ }
+ try {
+ stack.push(item);
+
+ Enumeration e = l.getResources(name);
+ while (e.hasMoreElements()) {
+ result.add(e.nextElement());
+ }
+ }
+ finally {
+ stack.pop();
}
}