mirror of
https://github.com/cincheo/jsweet.git
synced 2025-12-14 23:09:22 +00:00
add $invoke capability
Brings dynamic invoke capability to def.js.Object. It allows to dynamically call a method on an object for instance if definition is missing or simply if it is not possible to do it otherwise.
This commit is contained in:
parent
26beb8d8ce
commit
7f2000e03b
@ -234,6 +234,11 @@ public class Object {
|
||||
*/
|
||||
native public static Array<String> keys(java.lang.Object o);
|
||||
|
||||
/**
|
||||
* Invoke method of given name on this object with given parameters.
|
||||
*/
|
||||
native public <T> T $invoke(java.lang.String methodName, java.lang.Object... args);
|
||||
|
||||
/**
|
||||
* Gets the value for the given key. Generates <code>this[key]</code>.
|
||||
*/
|
||||
|
||||
@ -255,6 +255,11 @@ public class Object {
|
||||
*/
|
||||
native public java.lang.Boolean propertyIsEnumerable(double v);
|
||||
|
||||
/**
|
||||
* Invoke method of given name on this object with given parameters.
|
||||
*/
|
||||
native public <T> T $invoke(java.lang.String methodName, java.lang.Object... args);
|
||||
|
||||
/**
|
||||
* Gets the value for the given key. Generates <code>this[key]</code>.
|
||||
*/
|
||||
|
||||
@ -707,6 +707,8 @@ public final class Lang {
|
||||
|
||||
public static native <R> R await(Promise<R> promise);
|
||||
|
||||
public static native <R> R await(R promise);
|
||||
|
||||
public static native <R> def.js.Function async(def.js.Function function);
|
||||
|
||||
public static native <T> Promise<T> asyncReturn(T result);
|
||||
|
||||
@ -234,7 +234,7 @@
|
||||
<dependency>
|
||||
<groupId>org.jsweet</groupId>
|
||||
<artifactId>jsweet-core</artifactId>
|
||||
<version>6</version>
|
||||
<version>6.0.1-SNAPSHOT</version>
|
||||
<scope>test</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
@ -204,6 +204,8 @@ public abstract class JSweetConfig {
|
||||
public static final String UNION_PACKAGE = UTIL_PACKAGE + ".union";
|
||||
/** The constant for the Union core class full name. */
|
||||
public static final String UNION_CLASS_NAME = UNION_PACKAGE + ".Union";
|
||||
/** The constant for dynamic invoke function. */
|
||||
public static final String INVOKE_FUCTION_NAME = "$invoke";
|
||||
/** The constant for indexed access function. */
|
||||
public static final String INDEXED_GET_FUCTION_NAME = "$get";
|
||||
/** The constant for indexed assignment function. */
|
||||
|
||||
@ -1620,6 +1620,10 @@ public class JSweetContext extends Context {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given statement can be used in a Java object instantation block
|
||||
* to be transformed to a JS Object Literal
|
||||
*/
|
||||
private static boolean isAllowedStatementInMap(JCStatement statement) {
|
||||
if (statement instanceof JCExpressionStatement) {
|
||||
JCExpressionStatement exprStat = (JCExpressionStatement) statement;
|
||||
|
||||
@ -30,6 +30,7 @@ import static org.jsweet.JSweetConfig.INDEXED_GET_FUCTION_NAME;
|
||||
import static org.jsweet.JSweetConfig.INDEXED_GET_STATIC_FUCTION_NAME;
|
||||
import static org.jsweet.JSweetConfig.INDEXED_SET_FUCTION_NAME;
|
||||
import static org.jsweet.JSweetConfig.INDEXED_SET_STATIC_FUCTION_NAME;
|
||||
import static org.jsweet.JSweetConfig.INVOKE_FUCTION_NAME;
|
||||
import static org.jsweet.JSweetConfig.LANG_PACKAGE;
|
||||
import static org.jsweet.JSweetConfig.LANG_PACKAGE_ALT;
|
||||
import static org.jsweet.JSweetConfig.UTIL_CLASSNAME;
|
||||
@ -134,8 +135,7 @@ public class Java2TypeScriptAdapter extends PrinterAdapter {
|
||||
/**
|
||||
* Creates a root adapter (with no parent).
|
||||
*
|
||||
* @param context
|
||||
* the transpilation context
|
||||
* @param context the transpilation context
|
||||
*/
|
||||
public Java2TypeScriptAdapter(JSweetContext context) {
|
||||
super(context);
|
||||
@ -146,9 +146,9 @@ public class Java2TypeScriptAdapter extends PrinterAdapter {
|
||||
* Creates a new adapter that will try delegate to the given parent adapter when
|
||||
* not implementing its own behavior.
|
||||
*
|
||||
* @param parentAdapter
|
||||
* cannot be null: if no parent you must use the
|
||||
* {@link #AbstractPrinterAdapter(JSweetContext)} constructor
|
||||
* @param parentAdapter cannot be null: if no parent you must use the
|
||||
* {@link #AbstractPrinterAdapter(JSweetContext)}
|
||||
* constructor
|
||||
*/
|
||||
public Java2TypeScriptAdapter(PrinterAdapter parent) {
|
||||
super(parent);
|
||||
@ -639,6 +639,33 @@ public class Java2TypeScriptAdapter extends PrinterAdapter {
|
||||
|
||||
if (targetMethodName != null) {
|
||||
switch (targetMethodName) {
|
||||
case INVOKE_FUCTION_NAME:
|
||||
if (invocationElement.getTargetExpression() != null && !(UTIL_CLASSNAME.equals(targetClassName)
|
||||
|| DEPRECATED_UTIL_CLASSNAME.equals(targetClassName))) {
|
||||
|
||||
} else {
|
||||
if (invocationElement.getArgumentCount() == 1) {
|
||||
print("this[").print(invocationElement.getArguments().get(0)).print("]");
|
||||
} else {
|
||||
print(invocationElement.getArguments().get(0)).print("[")
|
||||
.print(invocationElement.getArguments().get(1)).print("]");
|
||||
}
|
||||
}
|
||||
print(invocationElement.getTargetExpression());
|
||||
print("[");
|
||||
print(invocationElement.getArgument(0));
|
||||
print("]");
|
||||
print("(");
|
||||
List<ExtendedElement> arguments = invocationElement.getArguments();
|
||||
int argCount = arguments.size();
|
||||
for (int i = 1; i < argCount; i++) {
|
||||
print(arguments.get(i));
|
||||
if (i < argCount - 1) {
|
||||
print(",");
|
||||
}
|
||||
}
|
||||
print(")");
|
||||
return true;
|
||||
case INDEXED_GET_FUCTION_NAME:
|
||||
if (isWithinGlobals(targetClassName)) {
|
||||
if (invocationElement.getArgumentCount() == 1) {
|
||||
@ -1327,8 +1354,7 @@ public class Java2TypeScriptAdapter extends PrinterAdapter {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param enclosingElement
|
||||
* is required for functional (ie dynamic) type mappings
|
||||
* @param enclosingElement is required for functional (ie dynamic) type mappings
|
||||
*/
|
||||
public boolean substituteAndPrintType(ExtendedElement enclosingElement, TypeElement type) {
|
||||
String typeFullName = type.toString();
|
||||
|
||||
@ -22,22 +22,37 @@ import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.jsweet.test.transpiler.util.TranspilerTestRunner;
|
||||
import org.jsweet.transpiler.*;
|
||||
import org.jsweet.transpiler.extension.PrinterAdapter;
|
||||
import org.jsweet.transpiler.model.ExtendedElement;
|
||||
import org.jsweet.transpiler.model.MethodInvocationElement;
|
||||
import org.jsweet.transpiler.JSweetProblem;
|
||||
import org.jsweet.transpiler.ModuleKind;
|
||||
import org.jsweet.transpiler.SourceFile;
|
||||
import org.jsweet.transpiler.util.EvaluationResult;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import source.syntax.*;
|
||||
import source.syntax.AnnotationQualifiedNames;
|
||||
import source.syntax.Casts;
|
||||
import source.syntax.DocComments;
|
||||
import source.syntax.DynamicInvoke;
|
||||
import source.syntax.FinalVariables;
|
||||
import source.syntax.FinalVariablesRuntime;
|
||||
import source.syntax.GlobalsCastMethod;
|
||||
import source.syntax.GlobalsInvocation;
|
||||
import source.syntax.Keywords;
|
||||
import source.syntax.Labels;
|
||||
import source.syntax.LambdaExpression;
|
||||
import source.syntax.LambdasWithInterfaces;
|
||||
import source.syntax.Literals;
|
||||
import source.syntax.Looping;
|
||||
import source.syntax.MemberReferences;
|
||||
import source.syntax.QualifiedNames;
|
||||
import source.syntax.References;
|
||||
import source.syntax.SpecialFunctions;
|
||||
import source.syntax.StatementsWithNoBlocks;
|
||||
import source.syntax.SuperInvocation;
|
||||
import source.syntax.ValidIndexedAccesses;
|
||||
|
||||
public class SyntaxTests extends AbstractTest {
|
||||
|
||||
@ -140,14 +155,17 @@ public class SyntaxTests extends AbstractTest {
|
||||
|
||||
}
|
||||
|
||||
@Ignore
|
||||
@Test
|
||||
public void testIndexedAccessInStaticScope() {
|
||||
public void testDynamicInvoke() {
|
||||
eval((logHandler, r) -> {
|
||||
Assert.assertEquals("Wrong output value", "value", r.get("out_a"));
|
||||
Assert.assertNull("Wrong output value", r.get("out_b"));
|
||||
Assert.assertNull("var wasn't deleted", r.get("out_c"));
|
||||
}, getSourceFile(IndexedAccessInStaticScope.class));
|
||||
assertEquals(true, r.get("a_1"));
|
||||
assertEquals(true, r.get("a"));
|
||||
assertEquals(true, r.get("b"));
|
||||
assertEquals(true, r.get("c"));
|
||||
assertEquals(true, r.get("d"));
|
||||
assertEquals(true, r.get("e"));
|
||||
assertEquals("5;true;foo", r.get("f"));
|
||||
}, getSourceFile(DynamicInvoke.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
70
transpiler/src/test/java/source/syntax/DynamicInvoke.java
Normal file
70
transpiler/src/test/java/source/syntax/DynamicInvoke.java
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* JSweet - http://www.jsweet.org
|
||||
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
|
||||
*
|
||||
* 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 source.syntax;
|
||||
|
||||
import static jsweet.util.Lang.$export;
|
||||
import static jsweet.util.Lang.object;
|
||||
|
||||
public class DynamicInvoke {
|
||||
|
||||
{
|
||||
object(this).$invoke("a");
|
||||
jsweet.util.Lang.object(this).$invoke("b");
|
||||
}
|
||||
|
||||
public DynamicInvoke() {
|
||||
object(this).$invoke("c");
|
||||
jsweet.util.Lang.object(this).$invoke("d");
|
||||
}
|
||||
|
||||
public void a_1() {
|
||||
$export("a_1", "true");
|
||||
}
|
||||
|
||||
public void a() {
|
||||
object(this).$invoke("a_1");
|
||||
$export("a", "true");
|
||||
}
|
||||
|
||||
public void b() {
|
||||
$export("b", "true");
|
||||
}
|
||||
|
||||
public void c() {
|
||||
$export("c", "true");
|
||||
}
|
||||
|
||||
public void d() {
|
||||
$export("d", "true");
|
||||
}
|
||||
|
||||
public void e() {
|
||||
$export("e", "true");
|
||||
}
|
||||
|
||||
public void f(Integer i, Boolean b, String s) {
|
||||
$export("f", i + ";" + b + ";" + s);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
DynamicInvoke test = new DynamicInvoke();
|
||||
object(test).$invoke("e");
|
||||
object(test).$invoke("f", 5, new Boolean(true), "foo");
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* JSweet - http://www.jsweet.org
|
||||
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
|
||||
*
|
||||
* 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 source.syntax;
|
||||
|
||||
public class IndexedAccessInStaticScope {
|
||||
|
||||
static {
|
||||
// $get("a");
|
||||
// $set("a", "value");
|
||||
// jsweet.util.Globals.$get("a");
|
||||
// jsweet.util.Globals.$set("a", "value");
|
||||
}
|
||||
|
||||
public static void m() {
|
||||
// $get("a");
|
||||
// $set("a", "value");
|
||||
// jsweet.util.Globals.$get("a");
|
||||
// jsweet.util.Globals.$set("a", "value");
|
||||
//
|
||||
// $set("c", "i want to be deleted");
|
||||
// $delete("c");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// m();
|
||||
// $export("out_a", $get("a"));
|
||||
// $export("out_b", $get("b"));
|
||||
// $export("out_c", $get("c"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class C {
|
||||
public static void m() {
|
||||
// $set("b", "value");
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user