mirror of
https://github.com/cincheo/jsweet.git
synced 2025-12-15 15:29:22 +00:00
add basic adapters and associated tests
This commit is contained in:
parent
c10770d80b
commit
1a1110969d
@ -243,7 +243,7 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
private List<JCClassDecl> localClasses = new ArrayList<>();
|
||||
|
||||
private List<String> generatedMethodNames = new ArrayList<>();
|
||||
|
||||
|
||||
// to be accessed in the parent scope
|
||||
private boolean isAnonymousClass = false;
|
||||
// to be accessed in the parent scope
|
||||
@ -1461,8 +1461,9 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
Map<Name, String> signatures = new HashMap<>();
|
||||
for (MethodSymbol meth : methods) {
|
||||
if (meth.type instanceof MethodType) {
|
||||
// do not generate default abstract method for already generated methods
|
||||
if(getScope().generatedMethodNames.contains(meth.name.toString())) {
|
||||
// do not generate default abstract method for already
|
||||
// generated methods
|
||||
if (getScope().generatedMethodNames.contains(meth.name.toString())) {
|
||||
continue;
|
||||
}
|
||||
MethodSymbol s = Util.findMethodDeclarationInType(getContext().types, classdecl.sym,
|
||||
@ -2809,7 +2810,8 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
print("[]");
|
||||
}
|
||||
} else {
|
||||
if (context.hasAnnotationType(varDecl.vartype.type.tsym, ANNOTATION_STRING_TYPE)) {
|
||||
if (context.hasAnnotationType(varDecl.vartype.type.tsym, ANNOTATION_STRING_TYPE)
|
||||
&& !varDecl.vartype.type.tsym.isEnum()) {
|
||||
print("\"");
|
||||
print(context.getAnnotationValue(varDecl.vartype.type.tsym, ANNOTATION_STRING_TYPE,
|
||||
String.class, varDecl.vartype.type.tsym.name.toString()).toString());
|
||||
|
||||
@ -1,5 +1,23 @@
|
||||
package org.jsweet.transpiler.extension;
|
||||
|
||||
/*
|
||||
* JSweet transpiler - http://www.jsweet.org
|
||||
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.Modifier;
|
||||
@ -8,6 +26,17 @@ import javax.lang.model.element.VariableElement;
|
||||
|
||||
import org.jsweet.transpiler.util.Util;
|
||||
|
||||
/**
|
||||
* This simple adapter renames non-public members by adding two underscores as a
|
||||
* prefix.
|
||||
*
|
||||
* <p>
|
||||
* Note that this could be dangerous to use for protected fields if wanting to
|
||||
* access them from subclasses declared in other JSweet projects.
|
||||
*
|
||||
* @author Renaud Pawlak
|
||||
*/
|
||||
|
||||
public class AddPrefixToNonPublicMembersAdapter extends PrinterAdapter {
|
||||
|
||||
public AddPrefixToNonPublicMembersAdapter(PrinterAdapter parentAdapter) {
|
||||
|
||||
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* JSweet transpiler - http://www.jsweet.org
|
||||
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
package org.jsweet.transpiler.extension;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
|
||||
import org.jsweet.transpiler.extension.PrinterAdapter;
|
||||
import org.jsweet.transpiler.model.MethodInvocationElement;
|
||||
import org.jsweet.transpiler.model.NewClassElement;
|
||||
|
||||
/**
|
||||
* This optional adapter tunes the JavaScript generation to map the Java's
|
||||
* BigDecimal API to the Big JavaScript library.
|
||||
*
|
||||
* <p>
|
||||
* Warning: this adapter is not activated by default. See JSweet specifications
|
||||
* to know how to activate this adapter.
|
||||
*
|
||||
* <p>
|
||||
* This extension requires the big.js candy to be available in the JSweet
|
||||
* classpath: https://github.com/jsweet-candies/candy-bigjs.
|
||||
*
|
||||
* @author Renaud Pawlak
|
||||
*/
|
||||
public class BigDecimalAdapter extends PrinterAdapter {
|
||||
|
||||
public BigDecimalAdapter(PrinterAdapter parent) {
|
||||
super(parent);
|
||||
// all BigDecimal types are mapped to Big
|
||||
addTypeMapping(BigDecimal.class.getName(), "Big");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean substituteNewClass(NewClassElement newClass) {
|
||||
String className = newClass.getTypeAsElement().toString();
|
||||
// map the BigDecimal constructors
|
||||
if (BigDecimal.class.getName().equals(className)) {
|
||||
print("new Big(").printArgList(newClass.getArguments()).print(")");
|
||||
return true;
|
||||
}
|
||||
// delegate to the adapter chain
|
||||
return super.substituteNewClass(newClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean substituteMethodInvocation(MethodInvocationElement invocation) {
|
||||
if (invocation.getTargetExpression() != null) {
|
||||
Element targetType = invocation.getTargetExpression().getTypeAsElement();
|
||||
if (BigDecimal.class.getName().equals(targetType.toString())) {
|
||||
// BigDecimal methods are mapped to their Big.js equivalent
|
||||
switch (invocation.getMethodName()) {
|
||||
case "multiply":
|
||||
printMacroName(invocation.getMethodName());
|
||||
print(invocation.getTargetExpression()).print(".times(").printArgList(invocation.getArguments())
|
||||
.print(")");
|
||||
return true;
|
||||
case "add":
|
||||
printMacroName(invocation.getMethodName());
|
||||
print(invocation.getTargetExpression()).print(".plus(").printArgList(invocation.getArguments())
|
||||
.print(")");
|
||||
return true;
|
||||
case "scale":
|
||||
printMacroName(invocation.getMethodName());
|
||||
// we assume that we always have a scale of 2, which is a
|
||||
// good default if we deal with currencies...
|
||||
// to be changed/implemented further
|
||||
print("2");
|
||||
return true;
|
||||
case "setScale":
|
||||
printMacroName(invocation.getMethodName());
|
||||
print(invocation.getTargetExpression()).print(".round(").print(invocation.getArguments().get(0))
|
||||
.print(")");
|
||||
return true;
|
||||
case "compareTo":
|
||||
printMacroName(invocation.getMethodName());
|
||||
print(invocation.getTargetExpression()).print(".cmp(").print(invocation.getArguments().get(0))
|
||||
.print(")");
|
||||
return true;
|
||||
case "equals":
|
||||
printMacroName(invocation.getMethodName());
|
||||
print(invocation.getTargetExpression()).print(".eq(").print(invocation.getArguments().get(0))
|
||||
.print(")");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// delegate to the adapter chain
|
||||
return super.substituteMethodInvocation(invocation);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* JSweet transpiler - http://www.jsweet.org
|
||||
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
package org.jsweet.transpiler.extension;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
|
||||
import org.jsweet.transpiler.model.MethodInvocationElement;
|
||||
import org.jsweet.transpiler.model.NewClassElement;
|
||||
|
||||
/**
|
||||
* This optional adapter tunes the JavaScript generation to use JavaScript ES6
|
||||
* maps to implement Java maps.
|
||||
*
|
||||
* <p>
|
||||
* Note that this is a partial implementation that shall be extended to support
|
||||
* more cases and adapted to your own requirements. Additionally, this
|
||||
* implementation generates untyped JavaScript in order to avoid having to have
|
||||
* the ES6 API in the compilation path.
|
||||
*
|
||||
* @author Renaud Pawlak
|
||||
*/
|
||||
public class MapAdapter extends PrinterAdapter {
|
||||
|
||||
static String[] mapTypes = { Map.class.getName(), HashMap.class.getName(), TreeMap.class.getName(),
|
||||
Hashtable.class.getName() };
|
||||
|
||||
public MapAdapter(PrinterAdapter parent) {
|
||||
super(parent);
|
||||
// rewrite all Java map and compatible map implementations types
|
||||
// note that we rewrite to 'any' because we don't want to require the
|
||||
// ES6 API to compile (all subsequent accesses will be untyped)
|
||||
for (String mapType : mapTypes) {
|
||||
addTypeMapping(mapType, "any");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean substituteNewClass(NewClassElement newClass) {
|
||||
String className = newClass.getTypeAsElement().toString();
|
||||
// map the map constructor to the global 'Map' variable (untyped access)
|
||||
if (Arrays.binarySearch(mapTypes, className) >= 0) {
|
||||
// this access is browser/node-compatible
|
||||
print("new (typeof window == 'undefined'?global:window)['Map'](").printArgList(newClass.getArguments()).print(")");
|
||||
return true;
|
||||
}
|
||||
// delegate to the adapter chain
|
||||
return super.substituteNewClass(newClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean substituteMethodInvocation(MethodInvocationElement invocation) {
|
||||
if (invocation.getTargetExpression() != null) {
|
||||
Element targetType = invocation.getTargetExpression().getTypeAsElement();
|
||||
if (Arrays.binarySearch(mapTypes, targetType.toString()) >= 0) {
|
||||
// Java Map methods are mapped to their JavaScript equivalent
|
||||
switch (invocation.getMethodName()) {
|
||||
case "put":
|
||||
printMacroName(invocation.getMethodName());
|
||||
print(invocation.getTargetExpression()).print(".set(").printArgList(invocation.getArguments())
|
||||
.print(")");
|
||||
return true;
|
||||
// although 'get' has the same name, we still rewrite it in case
|
||||
// another extension would provide it's own implementation
|
||||
case "get":
|
||||
printMacroName(invocation.getMethodName());
|
||||
print(invocation.getTargetExpression()).print(".get(").printArgList(invocation.getArguments())
|
||||
.print(")");
|
||||
return true;
|
||||
case "containsKey":
|
||||
printMacroName(invocation.getMethodName());
|
||||
print(invocation.getTargetExpression()).print(".has(").printArgList(invocation.getArguments())
|
||||
.print(")");
|
||||
return true;
|
||||
// we use the ES6 'Array.from' method in an untyped way to
|
||||
// transform the iterator in an array
|
||||
case "keySet":
|
||||
printMacroName(invocation.getMethodName());
|
||||
print("(<any>Array).from(").print(invocation.getTargetExpression()).print(".keys())");
|
||||
return true;
|
||||
case "values":
|
||||
printMacroName(invocation.getMethodName());
|
||||
print("(<any>Array).from(").print(invocation.getTargetExpression()).print(".values())");
|
||||
return true;
|
||||
// in ES6 maps, 'size' is a property, not a method
|
||||
case "size":
|
||||
printMacroName(invocation.getMethodName());
|
||||
print(invocation.getTargetExpression()).print(".size");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// delegate to the adapter chain
|
||||
return super.substituteMethodInvocation(invocation);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* JSweet transpiler - http://www.jsweet.org
|
||||
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
package org.jsweet.transpiler.extension;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
|
||||
import org.jsweet.JSweetConfig;
|
||||
import org.jsweet.transpiler.model.CaseElement;
|
||||
import org.jsweet.transpiler.model.ExtendedElement;
|
||||
import org.jsweet.transpiler.model.MethodInvocationElement;
|
||||
import org.jsweet.transpiler.model.VariableAccessElement;
|
||||
|
||||
/**
|
||||
* This optional adapter tunes the JavaScript generation to remove enums and
|
||||
* replace them with strings. It only applies to enums that are annotated with
|
||||
* <code>@StringType</code>.
|
||||
*
|
||||
* <p>
|
||||
* For instance: <code>@StringType enum MyEnum { A, B, C }</code> will be erased
|
||||
* and all subsequent accesses to the enum will be mapped to simple strings.
|
||||
*
|
||||
* <p>
|
||||
* Typically, the method declaration <code>void m(MyEnum e) {...}</code> will be
|
||||
* mapped to <code>void m(e : string) {...}</code>. And of course, the
|
||||
* invocation <code>xxx.m(MyEnum.A)</code> will be mapped to
|
||||
* <code>xxx.m("A")</code>.
|
||||
*
|
||||
* <p>
|
||||
* Warning: this adapter is not activated by default. See JSweet specifications
|
||||
* to know how to activate this adapter.
|
||||
*
|
||||
* @author Renaud Pawlak
|
||||
*/
|
||||
public class StringEnumAdapter extends PrinterAdapter {
|
||||
|
||||
private boolean isStringEnum(Element element) {
|
||||
// note: this function could be improved to exclude enums that have
|
||||
// fields or methods other than the enum constants
|
||||
return element.getKind() == ElementKind.ENUM && hasAnnotationType(element, JSweetConfig.ANNOTATION_STRING_TYPE);
|
||||
}
|
||||
|
||||
public StringEnumAdapter(PrinterAdapter parent) {
|
||||
super(parent);
|
||||
// eligible enums will be translated to string in JS
|
||||
addTypeMapping((typeTree, name) -> isStringEnum(typeTree.getTypeAsElement()) ? "string" : null);
|
||||
|
||||
// ignore enum declarations with a programmatic annotation manager
|
||||
addAnnotationManager(new AnnotationManager() {
|
||||
@Override
|
||||
public Action manageAnnotation(Element element, String annotationType) {
|
||||
// add the @Erased annotation to string enums
|
||||
return JSweetConfig.ANNOTATION_ERASED.equals(annotationType) && isStringEnum(element) ? Action.ADD
|
||||
: Action.VOID;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean substituteMethodInvocation(MethodInvocationElement invocation) {
|
||||
if (invocation.getTargetExpression() != null) {
|
||||
Element targetType = invocation.getTargetExpression().getTypeAsElement();
|
||||
// enum API must be erased and use plain strings instead
|
||||
if (isStringEnum(targetType)) {
|
||||
switch (invocation.getMethodName()) {
|
||||
case "name":
|
||||
printMacroName(invocation.getMethodName());
|
||||
print(invocation.getTargetExpression());
|
||||
return true;
|
||||
case "valueOf":
|
||||
printMacroName(invocation.getMethodName());
|
||||
print(invocation.getArgument(0));
|
||||
return true;
|
||||
case "equals":
|
||||
printMacroName(invocation.getMethodName());
|
||||
print("(").print(invocation.getTargetExpression()).print(" == ")
|
||||
.print(invocation.getArguments().get(0)).print(")");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.substituteMethodInvocation(invocation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean substituteVariableAccess(VariableAccessElement variableAccess) {
|
||||
// accessing an enum field is replaced by a simple string value
|
||||
// (MyEnum.A => "A")
|
||||
if (isStringEnum(variableAccess.getTargetElement())) {
|
||||
print("\"" + variableAccess.getVariableName() + "\"");
|
||||
return true;
|
||||
}
|
||||
return super.substituteVariableAccess(variableAccess);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean substituteCaseStatementPattern(CaseElement caseStatement, ExtendedElement pattern) {
|
||||
// map enums to strings in case statements
|
||||
if (isStringEnum(pattern.getTypeAsElement())) {
|
||||
print("\"" + pattern + "\"");
|
||||
return true;
|
||||
}
|
||||
return super.substituteCaseStatementPattern(caseStatement, pattern);
|
||||
}
|
||||
|
||||
}
|
||||
@ -22,6 +22,8 @@ import org.jsweet.transpiler.JSweetContext;
|
||||
import org.jsweet.transpiler.JSweetFactory;
|
||||
import org.jsweet.transpiler.ModuleKind;
|
||||
import org.jsweet.transpiler.extension.Java2TypeScriptAdapter;
|
||||
import org.jsweet.transpiler.extension.PrinterAdapter;
|
||||
import org.jsweet.transpiler.extension.StringEnumAdapter;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
@ -33,6 +35,7 @@ import source.enums.ComplexEnums;
|
||||
import source.enums.EnumInSamePackage;
|
||||
import source.enums.Enums;
|
||||
import source.enums.ErasedEnum;
|
||||
import source.enums.StringEnums;
|
||||
import source.enums.other.EnumInOtherPackage;
|
||||
|
||||
public class EnumTests extends AbstractTest {
|
||||
@ -87,7 +90,7 @@ public class EnumTests extends AbstractTest {
|
||||
logHandler.assertNoProblems();
|
||||
}, getSourceFile(ComplexInnerEnums.class));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testComplexEnumWithAbstractMethods() {
|
||||
eval((logHandler, r) -> {
|
||||
@ -137,4 +140,18 @@ public class EnumTests extends AbstractTest {
|
||||
}, getSourceFile(EnumWithStatics.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringEnums() {
|
||||
createTranspiler(new JSweetFactory() {
|
||||
@Override
|
||||
public PrinterAdapter createAdapter(JSweetContext context) {
|
||||
return new StringEnumAdapter(super.createAdapter(context));
|
||||
}
|
||||
});
|
||||
eval((logHandler, r) -> {
|
||||
logHandler.assertNoProblems();
|
||||
}, getSourceFile(StringEnums.class));
|
||||
createTranspiler(new JSweetFactory());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -12,13 +12,18 @@ import org.jsweet.transpiler.JSweetContext;
|
||||
import org.jsweet.transpiler.JSweetFactory;
|
||||
import org.jsweet.transpiler.ModuleKind;
|
||||
import org.jsweet.transpiler.extension.Java2TypeScriptAdapter;
|
||||
import org.jsweet.transpiler.extension.MapAdapter;
|
||||
import org.jsweet.transpiler.extension.PrinterAdapter;
|
||||
import org.jsweet.transpiler.extension.RemoveJavaDependenciesAdapter;
|
||||
import org.jsweet.transpiler.extension.StringEnumAdapter;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import source.enums.StringEnums;
|
||||
import source.extension.AnnotationTest;
|
||||
import source.extension.Maps;
|
||||
|
||||
class TestFactory extends JSweetFactory {
|
||||
|
||||
@ -105,4 +110,19 @@ public class ExtensionTests extends AbstractTest {
|
||||
}, getSourceFile(AnnotationTest.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaps() {
|
||||
createTranspiler(new JSweetFactory() {
|
||||
@Override
|
||||
public PrinterAdapter createAdapter(JSweetContext context) {
|
||||
return new MapAdapter(super.createAdapter(context));
|
||||
}
|
||||
});
|
||||
eval((logHandler, r) -> {
|
||||
logHandler.assertNoProblems();
|
||||
}, getSourceFile(Maps.class));
|
||||
createTranspiler(new JSweetFactory());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
32
transpiler/src/test/java/source/enums/StringEnums.java
Normal file
32
transpiler/src/test/java/source/enums/StringEnums.java
Normal file
@ -0,0 +1,32 @@
|
||||
package source.enums;
|
||||
|
||||
import static jsweet.util.Lang.any;
|
||||
|
||||
import jsweet.lang.StringType;
|
||||
|
||||
public class StringEnums {
|
||||
|
||||
public static void main(String[] args) {
|
||||
m(MyStringEnum.A);
|
||||
}
|
||||
|
||||
public static void m(MyStringEnum e) {
|
||||
assert any(e) == "A";
|
||||
switch (e) {
|
||||
case A:
|
||||
break;
|
||||
case B:
|
||||
case C:
|
||||
default:
|
||||
assert false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@StringType
|
||||
enum MyStringEnum {
|
||||
|
||||
A, B, C
|
||||
|
||||
}
|
||||
45
transpiler/src/test/java/source/extension/Maps.java
Normal file
45
transpiler/src/test/java/source/extension/Maps.java
Normal file
@ -0,0 +1,45 @@
|
||||
package source.extension;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import def.js.Array;
|
||||
|
||||
/**
|
||||
* This test is executed without any Java runtime.
|
||||
*/
|
||||
public class Maps {
|
||||
|
||||
static Array<String> trace = new Array<>();
|
||||
|
||||
static String key1() {
|
||||
return "1";
|
||||
}
|
||||
|
||||
static String key2() {
|
||||
return "a";
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
HashMap<String, String> m = new HashMap<>();
|
||||
|
||||
m.put(key1(), "a");
|
||||
m.put("2", "b");
|
||||
|
||||
// for(Entry<String, String> e : m.entrySet()) {
|
||||
//
|
||||
// trace.push("" + e.getKey());
|
||||
// trace.push("" + e.getValue());
|
||||
// }
|
||||
|
||||
assert 2 == m.size();
|
||||
assert "a" == m.get("1");
|
||||
|
||||
assert m.containsKey("2");
|
||||
|
||||
assert m.keySet().toString() == "[1, 2]";
|
||||
|
||||
assert m.values().toString() == "[a, b]";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user