diff --git a/doc/jsweet-language-specifications.tex b/doc/jsweet-language-specifications.tex index ad92f075..074bee53 100644 --- a/doc/jsweet-language-specifications.tex +++ b/doc/jsweet-language-specifications.tex @@ -199,9 +199,9 @@ Examples of valid statements: // warning '==' behaves like the JavaScript one at runtime Integer i = 2; assert i == 2; -Double d = i + 4; +Double d = i + 4d; assert d.toString() == "6"; -assert d == "6"; +assert (Object) d == "6"; BiFunction f = (s, i) -> { return s.substring(i); }; assert "bc" == f.apply("abc", 1); \end{lstlisting} @@ -214,9 +214,9 @@ Arrays can be used in JSweet and are transpiled to JavaScript arrays. Array init int[] arrayOfInts = { 1, 2, 3, 4}; assert arrayOfInts.length == 4; assert arrayOfInts[0] == 1; -for(int i : arrayOfInts) { - arrayOfInts[i] = arrayOfInts[i] - 1; - assert arrayOfInts[i] == i; +int i = 0; +for (int intItem : arrayOfInts) { + assert arrayOfInts[i++] == intItem; } \end{lstlisting} @@ -240,7 +240,7 @@ Programmers should use this API most of the time, which is HTML5 compatible and As a consequence, programmers need to be able to switch to the JavaScript API when coming from a Java object. The \texttt{jsweet.util.Globals} class defines convenient static methods to cast back and forth core Java objects to their corresponding JSweet objects. For instance the \texttt{string(...)} method will allow the programmer to switch from the Java to the JSweet strings and conversely. \begin{lstlisting}[language=Java] -import jsweet.util.Globals.string; +import static jsweet.util.Globals.string; String str = "This is a test string"; str.toLowerCase(); // valid: toLowerCase it defined both in Java and JavaScript str.substr(1); // compile error: substr is not a Java method @@ -251,7 +251,7 @@ string(str).substr(1); // valid: string(str) is a jsweet.lang.String. Here is another example that shows the use of the \texttt{array} method to access the \texttt{push} method available on JavaScript arrays. \begin{lstlisting}[language=Java] -import jsweet.util.Globals.array; +import static jsweet.util.Globals.array; String[] strings = { "a", "b", "c" }; array(strings).push("d"); assert strings[3] == "d"; @@ -410,7 +410,7 @@ The following statements are valid statements in JSweet. \begin{lstlisting}[language=Java] MyEnum e = MyEnum.A; assert MyEnum.A == e; -assert e.name().equals("A"); +assert e.name() == "A"; assert e.ordinal() == 0; assert MyEnum.valueOf("A") == e; assert array(MyEnum.values()).indexOf(MyEnum.valueOf("C")) == 2; @@ -631,7 +631,7 @@ Main methods are the program execution entry points and will be invoked globally public class C { private int n; public static C instance; - public static main(String[] args) { + public static void main(String[] args) { instance = new C(); instance.n = 4; } @@ -680,7 +680,7 @@ public class C2 { n = 4; } } -assert new C2.n == 4; +assert C2.n == 4; \end{lstlisting} diff --git a/src/main/java/org/jsweet/transpiler/JSweetTranspiler.java b/src/main/java/org/jsweet/transpiler/JSweetTranspiler.java index cfcafb70..5fd64e30 100644 --- a/src/main/java/org/jsweet/transpiler/JSweetTranspiler.java +++ b/src/main/java/org/jsweet/transpiler/JSweetTranspiler.java @@ -481,10 +481,11 @@ public class JSweetTranspiler { StringWriter trace = new StringWriter(); + Process runProcess; if (context.useModules) { File f = sourceFiles[sourceFiles.length - 1].getJsFile(); logger.debug("eval file: " + f); - ProcessUtil.runCommand(ProcessUtil.NODE_COMMAND, line -> trace.append(line + "\n"), null, f.getPath()); + runProcess = ProcessUtil.runCommand(ProcessUtil.NODE_COMMAND, line -> trace.append(line + "\n"), null, f.getPath()); } else { File tmpFile = new File(new File(TMP_WORKING_DIR_NAME), "eval.tmp.js"); FileUtils.deleteQuietly(tmpFile); @@ -493,9 +494,14 @@ public class JSweetTranspiler { FileUtils.write(tmpFile, script + "\n", true); } logger.debug("eval file: " + tmpFile); - ProcessUtil.runCommand(ProcessUtil.NODE_COMMAND, line -> trace.append(line + "\n"), null, tmpFile.getPath()); + runProcess = ProcessUtil.runCommand(ProcessUtil.NODE_COMMAND, line -> trace.append(line + "\n"), null, tmpFile.getPath()); } + int returnCode = runProcess.exitValue(); + logger.info("return code=" + returnCode); + if (returnCode != 0) { + throw new Exception("evaluation error (code=" + returnCode + ") - trace=" + trace); + } return new TraceBasedEvaluationResult(trace.getBuffer().toString()); } } diff --git a/src/main/java/org/jsweet/transpiler/typescript/Java2TypeScriptTranslator.java b/src/main/java/org/jsweet/transpiler/typescript/Java2TypeScriptTranslator.java index 0a7fe401..63b6f906 100644 --- a/src/main/java/org/jsweet/transpiler/typescript/Java2TypeScriptTranslator.java +++ b/src/main/java/org/jsweet/transpiler/typescript/Java2TypeScriptTranslator.java @@ -1812,7 +1812,8 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter { @Override public void visitAssert(JCAssert assertion) { if (!context.ignoreAssertions) { - print("if(!(").print(assertion.cond).print(")) throw new Error(\"Assertion error\");"); + String assertCode = assertion.toString().replace("\"", "'"); + print("if(!(").print(assertion.cond).print(")) throw new Error(\"Assertion error line " + getCurrentLine() + ": " + assertCode + "\");"); } } diff --git a/src/test/java/org/jsweet/test/transpiler/DocTests.java b/src/test/java/org/jsweet/test/transpiler/DocTests.java new file mode 100644 index 00000000..b1998dd7 --- /dev/null +++ b/src/test/java/org/jsweet/test/transpiler/DocTests.java @@ -0,0 +1,36 @@ +/* + * JSweet - http://www.jsweet.org + * Copyright (C) 2015 CINCHEO SAS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jsweet.test.transpiler; + +import static org.junit.Assert.assertEquals; + +import org.jsweet.transpiler.util.EvaluationResult; +import org.junit.Test; + +import source.doc.LanguageSpecifications; + +public class DocTests extends AbstractTest { + + @Test + public void testLanguageSpecifications() { + EvaluationResult result = eval(getSourceFile(LanguageSpecifications.class)); + + assertEquals(4, result. get("main_n")); + assertEquals(true, result. get("finished")); + } + +} diff --git a/src/test/java/source/doc/LanguageSpecifications.java b/src/test/java/source/doc/LanguageSpecifications.java new file mode 100644 index 00000000..8e3efaab --- /dev/null +++ b/src/test/java/source/doc/LanguageSpecifications.java @@ -0,0 +1,112 @@ +package source.doc; + +import java.util.function.BiFunction; + +import static jsweet.util.Globals.string; +import static jsweet.util.Globals.$export; +import static jsweet.util.Globals.array; + +enum MyEnum { + A, B, C +} + +class C1 { + int n; + + { + n = 4; + } +} + +class C2 { + static int n; + + static { + n = 4; + } +} + +public class LanguageSpecifications { + public static void basicConcepts_coreTypes_primitiveTypes() { + int i = 2; + assert i == 2; + double d = i + 4; + assert d == 6; + String s = "string" + '0' + i; + assert s == "string02"; + boolean b = false; + assert!b; + } + + public static void basicConcepts_coreTypes_allowedJavaObjects() { + Integer i = 2; + assert i == 2; + + Double d = i + 4d; + assert d.toString() == "6"; + assert(Object) d == "6"; + + BiFunction f = (str, integer) -> { + return str.substring(integer); + }; + assert"bc" == f.apply("abc", 1); + } + + public static void basicConcepts_coreTypes_javaArrays() { + int[] arrayOfInts = { 1, 2, 3, 4 }; + assert arrayOfInts.length == 4; + assert arrayOfInts[0] == 1; + + int i = 0; + for (int intItem : arrayOfInts) { + assert arrayOfInts[i++] == intItem; + } + } + + public static void basicConcepts_coreTypes_coreJavascript() { + String str = "This is a test string"; + assert str.toLowerCase() == "this is a test string"; + assert string(str).substr(1) == "his is a test string"; + + String[] strings = { "a", "b", "c" }; + array(strings).push("d"); + assert strings[3] == "d"; + } + + public static void basicConcepts_enums() { + + MyEnum e = MyEnum.A; + assert MyEnum.A == e; + assert e.name() == "A"; + assert e.ordinal() == 0; + assert MyEnum.valueOf("A") == e; + assert array(MyEnum.values()).indexOf(MyEnum.valueOf("C")) == 2; + } + + public static void semantics_initializers() { + assert new C1().n == 4; + + assert C2.n == 4; + } + + private int n; + public static LanguageSpecifications instance; + + public static void main(String[] args) { + instance = new LanguageSpecifications(); + instance.n = 4; + + $export("main_n", instance.n); + + basicConcepts_coreTypes_primitiveTypes(); + basicConcepts_coreTypes_allowedJavaObjects(); + basicConcepts_coreTypes_javaArrays(); + basicConcepts_coreTypes_coreJavascript(); + basicConcepts_enums(); + + semantics_initializers(); + + $export("finished", true); + + } +}