mirror of
https://github.com/cincheo/jsweet.git
synced 2025-12-15 07:19:22 +00:00
Merge pull request #604 from cincheo/dev/20200607
Moving forward version 2.4
This commit is contained in:
commit
7d42942707
@ -24,7 +24,9 @@ import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* This annotation type is used on elements that should be erased at generation
|
||||
* time (casts and constructor invocations are removed).
|
||||
* time. For erased types, casts and constructor invocations are removed. For
|
||||
* erased methods, invocation are removed, except if the {@link KeepUses}
|
||||
* annotation is also defined on the erased method..
|
||||
*
|
||||
* @author Renaud Pawlak
|
||||
*/
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.jsweet</groupId>
|
||||
<artifactId>jsweet-transpiler</artifactId>
|
||||
<version>2.3.10-SNAPSHOT</version>
|
||||
<version>2.4.0-SNAPSHOT</version>
|
||||
<name>JSweet transpiler</name>
|
||||
<description>A Java to TypeScript/JavaScript Open Transpiler</description>
|
||||
<url>http://www.jsweet.org</url>
|
||||
@ -264,6 +264,12 @@
|
||||
<scope>test</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jsweet</groupId>
|
||||
<artifactId>j4ts</artifactId>
|
||||
<version>0.6.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jsweet.candies</groupId>
|
||||
<artifactId>jquery</artifactId>
|
||||
|
||||
@ -321,8 +321,8 @@ public class JSweetCommandLineLauncher {
|
||||
jsap.registerParameter(switchArg);
|
||||
|
||||
// Java compiler's encoding
|
||||
optionArg = new FlaggedOption("encoding");
|
||||
optionArg.setLongFlag("encoding");
|
||||
optionArg = new FlaggedOption(JSweetOptions.encoding);
|
||||
optionArg.setLongFlag(JSweetOptions.encoding);
|
||||
optionArg.setStringParser(JSAP.STRING_PARSER);
|
||||
optionArg.setRequired(false);
|
||||
optionArg.setDefault("UTF-8");
|
||||
@ -330,8 +330,8 @@ public class JSweetCommandLineLauncher {
|
||||
jsap.registerParameter(optionArg);
|
||||
|
||||
// Output encoding
|
||||
optionArg = new FlaggedOption("outEncoding");
|
||||
optionArg.setLongFlag("outEncoding");
|
||||
optionArg = new FlaggedOption(JSweetOptions.outEncoding);
|
||||
optionArg.setLongFlag(JSweetOptions.outEncoding);
|
||||
optionArg.setStringParser(JSAP.STRING_PARSER);
|
||||
optionArg.setRequired(false);
|
||||
optionArg.setDefault("UTF-8");
|
||||
@ -388,9 +388,9 @@ public class JSweetCommandLineLauncher {
|
||||
jsap.registerParameter(optionArg);
|
||||
|
||||
// Definition directories
|
||||
optionArg = new FlaggedOption("defInput");
|
||||
optionArg = new FlaggedOption(JSweetOptions.defInput);
|
||||
optionArg.setShortFlag('d');
|
||||
optionArg.setLongFlag("defInput");
|
||||
optionArg.setLongFlag(JSweetOptions.defInput);
|
||||
optionArg.setList(true);
|
||||
optionArg.setStringParser(FileStringParser.getParser());
|
||||
optionArg.setListSeparator(File.pathSeparatorChar);
|
||||
@ -400,16 +400,16 @@ public class JSweetCommandLineLauncher {
|
||||
jsap.registerParameter(optionArg);
|
||||
|
||||
// Skip empty root dirs
|
||||
switchArg = new Switch("noRootDirectories");
|
||||
switchArg.setLongFlag("noRootDirectories");
|
||||
switchArg = new Switch(JSweetOptions.noRootDirectories);
|
||||
switchArg.setLongFlag(JSweetOptions.noRootDirectories);
|
||||
switchArg.setHelp(
|
||||
"Skip the root directories (i.e. packages annotated with @jsweet.lang.Root) so that the generated file hierarchy starts at the root directories rather than including the entire directory structure.");
|
||||
switchArg.setDefault("false");
|
||||
jsap.registerParameter(switchArg);
|
||||
|
||||
// TypeScript output directory
|
||||
optionArg = new FlaggedOption("tsout");
|
||||
optionArg.setLongFlag("tsout");
|
||||
optionArg = new FlaggedOption(JSweetOptions.tsout);
|
||||
optionArg.setLongFlag(JSweetOptions.tsout);
|
||||
optionArg.setDefault(".ts");
|
||||
optionArg.setHelp("Specify where to place generated TypeScript files.");
|
||||
optionArg.setStringParser(FileStringParser.getParser());
|
||||
@ -417,9 +417,9 @@ public class JSweetCommandLineLauncher {
|
||||
jsap.registerParameter(optionArg);
|
||||
|
||||
// JavaScript output directory
|
||||
optionArg = new FlaggedOption("jsout");
|
||||
optionArg = new FlaggedOption(JSweetOptions.jsout);
|
||||
optionArg.setShortFlag('o');
|
||||
optionArg.setLongFlag("jsout");
|
||||
optionArg.setLongFlag(JSweetOptions.jsout);
|
||||
optionArg.setDefault("js");
|
||||
optionArg.setHelp("Specify where to place generated JavaScript files (ignored if jsFile is specified).");
|
||||
optionArg.setStringParser(FileStringParser.getParser());
|
||||
@ -427,41 +427,48 @@ public class JSweetCommandLineLauncher {
|
||||
jsap.registerParameter(optionArg);
|
||||
|
||||
// Disable single precision floats
|
||||
switchArg = new Switch("disableSinglePrecisionFloats");
|
||||
switchArg.setLongFlag("disableSinglePrecisionFloats");
|
||||
switchArg = new Switch(JSweetOptions.disableSinglePrecisionFloats);
|
||||
switchArg.setLongFlag(JSweetOptions.disableSinglePrecisionFloats);
|
||||
switchArg.setHelp(
|
||||
"By default, for a target version >=ES5, JSweet will force Java floats to be mapped to JavaScript numbers that will be constrained with ES5 Math.fround function. If this option is true, then the calls to Math.fround are erased and the generated program will use the JavaScript default precision (double precision).");
|
||||
jsap.registerParameter(switchArg);
|
||||
|
||||
// Transients as non-enumerable properties
|
||||
switchArg = new Switch(JSweetOptions.nonEnumerableTransients);
|
||||
switchArg.setLongFlag(JSweetOptions.nonEnumerableTransients);
|
||||
switchArg.setHelp(
|
||||
"Generate Java transient fields as non-enumerable JavaScript properties..");
|
||||
jsap.registerParameter(switchArg);
|
||||
|
||||
// Do not generate JavaScript
|
||||
switchArg = new Switch("tsOnly");
|
||||
switchArg.setLongFlag("tsOnly");
|
||||
switchArg = new Switch(JSweetOptions.tsOnly);
|
||||
switchArg.setLongFlag(JSweetOptions.tsOnly);
|
||||
switchArg.setHelp("Do not compile the TypeScript output (let an external TypeScript compiler do so).");
|
||||
jsap.registerParameter(switchArg);
|
||||
|
||||
// Do not generate d.ts files that correspond to def.* packages
|
||||
switchArg = new Switch("ignoreDefinitions");
|
||||
switchArg.setLongFlag("ignoreDefinitions");
|
||||
switchArg = new Switch(JSweetOptions.ignoreDefinitions);
|
||||
switchArg.setLongFlag(JSweetOptions.ignoreDefinitions);
|
||||
switchArg.setHelp(
|
||||
"Ignore definitions from def.* packages, so that they are not generated in d.ts definition files. If this option is not set, the transpiler generates d.ts definition files in the directory given by the tsout option.");
|
||||
jsap.registerParameter(switchArg);
|
||||
|
||||
switchArg = new Switch("ignoreJavaErrors");
|
||||
switchArg.setLongFlag("ignoreJavaErrors");
|
||||
switchArg = new Switch(JSweetOptions.ignoreJavaErrors);
|
||||
switchArg.setLongFlag(JSweetOptions.ignoreJavaErrors);
|
||||
switchArg.setHelp(
|
||||
"Ignore Java compilation errors. Do not use unless you know what you are doing.");
|
||||
jsap.registerParameter(switchArg);
|
||||
|
||||
// Generates declarations
|
||||
switchArg = new Switch("declaration");
|
||||
switchArg.setLongFlag("declaration");
|
||||
switchArg = new Switch(JSweetOptions.declaration);
|
||||
switchArg.setLongFlag(JSweetOptions.declaration);
|
||||
switchArg.setHelp(
|
||||
"Generate the d.ts files along with the js files, so that other programs can use them to compile.");
|
||||
jsap.registerParameter(switchArg);
|
||||
|
||||
// Declarations output directory
|
||||
optionArg = new FlaggedOption("dtsout");
|
||||
optionArg.setLongFlag("dtsout");
|
||||
optionArg = new FlaggedOption(JSweetOptions.dtsout);
|
||||
optionArg.setLongFlag(JSweetOptions.dtsout);
|
||||
optionArg.setHelp(
|
||||
"Specify where to place generated d.ts files when the declaration option is set (by default, d.ts files are generated in the JavaScript output directory - next to the corresponding js files).");
|
||||
optionArg.setStringParser(FileStringParser.getParser());
|
||||
@ -469,8 +476,8 @@ public class JSweetCommandLineLauncher {
|
||||
jsap.registerParameter(optionArg);
|
||||
|
||||
// Candies javascript output directory
|
||||
optionArg = new FlaggedOption("candiesJsOut");
|
||||
optionArg.setLongFlag("candiesJsOut");
|
||||
optionArg = new FlaggedOption(JSweetOptions.candiesJsOut);
|
||||
optionArg.setLongFlag(JSweetOptions.candiesJsOut);
|
||||
optionArg.setDefault("js/candies");
|
||||
optionArg.setHelp("Specify where to place extracted JavaScript files from candies.");
|
||||
optionArg.setStringParser(FileStringParser.getParser());
|
||||
@ -478,8 +485,8 @@ public class JSweetCommandLineLauncher {
|
||||
jsap.registerParameter(optionArg);
|
||||
|
||||
// Source root directory for source maps
|
||||
optionArg = new FlaggedOption("sourceRoot");
|
||||
optionArg.setLongFlag("sourceRoot");
|
||||
optionArg = new FlaggedOption(JSweetOptions.sourceRoot);
|
||||
optionArg.setLongFlag(JSweetOptions.sourceRoot);
|
||||
optionArg.setHelp(
|
||||
"Specify the location where debugger should locate Java files instead of source locations. Use this flag if the sources will be located at run-time in a different location than that at design-time. The location specified will be embedded in the sourceMap to direct the debugger where the source files will be located.");
|
||||
optionArg.setStringParser(FileStringParser.getParser());
|
||||
@ -487,8 +494,8 @@ public class JSweetCommandLineLauncher {
|
||||
jsap.registerParameter(optionArg);
|
||||
|
||||
// Classpath
|
||||
optionArg = new FlaggedOption("classpath");
|
||||
optionArg.setLongFlag("classpath");
|
||||
optionArg = new FlaggedOption(JSweetOptions.classpath);
|
||||
optionArg.setLongFlag(JSweetOptions.classpath);
|
||||
optionArg.setHelp(
|
||||
"The JSweet transpilation classpath (candy jars). This classpath should at least contain the core candy.");
|
||||
optionArg.setStringParser(JSAP.STRING_PARSER);
|
||||
@ -496,8 +503,8 @@ public class JSweetCommandLineLauncher {
|
||||
jsap.registerParameter(optionArg);
|
||||
|
||||
// Module
|
||||
optionArg = new FlaggedOption("module");
|
||||
optionArg.setLongFlag("module");
|
||||
optionArg = new FlaggedOption(JSweetOptions.module);
|
||||
optionArg.setLongFlag(JSweetOptions.module);
|
||||
optionArg.setShortFlag('m');
|
||||
optionArg.setDefault("none");
|
||||
optionArg.setHelp("The module kind (none, commonjs, amd, system, umd, es2015).");
|
||||
@ -515,8 +522,8 @@ public class JSweetCommandLineLauncher {
|
||||
jsap.registerParameter(optionArg);
|
||||
|
||||
// Bundle
|
||||
switchArg = new Switch("bundle");
|
||||
switchArg.setLongFlag("bundle");
|
||||
switchArg = new Switch(JSweetOptions.bundle);
|
||||
switchArg.setLongFlag(JSweetOptions.bundle);
|
||||
switchArg.setShortFlag('b');
|
||||
switchArg.setHelp(
|
||||
"Bundle up all the generated code in a single file, which can be used in the browser. The bundle files are called 'bundle.ts', 'bundle.d.ts', or 'bundle.js' depending on the kind of generated code. NOTE: bundles are not compatible with any module kind other than 'none'.");
|
||||
@ -551,23 +558,23 @@ public class JSweetCommandLineLauncher {
|
||||
// jsap.registerParameter(optionArg);
|
||||
|
||||
// Debug
|
||||
switchArg = new Switch("sourceMap");
|
||||
switchArg.setLongFlag("sourceMap");
|
||||
switchArg = new Switch(JSweetOptions.sourceMap);
|
||||
switchArg.setLongFlag(JSweetOptions.sourceMap);
|
||||
switchArg.setHelp(
|
||||
"Generate source map files for the Java files, so that it is possible to debug Java files directly with a debugger that supports source maps (most JavaScript debuggers).");
|
||||
switchArg.setDefault("false");
|
||||
jsap.registerParameter(switchArg);
|
||||
|
||||
// Enable assertions
|
||||
switchArg = new Switch("enableAssertions");
|
||||
switchArg.setLongFlag("enableAssertions");
|
||||
switchArg = new Switch(JSweetOptions.enableAssertions);
|
||||
switchArg.setLongFlag(JSweetOptions.enableAssertions);
|
||||
switchArg.setHelp("Java 'assert' statements are transpiled as runtime JavaScript checks.");
|
||||
switchArg.setDefault("false");
|
||||
jsap.registerParameter(switchArg);
|
||||
|
||||
// Header file
|
||||
optionArg = new FlaggedOption("header");
|
||||
optionArg.setLongFlag("header");
|
||||
optionArg = new FlaggedOption(JSweetOptions.header);
|
||||
optionArg.setLongFlag(JSweetOptions.header);
|
||||
optionArg.setHelp(
|
||||
"A file that contains a header to be written at the beginning of each generated file. If left unspecified, JSweet will generate a default header.");
|
||||
optionArg.setStringParser(FileStringParser.getParser());
|
||||
@ -583,8 +590,8 @@ public class JSweetCommandLineLauncher {
|
||||
optionArg.setRequired(false);
|
||||
jsap.registerParameter(optionArg);
|
||||
|
||||
optionArg = new FlaggedOption("targetVersion");
|
||||
optionArg.setLongFlag("targetVersion");
|
||||
optionArg = new FlaggedOption(JSweetOptions.targetVersion);
|
||||
optionArg.setLongFlag(JSweetOptions.targetVersion);
|
||||
optionArg.setHelp("The EcmaScript target (JavaScript) version. Possible values: "
|
||||
+ Arrays.asList(EcmaScriptComplianceLevel.values()));
|
||||
optionArg.setDefault("ES3");
|
||||
@ -600,15 +607,24 @@ public class JSweetCommandLineLauncher {
|
||||
jsap.registerParameter(optionArg);
|
||||
|
||||
// Disable statics lazy initialization
|
||||
switchArg = new Switch("disableStaticsLazyInitialization");
|
||||
switchArg.setLongFlag("disableStaticsLazyInitialization");
|
||||
switchArg = new Switch(JSweetOptions.disableStaticsLazyInitialization);
|
||||
switchArg.setLongFlag(JSweetOptions.disableStaticsLazyInitialization);
|
||||
switchArg.setHelp(
|
||||
"Do not generate lazy initialization code of static fields that is meant " +
|
||||
"to emulate the Java behavior. When disables, the code is more readable " +
|
||||
"but it may result into runtime static initialization issues (cross-class " +
|
||||
"static dependencies).");
|
||||
jsap.registerParameter(switchArg);
|
||||
|
||||
|
||||
// Sort class members
|
||||
switchArg = new Switch(JSweetOptions.sortClassMembers);
|
||||
switchArg.setLongFlag(JSweetOptions.sortClassMembers);
|
||||
switchArg.setHelp(
|
||||
"If enabled, class members are sorted using " +
|
||||
"PrinterAdapter#getClassMemberComparator(), to be overloaded by the user to "+
|
||||
"implement the desired order.");
|
||||
jsap.registerParameter(switchArg);
|
||||
|
||||
return jsap;
|
||||
}
|
||||
|
||||
@ -662,7 +678,7 @@ public class JSweetCommandLineLauncher {
|
||||
|
||||
@Override
|
||||
public void run() throws Exception {
|
||||
String classPath = jsapArgs.getString("classpath");
|
||||
String classPath = jsapArgs.getString(JSweetOptions.classpath);
|
||||
logger.info("classpath: " + classPath);
|
||||
|
||||
ErrorCountTranspilationHandler transpilationHandler = new ErrorCountTranspilationHandler(
|
||||
@ -724,32 +740,32 @@ public class JSweetCommandLineLauncher {
|
||||
javaInputFiles.addAll(extraJavaInputFiles);
|
||||
|
||||
File tsOutputDir = null;
|
||||
if (jsapArgs.userSpecified("tsout") && jsapArgs.getFile("tsout") != null) {
|
||||
tsOutputDir = jsapArgs.getFile("tsout");
|
||||
if (jsapArgs.userSpecified(JSweetOptions.tsout) && jsapArgs.getFile(JSweetOptions.tsout) != null) {
|
||||
tsOutputDir = jsapArgs.getFile(JSweetOptions.tsout);
|
||||
tsOutputDir.mkdirs();
|
||||
}
|
||||
logger.info("ts output dir: " + tsOutputDir);
|
||||
|
||||
File jsOutputDir = null;
|
||||
if (jsapArgs.userSpecified("jsout") && jsapArgs.getFile("jsout") != null) {
|
||||
jsOutputDir = jsapArgs.getFile("jsout");
|
||||
if (jsapArgs.userSpecified(JSweetOptions.jsout) && jsapArgs.getFile(JSweetOptions.jsout) != null) {
|
||||
jsOutputDir = jsapArgs.getFile(JSweetOptions.jsout);
|
||||
jsOutputDir.mkdirs();
|
||||
}
|
||||
logger.info("js output dir: " + jsOutputDir);
|
||||
|
||||
File dtsOutputDir = null;
|
||||
if (jsapArgs.userSpecified("dtsout") && jsapArgs.getFile("dtsout") != null) {
|
||||
dtsOutputDir = jsapArgs.getFile("dtsout");
|
||||
if (jsapArgs.userSpecified(JSweetOptions.dtsout) && jsapArgs.getFile(JSweetOptions.dtsout) != null) {
|
||||
dtsOutputDir = jsapArgs.getFile(JSweetOptions.dtsout);
|
||||
}
|
||||
|
||||
File candiesJsOutputDir = null;
|
||||
if (jsapArgs.userSpecified("candiesJsOut") && jsapArgs.getFile("candiesJsOut") != null) {
|
||||
candiesJsOutputDir = jsapArgs.getFile("candiesJsOut");
|
||||
if (jsapArgs.userSpecified(JSweetOptions.candiesJsOut) && jsapArgs.getFile(JSweetOptions.candiesJsOut) != null) {
|
||||
candiesJsOutputDir = jsapArgs.getFile(JSweetOptions.candiesJsOut);
|
||||
}
|
||||
|
||||
File sourceRootDir = null;
|
||||
if (jsapArgs.userSpecified("sourceRoot") && jsapArgs.getFile("sourceRoot") != null) {
|
||||
sourceRootDir = jsapArgs.getFile("sourceRoot");
|
||||
if (jsapArgs.userSpecified(JSweetOptions.sourceRoot) && jsapArgs.getFile(JSweetOptions.sourceRoot) != null) {
|
||||
sourceRootDir = jsapArgs.getFile(JSweetOptions.sourceRoot);
|
||||
}
|
||||
|
||||
JSweetFactory factory = null;
|
||||
@ -779,65 +795,71 @@ public class JSweetCommandLineLauncher {
|
||||
JSweetTranspiler transpiler = new JSweetTranspiler(factory, jsapArgs.getFile("workingDir"), tsOutputDir,
|
||||
jsOutputDir, candiesJsOutputDir, classPath);
|
||||
|
||||
if (jsapArgs.userSpecified("bundle")) {
|
||||
transpiler.setBundle(jsapArgs.getBoolean("bundle"));
|
||||
if (jsapArgs.userSpecified(JSweetOptions.bundle)) {
|
||||
transpiler.setBundle(jsapArgs.getBoolean(JSweetOptions.bundle));
|
||||
}
|
||||
if (jsapArgs.userSpecified("noRootDirectories")) {
|
||||
transpiler.setNoRootDirectories(jsapArgs.getBoolean("noRootDirectories"));
|
||||
if (jsapArgs.userSpecified(JSweetOptions.noRootDirectories)) {
|
||||
transpiler.setNoRootDirectories(jsapArgs.getBoolean(JSweetOptions.noRootDirectories));
|
||||
}
|
||||
if (jsapArgs.userSpecified("sourceMap")) {
|
||||
transpiler.setGenerateSourceMaps(jsapArgs.getBoolean("sourceMap"));
|
||||
if (jsapArgs.userSpecified(JSweetOptions.sourceMap)) {
|
||||
transpiler.setGenerateSourceMaps(jsapArgs.getBoolean(JSweetOptions.sourceMap));
|
||||
}
|
||||
if (sourceRootDir != null) {
|
||||
transpiler.setSourceRoot(sourceRootDir);
|
||||
}
|
||||
if (jsapArgs.userSpecified("module")) {
|
||||
transpiler.setModuleKind(ModuleKind.valueOf(jsapArgs.getString("module")));
|
||||
if (jsapArgs.userSpecified(JSweetOptions.module)) {
|
||||
transpiler.setModuleKind(ModuleKind.valueOf(jsapArgs.getString(JSweetOptions.module)));
|
||||
}
|
||||
if (jsapArgs.userSpecified(JSweetOptions.moduleResolution)) {
|
||||
transpiler.setModuleResolution(
|
||||
ModuleResolution.valueOf(jsapArgs.getString(JSweetOptions.moduleResolution)));
|
||||
}
|
||||
if (jsapArgs.userSpecified("encoding")) {
|
||||
transpiler.setEncoding(jsapArgs.getString("encoding"));
|
||||
if (jsapArgs.userSpecified(JSweetOptions.encoding)) {
|
||||
transpiler.setEncoding(jsapArgs.getString(JSweetOptions.encoding));
|
||||
}
|
||||
if (jsapArgs.userSpecified("outEncoding")) {
|
||||
transpiler.setOutEncoding(jsapArgs.getString("outEncoding"));
|
||||
if (jsapArgs.userSpecified(JSweetOptions.outEncoding)) {
|
||||
transpiler.setOutEncoding(jsapArgs.getString(JSweetOptions.outEncoding));
|
||||
}
|
||||
if (jsapArgs.userSpecified("enableAssertions")) {
|
||||
transpiler.setIgnoreAssertions(!jsapArgs.getBoolean("enableAssertions"));
|
||||
if (jsapArgs.userSpecified(JSweetOptions.nonEnumerableTransients)) {
|
||||
transpiler.setNonEnumerableTransients(jsapArgs.getBoolean(JSweetOptions.nonEnumerableTransients));
|
||||
}
|
||||
if (jsapArgs.userSpecified(JSweetOptions.enableAssertions)) {
|
||||
transpiler.setIgnoreAssertions(!jsapArgs.getBoolean(JSweetOptions.enableAssertions));
|
||||
}
|
||||
if (jsapArgs.userSpecified("declaration")) {
|
||||
transpiler.setGenerateDeclarations(jsapArgs.getBoolean("declaration"));
|
||||
if (jsapArgs.userSpecified(JSweetOptions.declaration)) {
|
||||
transpiler.setGenerateDeclarations(jsapArgs.getBoolean(JSweetOptions.declaration));
|
||||
}
|
||||
if (jsapArgs.userSpecified("tsOnly")) {
|
||||
transpiler.setGenerateJsFiles(!jsapArgs.getBoolean("tsOnly"));
|
||||
if (jsapArgs.userSpecified(JSweetOptions.tsOnly)) {
|
||||
transpiler.setGenerateJsFiles(!jsapArgs.getBoolean(JSweetOptions.tsOnly));
|
||||
}
|
||||
if (jsapArgs.userSpecified("ignoreDefinitions")) {
|
||||
transpiler.setGenerateDefinitions(!jsapArgs.getBoolean("ignoreDefinitions"));
|
||||
if (jsapArgs.userSpecified(JSweetOptions.ignoreDefinitions)) {
|
||||
transpiler.setGenerateDefinitions(!jsapArgs.getBoolean(JSweetOptions.ignoreDefinitions));
|
||||
}
|
||||
if (jsapArgs.userSpecified("ignoreJavaErrors")) {
|
||||
transpiler.setIgnoreJavaErrors(jsapArgs.getBoolean("ignoreJavaErrors"));
|
||||
if (jsapArgs.userSpecified(JSweetOptions.ignoreJavaErrors)) {
|
||||
transpiler.setIgnoreJavaErrors(jsapArgs.getBoolean(JSweetOptions.ignoreJavaErrors));
|
||||
}
|
||||
if (jsapArgs.userSpecified("dtsout")) {
|
||||
if (jsapArgs.userSpecified(JSweetOptions.dtsout)) {
|
||||
transpiler.setDeclarationsOutputDir(dtsOutputDir);
|
||||
}
|
||||
if (jsapArgs.userSpecified("header")) {
|
||||
transpiler.setHeaderFile(jsapArgs.getFile("header"));
|
||||
if (jsapArgs.userSpecified(JSweetOptions.header)) {
|
||||
transpiler.setHeaderFile(jsapArgs.getFile(JSweetOptions.header));
|
||||
}
|
||||
if (jsapArgs.userSpecified("targetVersion")) {
|
||||
if (jsapArgs.userSpecified(JSweetOptions.targetVersion)) {
|
||||
transpiler.setEcmaTargetVersion(
|
||||
JSweetTranspiler.getEcmaTargetVersion(jsapArgs.getString("targetVersion")));
|
||||
JSweetTranspiler.getEcmaTargetVersion(jsapArgs.getString(JSweetOptions.targetVersion)));
|
||||
}
|
||||
if (jsapArgs.userSpecified("disableSinglePrecisionFloats")) {
|
||||
transpiler.setDisableSinglePrecisionFloats(jsapArgs.getBoolean("disableSinglePrecisionFloats"));
|
||||
if (jsapArgs.userSpecified(JSweetOptions.disableSinglePrecisionFloats)) {
|
||||
transpiler.setDisableSinglePrecisionFloats(jsapArgs.getBoolean(JSweetOptions.disableSinglePrecisionFloats));
|
||||
}
|
||||
if (jsapArgs.userSpecified(JSweetOptions.extraSystemPath)) {
|
||||
ProcessUtil.addExtraPath(jsapArgs.getString(JSweetOptions.extraSystemPath));
|
||||
}
|
||||
if (jsapArgs.userSpecified("disableStaticsLazyInitialization")) {
|
||||
transpiler.setLazyInitializedStatics(!jsapArgs.getBoolean("disableStaticsLazyInitialization"));
|
||||
if (jsapArgs.userSpecified(JSweetOptions.disableStaticsLazyInitialization)) {
|
||||
transpiler.setLazyInitializedStatics(!jsapArgs.getBoolean(JSweetOptions.disableStaticsLazyInitialization));
|
||||
}
|
||||
if (jsapArgs.userSpecified(JSweetOptions.sortClassMembers)) {
|
||||
transpiler.setSortClassMembers(jsapArgs.getBoolean(JSweetOptions.sortClassMembers));
|
||||
}
|
||||
|
||||
if (tsOutputDir != null) {
|
||||
transpiler.setTsOutputDir(tsOutputDir);
|
||||
@ -848,7 +870,7 @@ public class JSweetCommandLineLauncher {
|
||||
|
||||
// transpiler.setAdapters(Arrays.asList(jsapArgs.getStringArray("adapters")));
|
||||
|
||||
List<File> files = Arrays.asList(jsapArgs.getFileArray("defInput"));
|
||||
List<File> files = Arrays.asList(jsapArgs.getFileArray(JSweetOptions.defInput));
|
||||
logger.info("definition input dirs: " + files);
|
||||
|
||||
for (File f : files) {
|
||||
|
||||
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.lang.model.element.ElementKind;
|
||||
|
||||
import org.jsweet.transpiler.util.Util;
|
||||
|
||||
import com.sun.tools.javac.code.Symbol;
|
||||
import com.sun.tools.javac.code.Symbol.VarSymbol;
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.tree.JCTree.JCAssign;
|
||||
import com.sun.tools.javac.tree.JCTree.JCAssignOp;
|
||||
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
|
||||
import com.sun.tools.javac.tree.JCTree.JCIdent;
|
||||
import com.sun.tools.javac.tree.JCTree.JCUnary;
|
||||
import com.sun.tools.javac.tree.TreeScanner;
|
||||
|
||||
/**
|
||||
* This AST scanner analyzes local variables to determine if they are locally
|
||||
* assigned and can be assumed constant or not.
|
||||
*
|
||||
* @see JSweetContext
|
||||
* @author Renaud Pawlak
|
||||
*/
|
||||
public class ConstAnalyzer extends TreeScanner {
|
||||
|
||||
private Set<VarSymbol> modifiedVariables = new HashSet<>();
|
||||
private ElementKind variableKind = ElementKind.LOCAL_VARIABLE;
|
||||
private boolean initializationOnly = false;
|
||||
|
||||
/**
|
||||
* Create a constant variable analyzer on local variables only (default).
|
||||
*/
|
||||
public ConstAnalyzer() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a constant variable analyzer on the given kind of variable.
|
||||
*
|
||||
* @param variableKind the variable kind to analyze (if null, analyzes all kinds
|
||||
* of variables)
|
||||
* @param initializationOnly only takes into account direct assignments and not self-dependent modifications
|
||||
*/
|
||||
public ConstAnalyzer(ElementKind variableKind, boolean initializationOnly) {
|
||||
this.variableKind = variableKind;
|
||||
this.initializationOnly = initializationOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the local variables that are modified within the program. All other
|
||||
* local variables can be assumed as constant.
|
||||
*/
|
||||
public Set<VarSymbol> getModifiedVariables() {
|
||||
return modifiedVariables;
|
||||
}
|
||||
|
||||
private void registerModification(JCTree tree) {
|
||||
Symbol symbol = Util.getAccessedSymbol(tree);
|
||||
if (symbol != null && (variableKind == null || symbol.getKind() == variableKind)) {
|
||||
modifiedVariables.add((VarSymbol) symbol);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAssign(JCAssign assign) {
|
||||
// TODO: should check if rhs contains self reference for initialization only
|
||||
registerModification(assign.lhs);
|
||||
super.visitAssign(assign);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitAssignop(JCAssignOp assignOp) {
|
||||
if (!this.initializationOnly) {
|
||||
registerModification(assignOp.lhs);
|
||||
}
|
||||
super.visitAssignop(assignOp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitUnary(JCUnary unary) {
|
||||
switch (unary.getTag()) {
|
||||
case PREINC:
|
||||
case POSTINC:
|
||||
case PREDEC:
|
||||
case POSTDEC:
|
||||
if (!this.initializationOnly) {
|
||||
registerModification(unary.arg);
|
||||
}
|
||||
default:
|
||||
}
|
||||
super.visitUnary(unary);
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans a given compilation unit list.
|
||||
*/
|
||||
public void process(List<JCCompilationUnit> cuList) {
|
||||
for (JCCompilationUnit cu : cuList) {
|
||||
scan(cu);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -116,6 +116,17 @@ public class JSweetContext extends Context {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The constant variables (variables assigned only at initialization) scanner
|
||||
* and accessor.
|
||||
*
|
||||
* <p>TODO: This scanner is run globally (for all compilation units) before
|
||||
* translation. It could be run locally to each compilation unit, except for
|
||||
* default methods that are injected in the target classes.
|
||||
*/
|
||||
public ConstAnalyzer constAnalyzer = null;
|
||||
|
||||
private Map<String, TypeMirror> jdkSubclasses = new HashMap<>();
|
||||
|
||||
public StaticInitilializerAnalyzer referenceAnalyzer;
|
||||
|
||||
@ -71,6 +71,10 @@ public interface JSweetOptions {
|
||||
* Constant string for the 'ignoreDefinitions' option.
|
||||
*/
|
||||
String ignoreDefinitions = "ignoreDefinitions";
|
||||
/**
|
||||
* Constant string for the 'ignoreJavaErrors' option.
|
||||
*/
|
||||
String ignoreJavaErrors = "ignoreJavaErrors";
|
||||
/**
|
||||
* Constant string for the 'header' option.
|
||||
*/
|
||||
@ -99,6 +103,14 @@ public interface JSweetOptions {
|
||||
* Constant string for the 'jsout' option.
|
||||
*/
|
||||
String jsout = "jsout";
|
||||
/**
|
||||
* Constant string for the 'sourceRoot' option.
|
||||
*/
|
||||
String sourceRoot = "sourceRoot";
|
||||
/**
|
||||
* Constant string for the 'defInput' option.
|
||||
*/
|
||||
String defInput = "defInput";
|
||||
/**
|
||||
* Constant string for the 'candiesJsOut' option.
|
||||
*/
|
||||
@ -117,13 +129,28 @@ public interface JSweetOptions {
|
||||
*/
|
||||
String useSingleQuotesForStringLiterals = "useSingleQuotesForStringLiterals";
|
||||
|
||||
/**
|
||||
* Constant string for the 'nonEnumerableTransients' option.
|
||||
*/
|
||||
String nonEnumerableTransients = "nonEnumerableTransients";
|
||||
|
||||
/**
|
||||
* Constant string for the 'classpath' option.
|
||||
*/
|
||||
String classpath = "classpath";
|
||||
|
||||
/**
|
||||
* Constant string for the 'sortClassMembers' option.
|
||||
*/
|
||||
String sortClassMembers = "sortClassMembers";
|
||||
|
||||
/**
|
||||
* All the supported options (used to report non-blocking errors when options do not exist).
|
||||
*/
|
||||
String[] options = { bundle, noRootDirectories, sourceMap, module, encoding, outEncoding, enableAssertions,
|
||||
declaration, tsOnly, ignoreDefinitions, header, disableSinglePrecisionFloats,
|
||||
declaration, tsOnly, ignoreDefinitions, ignoreJavaErrors, header, disableSinglePrecisionFloats,
|
||||
disableStaticsLazyInitialization, targetVersion, tsout, dtsout, jsout, candiesJsOut, moduleResolution,
|
||||
extraSystemPath, useSingleQuotesForStringLiterals };
|
||||
extraSystemPath, useSingleQuotesForStringLiterals, nonEnumerableTransients, classpath, sortClassMembers };
|
||||
|
||||
/**
|
||||
* Returns the configuration from the configuration file.
|
||||
@ -337,4 +364,15 @@ public interface JSweetOptions {
|
||||
*/
|
||||
boolean isUseSingleQuotesForStringLiterals();
|
||||
|
||||
/**
|
||||
* If true, the transpiler generates Java transient fields as non-enumerable
|
||||
* JavaScript properties.
|
||||
*/
|
||||
boolean isNonEnumerableTransients();
|
||||
|
||||
/**
|
||||
* If true, class members are sorted using
|
||||
* {@link PrinterAdapter#getClassMemberComparator()}.
|
||||
*/
|
||||
boolean isSortClassMembers();
|
||||
}
|
||||
@ -241,6 +241,8 @@ public class JSweetTranspiler implements JSweetOptions {
|
||||
private boolean ignoreCandiesTypeScriptDefinitions = false;
|
||||
private boolean lazyInitializedStatics = true;
|
||||
private boolean useSingleQuotesForStringLiterals = false;
|
||||
private boolean nonEnumerableTransients = false;
|
||||
private boolean sortClassMembers = false;
|
||||
|
||||
private ArrayList<String> adapters = new ArrayList<>();
|
||||
private File configurationFile;
|
||||
@ -394,6 +396,12 @@ public class JSweetTranspiler implements JSweetOptions {
|
||||
}
|
||||
if (options.containsKey(JSweetOptions.useSingleQuotesForStringLiterals)) {
|
||||
setUseSingleQuotesForStringLiterals((Boolean) getMapValue(options, JSweetOptions.useSingleQuotesForStringLiterals));
|
||||
}
|
||||
if (options.containsKey(JSweetOptions.ignoreJavaErrors)) {
|
||||
setIgnoreJavaErrors((Boolean) getMapValue(options, JSweetOptions.ignoreJavaErrors));
|
||||
}
|
||||
if (options.containsKey(JSweetOptions.nonEnumerableTransients)) {
|
||||
setNonEnumerableTransients((Boolean) getMapValue(options, JSweetOptions.nonEnumerableTransients));
|
||||
}
|
||||
}
|
||||
|
||||
@ -712,11 +720,9 @@ public class JSweetTranspiler implements JSweetOptions {
|
||||
SourceFile... sourceFiles) throws Exception {
|
||||
logger.info("[" + engineName + " engine] eval files: " + Arrays.asList(sourceFiles));
|
||||
|
||||
EvalOptions options = new EvalOptions(isUsingModules(), workingDir);
|
||||
|
||||
if ("Java".equals(engineName)) {
|
||||
|
||||
JavaEval evaluator = new JavaEval(this, options);
|
||||
JavaEval evaluator = new JavaEval(this, new EvalOptions(isUsingModules(), workingDir, false));
|
||||
return evaluator.performEval(sourceFiles);
|
||||
} else {
|
||||
if (!areAllTranspiled(sourceFiles)) {
|
||||
@ -747,7 +753,9 @@ public class JSweetTranspiler implements JSweetOptions {
|
||||
jsFiles = Stream.of(sourceFiles).map(sourceFile -> sourceFile.getJsFile()).collect(toList());
|
||||
}
|
||||
|
||||
JavaScriptEval evaluator = new JavaScriptEval(options, JavaScriptRuntime.NodeJs);
|
||||
JavaScriptEval evaluator = new JavaScriptEval(
|
||||
new EvalOptions(isUsingModules(), workingDir, context.isUsingJavaRuntime()),
|
||||
JavaScriptRuntime.NodeJs);
|
||||
return evaluator.performEval(jsFiles);
|
||||
}
|
||||
}
|
||||
@ -983,6 +991,8 @@ public class JSweetTranspiler implements JSweetOptions {
|
||||
List<JCCompilationUnit> compilationUnits) throws IOException {
|
||||
// regular file-to-file generation
|
||||
new OverloadScanner(transpilationHandler, context).process(compilationUnits);
|
||||
context.constAnalyzer = new ConstAnalyzer();
|
||||
context.constAnalyzer.scan(compilationUnits);
|
||||
|
||||
if (isVerbose()) {
|
||||
context.dumpOverloads(System.out);
|
||||
@ -1115,7 +1125,9 @@ public class JSweetTranspiler implements JSweetOptions {
|
||||
}
|
||||
|
||||
new OverloadScanner(transpilationHandler, context).process(orderedCompilationUnits);
|
||||
|
||||
context.constAnalyzer = new ConstAnalyzer();
|
||||
context.constAnalyzer.process(orderedCompilationUnits);
|
||||
|
||||
adapter.onTranspilationStarted();
|
||||
|
||||
logger.debug("ordered compilation units: " + orderedCompilationUnits.stream().map(cu -> {
|
||||
@ -1929,4 +1941,22 @@ public class JSweetTranspiler implements JSweetOptions {
|
||||
this.useSingleQuotesForStringLiterals = useSingleQuotesForStringLiterals;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNonEnumerableTransients() {
|
||||
return this.nonEnumerableTransients;
|
||||
}
|
||||
|
||||
public void setNonEnumerableTransients(boolean nonEnumerableTransients) {
|
||||
this.nonEnumerableTransients = nonEnumerableTransients;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSortClassMembers() {
|
||||
return this.sortClassMembers;
|
||||
}
|
||||
|
||||
public void setSortClassMembers(boolean sortClassMembers) {
|
||||
this.sortClassMembers = sortClassMembers;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -66,6 +66,7 @@ import org.jsweet.transpiler.extension.PrinterAdapter;
|
||||
import org.jsweet.transpiler.model.ExtendedElement;
|
||||
import org.jsweet.transpiler.model.ExtendedElementFactory;
|
||||
import org.jsweet.transpiler.model.MethodInvocationElement;
|
||||
import org.jsweet.transpiler.model.TypeCastElement;
|
||||
import org.jsweet.transpiler.model.support.ArrayAccessElementSupport;
|
||||
import org.jsweet.transpiler.model.support.AssignmentElementSupport;
|
||||
import org.jsweet.transpiler.model.support.AssignmentWithOperatorElementSupport;
|
||||
@ -736,7 +737,7 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
footer.delete(0, footer.length());
|
||||
|
||||
setCompilationUnit(topLevel);
|
||||
|
||||
|
||||
String packge = topLevel.packge.toString();
|
||||
|
||||
boolean globalModule = JSweetConfig.GLOBALS_PACKAGE_NAME.equals(packge)
|
||||
@ -1633,8 +1634,10 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
printIndent().print("public " + PARENT_CLASS_FIELD_NAME + ": any;").println();
|
||||
}
|
||||
|
||||
Set<JCMethodDecl> injectedDefaultMethods = new HashSet<>();
|
||||
Map<JCMethodDecl, MethodSymbol> injectedDefaultMethodMap = new HashMap<>();
|
||||
|
||||
if (defaultMethods != null && !defaultMethods.isEmpty()) {
|
||||
getScope().defaultMethodScope = true;
|
||||
for (Entry<JCClassDecl, JCMethodDecl> entry : defaultMethods) {
|
||||
if (!(entry.getValue().type instanceof MethodType)) {
|
||||
continue;
|
||||
@ -1642,36 +1645,10 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
MethodSymbol s = Util.findMethodDeclarationInType2(context.types, classdecl.sym,
|
||||
entry.getValue().getName().toString(), (MethodType) entry.getValue().type);
|
||||
if (s == null || s == entry.getValue().sym) {
|
||||
getAdapter().typeVariablesToErase
|
||||
.addAll(((ClassSymbol) s.getEnclosingElement()).getTypeParameters());
|
||||
// scan for used types to generate imports
|
||||
if (context.useModules) {
|
||||
UsedTypesScanner scanner = new UsedTypesScanner();
|
||||
JCMethodDecl method = entry.getValue();
|
||||
if (!context.hasAnnotationType(method.sym, JSweetConfig.ANNOTATION_ERASED)) {
|
||||
if (context.hasAnnotationType(method.sym, JSweetConfig.ANNOTATION_REPLACE)) {
|
||||
// do not scan the method body
|
||||
scanner.scan(method.params);
|
||||
scanner.scan(method.restype);
|
||||
scanner.scan(method.thrown);
|
||||
scanner.scan(method.typarams);
|
||||
scanner.scan(method.recvparam);
|
||||
} else {
|
||||
scanner.scan(method);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!context.hasAnnotationType(entry.getValue().sym, JSweetConfig.ANNOTATION_ERASED)) {
|
||||
printIndent().print(
|
||||
"/* Default method injected from " + entry.getKey().sym.getQualifiedName() + " */")
|
||||
.println();
|
||||
}
|
||||
printIndent().print(entry.getValue()).println();
|
||||
getAdapter().typeVariablesToErase
|
||||
.removeAll(((ClassSymbol) s.getEnclosingElement()).getTypeParameters());
|
||||
injectedDefaultMethods.add(entry.getValue());
|
||||
injectedDefaultMethodMap.put(entry.getValue(), s);
|
||||
}
|
||||
}
|
||||
getScope().defaultMethodScope = false;
|
||||
}
|
||||
|
||||
if (getScope().enumScope) {
|
||||
@ -1700,7 +1677,7 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
String prefix = getClassName(classdecl.sym) + ".";
|
||||
|
||||
printIndent().print("static __static_initialize() { ");
|
||||
print("if(!" + prefix + "__static_initialized) { ");
|
||||
print("if (!" + prefix + "__static_initialized) { ");
|
||||
print(prefix + "__static_initialized = true; ");
|
||||
for (int i = 0; i < liCount; i++) {
|
||||
print(prefix + "__static_initializer_" + i + "(); ");
|
||||
@ -1713,7 +1690,57 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
|
||||
boolean hasUninitializedFields = false;
|
||||
|
||||
for (JCTree def : classdecl.defs) {
|
||||
List<JCTree> defs = new ArrayList<>();
|
||||
defs.addAll(injectedDefaultMethods);
|
||||
defs.addAll(classdecl.defs);
|
||||
if (context.options.isSortClassMembers()) {
|
||||
List<JCTree> memberDefs = defs.stream()
|
||||
.filter(t -> (t instanceof JCMethodDecl || t instanceof JCVariableDecl))
|
||||
.sorted((t1, t2) -> getAdapter().getClassMemberComparator().compare(
|
||||
ExtendedElementFactory.INSTANCE.create(t1), ExtendedElementFactory.INSTANCE.create(t2)))
|
||||
.collect(Collectors.toList());
|
||||
defs = new ArrayList<>();
|
||||
defs.addAll(memberDefs);
|
||||
for (JCTree def : classdecl.defs) {
|
||||
if (!defs.contains(def)) {
|
||||
defs.add(def);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (JCTree def : defs) {
|
||||
if (injectedDefaultMethods.contains(def)) {
|
||||
JCMethodDecl defaultMethod = (JCMethodDecl) def;
|
||||
MethodSymbol s = injectedDefaultMethodMap.get(defaultMethod);
|
||||
getScope().defaultMethodScope = true;
|
||||
getAdapter().typeVariablesToErase.addAll(((ClassSymbol) s.getEnclosingElement()).getTypeParameters());
|
||||
// scan for used types to generate imports
|
||||
if (context.useModules) {
|
||||
UsedTypesScanner scanner = new UsedTypesScanner();
|
||||
if (!context.hasAnnotationType(defaultMethod.sym, JSweetConfig.ANNOTATION_ERASED)) {
|
||||
if (context.hasAnnotationType(defaultMethod.sym, JSweetConfig.ANNOTATION_REPLACE)) {
|
||||
// do not scan the method body
|
||||
scanner.scan(defaultMethod.params);
|
||||
scanner.scan(defaultMethod.restype);
|
||||
scanner.scan(defaultMethod.thrown);
|
||||
scanner.scan(defaultMethod.typarams);
|
||||
scanner.scan(defaultMethod.recvparam);
|
||||
} else {
|
||||
scanner.scan(defaultMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!context.hasAnnotationType(defaultMethod.sym, JSweetConfig.ANNOTATION_ERASED)) {
|
||||
printIndent()
|
||||
.print("/* Default method injected from " + defaultMethod.sym.getEnclosingElement() + " */")
|
||||
.println();
|
||||
}
|
||||
printIndent().print(defaultMethod).println();
|
||||
getAdapter().typeVariablesToErase.removeAll(((ClassSymbol) s.getEnclosingElement()).getTypeParameters());
|
||||
getScope().defaultMethodScope = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (getScope().interfaceScope && ((def instanceof JCMethodDecl && ((JCMethodDecl) def).sym.isStatic())
|
||||
|| (def instanceof JCVariableDecl && ((JCVariableDecl) def).sym.isStatic()))) {
|
||||
// static interface members are printed in a namespace
|
||||
@ -2115,11 +2142,11 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
case JSweetConfig.NEW_FUNCTION_NAME:
|
||||
return "new";
|
||||
default:
|
||||
if (context.hasMethodNameMapping(methodDecl.sym)) {
|
||||
return context.getMethodNameMapping(methodDecl.sym);
|
||||
} else {
|
||||
return name;
|
||||
}
|
||||
if (context.hasMethodNameMapping(methodDecl.sym)) {
|
||||
return context.getMethodNameMapping(methodDecl.sym);
|
||||
} else {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2568,7 +2595,7 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
print(" else ");
|
||||
}
|
||||
wasPrinted = true;
|
||||
print("if(");
|
||||
print("if (");
|
||||
printMethodParamsTest(overload, method);
|
||||
print(") ");
|
||||
if (method.sym.isConstructor()
|
||||
@ -2615,7 +2642,9 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
}
|
||||
print(getOverloadMethodName(method.sym)).print("(");
|
||||
for (int j = 0; j < method.getParameters().size(); j++) {
|
||||
if (j == method.getParameters().size() - 1 && Util.hasVarargs(overload.coreMethod.sym)) {
|
||||
if (j == method.getParameters().size() - 1 && Util.hasVarargs(method.sym)) {
|
||||
print("...");
|
||||
} else if (j == method.getParameters().size() - 1 && Util.hasVarargs(overload.coreMethod.sym)) {
|
||||
print("<any>");
|
||||
}
|
||||
print(avoidJSKeyword(overload.coreMethod.getParameters().get(j).name.toString())).print(", ");
|
||||
@ -2810,12 +2839,25 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
print(";").println();
|
||||
} else if (var.init == null) {
|
||||
if (doesMemberNameRequireQuotes(name)) {
|
||||
printIndent().print("if(").print("this['").print(name).print("']").print("===undefined) ")
|
||||
.print("this['").print(name).print("'] = ").print(getAdapter().getVariableInitialValue(var.sym))
|
||||
.print(";").println();
|
||||
printIndent().print("if (").print("this['").print(name).print("']").print(" === undefined) { ");
|
||||
if (context.options.isNonEnumerableTransients() && var.sym.getModifiers().contains(Modifier.TRANSIENT)) {
|
||||
print("Object.defineProperty(this, " + getStringLiteralQuote() + name + getStringLiteralQuote()
|
||||
+ ", { value: ").print(getAdapter().getVariableInitialValue(var.sym))
|
||||
.print(", enumerable: false }); }").println();
|
||||
} else {
|
||||
print("this['").print(name).print("'] = ").print(getAdapter().getVariableInitialValue(var.sym))
|
||||
.print("; }").println();
|
||||
}
|
||||
} else {
|
||||
printIndent().print("if(").print("this.").print(name).print("===undefined) this.").print(name)
|
||||
.print(" = ").print(getAdapter().getVariableInitialValue(var.sym)).print(";").println();
|
||||
printIndent().print("if (").print("this.").print(name).print(" === undefined) { ");
|
||||
if (context.options.isNonEnumerableTransients() && var.sym.getModifiers().contains(Modifier.TRANSIENT)) {
|
||||
print("Object.defineProperty(this, " + getStringLiteralQuote() + name + getStringLiteralQuote()
|
||||
+ ", { value: ").print(getAdapter().getVariableInitialValue(var.sym))
|
||||
.print(", enumerable: false }); }").println();
|
||||
} else {
|
||||
print("this.").print(name).print(" = ").print(getAdapter().getVariableInitialValue(var.sym))
|
||||
.print("; }").println();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2887,7 +2929,6 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
}
|
||||
if (method.getBody() != null) {
|
||||
boolean skipFirst = false;
|
||||
boolean initialized = false;
|
||||
if (!method.getBody().stats.isEmpty() && method.getBody().stats.get(0).toString().startsWith("this(")) {
|
||||
skipFirst = true;
|
||||
JCMethodInvocation inv = (JCMethodInvocation) ((JCExpressionStatement) method.getBody().stats
|
||||
@ -2897,7 +2938,6 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
for (JCMethodDecl md : overload.methods) {
|
||||
if (md.sym.equals(ms)) {
|
||||
printIndent();
|
||||
initialized = true;
|
||||
printInlinedMethod(overload, md, inv.args);
|
||||
println();
|
||||
}
|
||||
@ -2914,21 +2954,17 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
enter(method.getBody());
|
||||
com.sun.tools.javac.util.List<JCStatement> stats = skipFirst ? method.getBody().stats.tail
|
||||
: method.getBody().stats;
|
||||
if (method.sym.isConstructor()) {
|
||||
getScope().hasDeclaredConstructor = true;
|
||||
}
|
||||
if (!stats.isEmpty() && stats.head.toString().startsWith("super(")) {
|
||||
printBlockStatement(stats.head);
|
||||
printFieldInitializations();
|
||||
if (!initialized) {
|
||||
printInstanceInitialization(getParent(JCClassDecl.class), method.sym);
|
||||
}
|
||||
printFieldInitializations(stats);
|
||||
if (!stats.tail.isEmpty()) {
|
||||
printIndent().print("((").print(") => {").startIndent().println();
|
||||
printBlockStatements(stats.tail);
|
||||
endIndent().printIndent().print("})(").print(");").println();
|
||||
}
|
||||
} else {
|
||||
if (!initialized) {
|
||||
printInstanceInitialization(getParent(JCClassDecl.class), method.sym);
|
||||
}
|
||||
printFieldInitializations(stats);
|
||||
if (!stats.isEmpty() || !method.sym.isConstructor()) {
|
||||
printIndent();
|
||||
}
|
||||
@ -2970,19 +3006,25 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
endIndent().printIndent().print("}");
|
||||
}
|
||||
|
||||
private void printFieldInitializations() {
|
||||
private void printFieldInitializations(List<JCStatement> potentialInitializationStatements) {
|
||||
JCClassDecl clazz = getParent(JCClassDecl.class);
|
||||
for (JCTree t : clazz.getMembers()) {
|
||||
if (t instanceof JCVariableDecl && !getScope().fieldsWithInitializers.contains(t)) {
|
||||
JCVariableDecl field = (JCVariableDecl) t;
|
||||
if (!field.sym.isStatic() && !context.hasAnnotationType(field.sym, JSweetConfig.ANNOTATION_ERASED)) {
|
||||
String name = getIdentifier(field.sym);
|
||||
if (!field.sym.isStatic() && !context.hasAnnotationType(field.sym, JSweetConfig.ANNOTATION_ERASED)) {
|
||||
String name = getIdentifier(field.sym);
|
||||
if (context.getFieldNameMapping(field.sym) != null) {
|
||||
name = context.getFieldNameMapping(field.sym);
|
||||
}
|
||||
printIndent().print("if(").print("this.").print(name).print("===undefined) ").print("this.")
|
||||
.print(name).print(" = ").print(getAdapter().getVariableInitialValue(field.sym)).print(";")
|
||||
.println();
|
||||
printIndent().print("if (").print("this.").print(name).print(" === undefined) { ");
|
||||
if (context.options.isNonEnumerableTransients() && field.sym.getModifiers().contains(Modifier.TRANSIENT)) {
|
||||
print("Object.defineProperty(this, " + getStringLiteralQuote() + name + getStringLiteralQuote()
|
||||
+ ", { value: ").print(getAdapter().getVariableInitialValue(field.sym))
|
||||
.print(", enumerable: false }); }").println();
|
||||
} else {
|
||||
print("this.").print(name).print(" = ").print(getAdapter().getVariableInitialValue(field.sym))
|
||||
.print("; }").println();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3114,9 +3156,17 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
int i = 0;
|
||||
for (; i < m.getParameters().size(); i++) {
|
||||
print("(");
|
||||
if (Class.class.getName().equals(context.types.erasure(m.getParameters().get(i).type).toString())
|
||||
&& m.getParameters().get(i).type.getTypeArguments().head != null
|
||||
&& m.getParameters().get(i).type.getTypeArguments().head.isInterface()) {
|
||||
print(avoidJSKeyword(overload.coreMethod.getParameters().get(i).name.toString())).print(" === ");
|
||||
print(getStringLiteralQuote()).print(m.getParameters().get(i).type.getTypeArguments().head.toString())
|
||||
.print(getStringLiteralQuote());
|
||||
print(" || ");
|
||||
}
|
||||
printInstanceOf(avoidJSKeyword(overload.coreMethod.getParameters().get(i).name.toString()), null,
|
||||
m.getParameters().get(i).type);
|
||||
checkType(m.getParameters().get(i).type.tsym);
|
||||
checkType(m.getParameters().get(i).type.tsym);
|
||||
print(" || ")
|
||||
.print(avoidJSKeyword(overload.coreMethod.getParameters().get(i).name.toString()) + " === null")
|
||||
.print(")");
|
||||
@ -3124,6 +3174,10 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
}
|
||||
for (; i < overload.coreMethod.getParameters().size(); i++) {
|
||||
print(avoidJSKeyword(overload.coreMethod.getParameters().get(i).name.toString())).print(" === undefined");
|
||||
if (i == overload.coreMethod.getParameters().size() - 1 && overload.coreMethod.sym.isVarArgs()) {
|
||||
print(" || ");
|
||||
print(avoidJSKeyword(overload.coreMethod.getParameters().get(i).name.toString())).print(".length === 0");
|
||||
}
|
||||
print(" && ");
|
||||
}
|
||||
removeLastChars(4);
|
||||
@ -3382,11 +3436,20 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
}
|
||||
}
|
||||
if (!(inArgListTail && (parent instanceof JCForLoop))) {
|
||||
if (isDefinitionScope) {
|
||||
print("var ");
|
||||
} else {
|
||||
print(VAR_DECL_KEYWORD + " ");
|
||||
}
|
||||
if (!getAdapter().substituteVariableDeclarationKeyword(varDecl.sym)) {
|
||||
if (isDefinitionScope) {
|
||||
print("var ");
|
||||
} else {
|
||||
if (!isLazyInitialized(varDecl.sym) && ((!globals && context.constAnalyzer != null
|
||||
&& !context.constAnalyzer.getModifiedVariables().contains(varDecl.sym))
|
||||
|| (globals && varDecl.sym.getModifiers().contains(Modifier.FINAL)
|
||||
&& varDecl.init != null))) {
|
||||
print("const ");
|
||||
} else {
|
||||
print(VAR_DECL_KEYWORD + " ");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ambient) {
|
||||
@ -3460,7 +3523,7 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
}
|
||||
}
|
||||
if (varDecl.init != null && !isDefinitionScope) {
|
||||
print("if(" + prefix).print(name).print(" == null) ").print(prefix).print(name).print(" = ");
|
||||
print("if (" + prefix).print(name).print(" == null) { ").print(prefix).print(name).print(" = ");
|
||||
/*
|
||||
* if (getScope().enumWrapperClassScope) { JCNewClass newClass = (JCNewClass)
|
||||
* varDecl.init; print("new "
|
||||
@ -3471,7 +3534,7 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
print(varDecl.init);
|
||||
}
|
||||
// }
|
||||
print("; ");
|
||||
print("; }");
|
||||
}
|
||||
print("return ").print(prefix).print(name).print("; }");
|
||||
if (!globals && context.bundleMode) {
|
||||
@ -4519,13 +4582,13 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
|
||||
println().endIndent().printIndent().print("}");
|
||||
if (!interfaces.isEmpty()) {
|
||||
print(", '" + INTERFACES_FIELD_NAME + "', { configurable: true, value: ");
|
||||
print(", 'constructor', { configurable: true, value: { " + INTERFACES_FIELD_NAME +": ");
|
||||
print("[");
|
||||
for (String i : interfaces) {
|
||||
print(getStringLiteralQuote()).print(i).print(getStringLiteralQuote() + ",");
|
||||
}
|
||||
removeLastChar();
|
||||
print("]");
|
||||
print("] }");
|
||||
print(" })");
|
||||
}
|
||||
} else {
|
||||
@ -4969,7 +5032,7 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
*/
|
||||
@Override
|
||||
public void visitIf(JCIf ifStatement) {
|
||||
print("if").print(ifStatement.cond).print(" ");
|
||||
print("if ").print(ifStatement.cond).print(" ");
|
||||
print(ifStatement.thenpart);
|
||||
if (!(ifStatement.thenpart instanceof JCBlock)) {
|
||||
if (!statementsWithNoSemis.contains(ifStatement.thenpart.getClass())) {
|
||||
@ -5242,7 +5305,7 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
}
|
||||
} else {
|
||||
print("<any> (function(dims) { " + VAR_DECL_KEYWORD
|
||||
+ " allocate = function(dims) { if(dims.length==0) { return "
|
||||
+ " allocate = function(dims) { if (dims.length === 0) { return "
|
||||
+ Util.getTypeInitialValue(newArray.elemtype.type) + "; } else { " + VAR_DECL_KEYWORD
|
||||
+ " array = []; for(" + VAR_DECL_KEYWORD
|
||||
+ " i = 0; i < dims[0]; i++) { array.push(allocate(dims.slice(1))); } return array; }}; return allocate(dims);})");
|
||||
@ -5335,10 +5398,13 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
@Override
|
||||
public void visitSwitch(JCSwitch switchStatement) {
|
||||
print("switch(");
|
||||
print(switchStatement.selector);
|
||||
if (context.types.isSameType(context.symtab.charType,
|
||||
context.types.unboxedTypeOrType(switchStatement.selector.type))) {
|
||||
print(".charCodeAt(0)");
|
||||
if (!getAdapter()
|
||||
.substituteSwitchStatementSelector(ExtendedElementFactory.INSTANCE.create(switchStatement.selector))) {
|
||||
print(switchStatement.selector);
|
||||
if (context.types.isSameType(context.symtab.charType,
|
||||
context.types.unboxedTypeOrType(switchStatement.selector.type))) {
|
||||
print(".charCodeAt(0)");
|
||||
}
|
||||
}
|
||||
print(") {").println();
|
||||
for (JCCase caseStatement : switchStatement.cases) {
|
||||
@ -5416,6 +5482,9 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
if (substituteAssignedExpression(cast.type, cast.expr)) {
|
||||
return;
|
||||
}
|
||||
if (getAdapter().substituteTypeCast((TypeCastElement)ExtendedElementFactory.INSTANCE.create(cast))) {
|
||||
return;
|
||||
}
|
||||
if (Util.isIntegral(cast.type)) {
|
||||
if (cast.type.getKind() == TypeKind.LONG) {
|
||||
print("(n => n<0?Math.ceil(n):Math.floor(n))(");
|
||||
@ -5801,7 +5870,7 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
if (context.isInterface(type.tsym)) {
|
||||
print(" != null && ");
|
||||
print("(");
|
||||
print(exprStr, expr);
|
||||
/*print(exprStr, expr);
|
||||
if (checkFirstArrayElement)
|
||||
print("[0]");
|
||||
print("[" + getStringLiteralQuote() + INTERFACES_FIELD_NAME + getStringLiteralQuote() + "]")
|
||||
@ -5809,9 +5878,10 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
print(exprStr, expr);
|
||||
if (checkFirstArrayElement)
|
||||
print("[0]");
|
||||
print("[" + getStringLiteralQuote() + INTERFACES_FIELD_NAME + getStringLiteralQuote()
|
||||
+ "].indexOf(\"").print(type.tsym.getQualifiedName().toString()).print("\") >= 0");
|
||||
print(" || ");
|
||||
print("[" + getStringLiteralQuote() + INTERFACES_FIELD_NAME
|
||||
+ getStringLiteralQuote() + "].indexOf(\"")
|
||||
.print(type.tsym.getQualifiedName().toString()).print("\") >= 0");
|
||||
print(" || ");*/
|
||||
print(exprStr, expr);
|
||||
if (checkFirstArrayElement)
|
||||
print("[0]");
|
||||
@ -5834,6 +5904,20 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
print(" === " + getStringLiteralQuote() + "string" + getStringLiteralQuote());
|
||||
}
|
||||
print(")");
|
||||
} else if (Class.class.getName().equals(type.tsym.getQualifiedName().toString())) {
|
||||
print(" != null && ");
|
||||
print("(");
|
||||
print(exprStr, expr);
|
||||
if (checkFirstArrayElement)
|
||||
print("[0]");
|
||||
print("[" + getStringLiteralQuote() + CLASS_NAME_IN_CONSTRUCTOR
|
||||
+ getStringLiteralQuote() + "]").print(" != null");
|
||||
print(" || ((t) => { try { new t; return true; } catch { return false; } })(");
|
||||
print(exprStr, expr);
|
||||
if (checkFirstArrayElement)
|
||||
print("[0]");
|
||||
print(")");
|
||||
print(")");
|
||||
} else {
|
||||
if (type.tsym instanceof TypeVariableSymbol
|
||||
|| Object.class.getName().equals(type.tsym.getQualifiedName().toString())) {
|
||||
@ -5860,7 +5944,7 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
print(exprStr, expr);
|
||||
if (checkFirstArrayElement)
|
||||
print("[0]");
|
||||
print(".length==0 || ");
|
||||
print(".length == 0 || ");
|
||||
print(exprStr, expr);
|
||||
print("[0] == null ||");
|
||||
if (t.elemtype instanceof ArrayType) {
|
||||
@ -5904,8 +5988,8 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
|
||||
public void visitAssert(JCAssert assertion) {
|
||||
if (!context.options.isIgnoreAssertions()) {
|
||||
String assertCode = assertion.toString().replace("\"", "'");
|
||||
print("if(!(").print(assertion.cond).print(
|
||||
")) throw new Error(\"Assertion error line " + getCurrentLine() + ": " + assertCode + "\");");
|
||||
print("if (!(").print(assertion.cond).print(
|
||||
")) { throw new Error(\"Assertion error line " + getCurrentLine() + ": " + assertCode + "\"); }");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,10 +5,12 @@ import java.io.File;
|
||||
public class EvalOptions {
|
||||
public final boolean useModules;
|
||||
public final File workingDir;
|
||||
public final boolean useJavaRuntime;
|
||||
|
||||
public EvalOptions(boolean useModules, File workingDir) {
|
||||
public EvalOptions(boolean useModules, File workingDir, boolean useJavaRuntime) {
|
||||
this.useModules = useModules;
|
||||
this.workingDir = workingDir;
|
||||
this.useJavaRuntime = useJavaRuntime;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -3,8 +3,10 @@ package org.jsweet.transpiler.eval;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
@ -52,6 +54,12 @@ public class JavaScriptEval extends RuntimeEval {
|
||||
|
||||
File tmpFile = new File(options.workingDir, "eval.tmp_" + System.currentTimeMillis() + ".js");
|
||||
FileUtils.deleteQuietly(tmpFile);
|
||||
if (options.useJavaRuntime) {
|
||||
List<File> newFiles = new ArrayList<>(jsFiles);
|
||||
newFiles.add(0, new File("src/test/resources/j4ts.js"));
|
||||
jsFiles = newFiles;
|
||||
}
|
||||
|
||||
Set<File> alreadyWrittenScripts = new HashSet<>();
|
||||
for (File jsFile : jsFiles) {
|
||||
if (!alreadyWrittenScripts.contains(jsFile)) {
|
||||
@ -61,7 +69,7 @@ public class JavaScriptEval extends RuntimeEval {
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("[no modules] eval file: " + tmpFile + " jsFiles=" + jsFiles);
|
||||
logger.info("[no modules] eval file: " + tmpFile + " jsFiles=" + jsFiles + ", useJavaRuntime=" + options.useJavaRuntime);
|
||||
|
||||
runProcess = runScript(trace, tmpFile);
|
||||
}
|
||||
|
||||
@ -72,6 +72,7 @@ import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.Modifier;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.type.PrimitiveType;
|
||||
import javax.lang.model.type.TypeKind;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
|
||||
@ -1249,14 +1250,14 @@ public class Java2TypeScriptAdapter extends PrinterAdapter {
|
||||
switch (targetMethodName) {
|
||||
case "getName":
|
||||
printMacroName(targetMethodName);
|
||||
getPrinter().print("(c => c[\"" + Java2TypeScriptTranslator.CLASS_NAME_IN_CONSTRUCTOR + "\"]?c[\""
|
||||
getPrinter().print("(c => typeof c === 'string'?c:c[\"" + Java2TypeScriptTranslator.CLASS_NAME_IN_CONSTRUCTOR + "\"]?c[\""
|
||||
+ Java2TypeScriptTranslator.CLASS_NAME_IN_CONSTRUCTOR + "\"]:c[\"name\"])(");
|
||||
printTarget(invocationElement.getTargetExpression());
|
||||
print(")");
|
||||
return true;
|
||||
case "getSimpleName":
|
||||
printMacroName(targetMethodName);
|
||||
print("(c => c[\"" + Java2TypeScriptTranslator.CLASS_NAME_IN_CONSTRUCTOR + "\"]?c[\""
|
||||
print("(c => typeof c === 'string'?(<any>c).substring((<any>c).lastIndexOf('.')+1):c[\"" + Java2TypeScriptTranslator.CLASS_NAME_IN_CONSTRUCTOR + "\"]?c[\""
|
||||
+ Java2TypeScriptTranslator.CLASS_NAME_IN_CONSTRUCTOR + "\"].substring(c[\""
|
||||
+ Java2TypeScriptTranslator.CLASS_NAME_IN_CONSTRUCTOR
|
||||
+ "\"].lastIndexOf('.')+1):c[\"name\"].substring(c[\"name\"].lastIndexOf('.')+1))(");
|
||||
@ -1285,15 +1286,25 @@ public class Java2TypeScriptAdapter extends PrinterAdapter {
|
||||
} else {
|
||||
switch (targetMethodName) {
|
||||
case "equals":
|
||||
if (types().isSameType(invocationElement.getTargetExpression().getType(),
|
||||
util().getType(String.class))
|
||||
|| util().isNumber(invocationElement.getTargetExpression().getType())) {
|
||||
if(isInlinedExpression(invocationElement)) {
|
||||
TypeMirror t1 = util().toPrimitiveTypeOrType(invocationElement.getTargetExpression().getType());
|
||||
TypeMirror t2 = util().toPrimitiveTypeOrType(invocationElement.getArgument(0).getType());
|
||||
if (types().isSameType(t1, t2) && util().isCoreType(t1)) {
|
||||
if (isInlinedExpression(invocationElement)) {
|
||||
print("(");
|
||||
}
|
||||
print(invocationElement.getTargetExpression()).print(" === ")
|
||||
.print(invocationElement.getArgument(0));
|
||||
if(isInlinedExpression(invocationElement)) {
|
||||
print(invocationElement.getTargetExpression()).print(" === ");
|
||||
ExtendedElement arg = invocationElement.getArgument(0);
|
||||
boolean inlinable = arg instanceof VariableAccessElement
|
||||
|| (arg instanceof MethodInvocationElement
|
||||
&& !"equals".equals(((MethodInvocationElement) arg).getMethodName()));
|
||||
if (!inlinable) {
|
||||
print("(");
|
||||
}
|
||||
print(invocationElement.getArgument(0));
|
||||
if (!inlinable) {
|
||||
print(")");
|
||||
}
|
||||
if (isInlinedExpression(invocationElement)) {
|
||||
print(")");
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
package org.jsweet.transpiler.extension;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -49,6 +50,7 @@ import org.jsweet.transpiler.model.AssignmentElement;
|
||||
import org.jsweet.transpiler.model.AssignmentWithOperatorElement;
|
||||
import org.jsweet.transpiler.model.BinaryOperatorElement;
|
||||
import org.jsweet.transpiler.model.CaseElement;
|
||||
import org.jsweet.transpiler.model.TypeCastElement;
|
||||
import org.jsweet.transpiler.model.CompilationUnitElement;
|
||||
import org.jsweet.transpiler.model.ExtendedElement;
|
||||
import org.jsweet.transpiler.model.ForeachLoopElement;
|
||||
@ -1053,6 +1055,13 @@ public class PrinterAdapter {
|
||||
return parentAdapter == null ? false : parentAdapter.substituteInstanceof(exprStr, expr, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Substitutes if necessary a type cast expression.
|
||||
*/
|
||||
public boolean substituteTypeCast(TypeCastElement castExpression) {
|
||||
return parentAdapter == null ? false : parentAdapter.substituteTypeCast(castExpression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Substitutes if necessary the pattern of a case statement.
|
||||
*/
|
||||
@ -1060,6 +1069,13 @@ public class PrinterAdapter {
|
||||
return parentAdapter == null ? false : parentAdapter.substituteCaseStatementPattern(caseStatement, pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Substitutes if necessary the selector expression of a switch statement.
|
||||
*/
|
||||
public boolean substituteSwitchStatementSelector(ExtendedElement selector) {
|
||||
return parentAdapter == null ? false : parentAdapter.substituteSwitchStatementSelector(selector);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called after a type was printed.
|
||||
*/
|
||||
@ -1204,4 +1220,36 @@ public class PrinterAdapter {
|
||||
return printer.isInlinedExpression(((ExtendedElementSupport<?>) element).getTree());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a comparator that will control the order of class members for output
|
||||
* (default will keep order of appearance in the source code).
|
||||
*/
|
||||
public Comparator<ExtendedElement> getClassMemberComparator() {
|
||||
if (parentAdapter == null) {
|
||||
return new Comparator<ExtendedElement>() {
|
||||
@Override
|
||||
public int compare(ExtendedElement e1, ExtendedElement e2) {
|
||||
return e1.getStartSourcePosition() - e2.getStartSourcePosition();
|
||||
}
|
||||
};
|
||||
} else {
|
||||
return parentAdapter.getClassMemberComparator();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Optionally substitutes the default variable declaration keyword
|
||||
* (<code>var</code>, <code>let</code>, <code>const</code>) for the given
|
||||
* variable. By default, regular variables are declared with the
|
||||
* <code>let</code> keyword, except for unmodified variables, which are declared
|
||||
* with the <code>const</code> keyword.
|
||||
*
|
||||
* @param variable the target variable
|
||||
* @return true if the default keyword has been substituted, false otherwise
|
||||
* (default is false)
|
||||
*/
|
||||
public boolean substituteVariableDeclarationKeyword(VariableElement variable) {
|
||||
return parentAdapter == null ? false : parentAdapter.substituteVariableDeclarationKeyword(variable);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
package org.jsweet.transpiler.model;
|
||||
|
||||
public interface ExecutableElement extends ExtendedElement, javax.lang.model.element.ExecutableElement {
|
||||
|
||||
javax.lang.model.element.ExecutableElement getStandardElement();
|
||||
|
||||
}
|
||||
@ -69,4 +69,9 @@ public interface ExtendedElement {
|
||||
*/
|
||||
boolean isStringLiteral();
|
||||
|
||||
/**
|
||||
* Gets the start position of the element in the source code.
|
||||
*/
|
||||
int getStartSourcePosition();
|
||||
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@ import org.jsweet.transpiler.model.support.AssignmentElementSupport;
|
||||
import org.jsweet.transpiler.model.support.BinaryOperatorElementSupport;
|
||||
import org.jsweet.transpiler.model.support.CaseElementSupport;
|
||||
import org.jsweet.transpiler.model.support.CompilationUnitElementSupport;
|
||||
import org.jsweet.transpiler.model.support.ExecutableElementSupport;
|
||||
import org.jsweet.transpiler.model.support.ExtendedElementSupport;
|
||||
import org.jsweet.transpiler.model.support.ForeachLoopElementSupport;
|
||||
import org.jsweet.transpiler.model.support.IdentifierElementSupport;
|
||||
@ -33,8 +34,10 @@ import org.jsweet.transpiler.model.support.LiteralElementSupport;
|
||||
import org.jsweet.transpiler.model.support.MethodInvocationElementSupport;
|
||||
import org.jsweet.transpiler.model.support.NewArrayElementSupport;
|
||||
import org.jsweet.transpiler.model.support.NewClassElementSupport;
|
||||
import org.jsweet.transpiler.model.support.TypeCastElementSupport;
|
||||
import org.jsweet.transpiler.model.support.UnaryOperatorElementSupport;
|
||||
import org.jsweet.transpiler.model.support.VariableAccessElementSupport;
|
||||
import org.jsweet.transpiler.model.support.VariableElementSupport;
|
||||
|
||||
import com.sun.tools.javac.tree.JCTree;
|
||||
import com.sun.tools.javac.tree.JCTree.JCArrayAccess;
|
||||
@ -47,10 +50,13 @@ import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
|
||||
import com.sun.tools.javac.tree.JCTree.JCIdent;
|
||||
import com.sun.tools.javac.tree.JCTree.JCImport;
|
||||
import com.sun.tools.javac.tree.JCTree.JCLiteral;
|
||||
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
|
||||
import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
|
||||
import com.sun.tools.javac.tree.JCTree.JCNewArray;
|
||||
import com.sun.tools.javac.tree.JCTree.JCNewClass;
|
||||
import com.sun.tools.javac.tree.JCTree.JCTypeCast;
|
||||
import com.sun.tools.javac.tree.JCTree.JCUnary;
|
||||
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
|
||||
|
||||
/**
|
||||
* A factory to create extended elements. It defines an overloaded create method
|
||||
@ -91,6 +97,10 @@ public class ExtendedElementFactory {
|
||||
return null;
|
||||
}
|
||||
switch (tree.getTag()) {
|
||||
case METHODDEF:
|
||||
return new ExecutableElementSupport((JCMethodDecl) tree);
|
||||
case VARDEF:
|
||||
return new VariableElementSupport((JCVariableDecl) tree);
|
||||
case APPLY:
|
||||
return new MethodInvocationElementSupport((JCMethodInvocation) tree);
|
||||
case SELECT:
|
||||
@ -147,6 +157,8 @@ public class ExtendedElementFactory {
|
||||
case POSTDEC:
|
||||
case POSTINC:
|
||||
return new UnaryOperatorElementSupport((JCUnary) tree);
|
||||
case TYPECAST:
|
||||
return new TypeCastElementSupport((JCTypeCast) tree);
|
||||
default:
|
||||
return new ExtendedElementSupport<>(tree);
|
||||
}
|
||||
|
||||
@ -42,5 +42,16 @@ public interface ForeachLoopElement extends ExtendedElement {
|
||||
* The body of the foreach loop.
|
||||
*/
|
||||
ExtendedElement getBody();
|
||||
|
||||
/**
|
||||
* Returns true if the loop contains a control flow statement
|
||||
* (<code>break</code>, <code>continue</code>, <code>return</code>).
|
||||
*/
|
||||
boolean hasControlFlowStatement();
|
||||
|
||||
/**
|
||||
* Returns true if the iteration variable is modified within the loop body.
|
||||
*/
|
||||
boolean isIterationVariableModified();
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.model;
|
||||
|
||||
/**
|
||||
* An AST node for a Java cast expression.
|
||||
*
|
||||
* @author Renaud Pawlak
|
||||
*/
|
||||
public interface TypeCastElement extends ExtendedElement {
|
||||
|
||||
/**
|
||||
* Gets the target type expression.
|
||||
*/
|
||||
public ExtendedElement getTargetTypeExpression();
|
||||
|
||||
/**
|
||||
* Gets the expression being cast.
|
||||
*/
|
||||
public ExtendedElement getExpression();
|
||||
|
||||
}
|
||||
@ -56,6 +56,11 @@ public interface Util {
|
||||
*/
|
||||
boolean isNumber(TypeMirror type);
|
||||
|
||||
/**
|
||||
* Tells if the given type is a boolean.
|
||||
*/
|
||||
boolean isBoolean(TypeMirror type);
|
||||
|
||||
/**
|
||||
* Tells if the given element is deprecated.
|
||||
*/
|
||||
@ -117,4 +122,21 @@ public interface Util {
|
||||
*/
|
||||
String getTypeInitialValue(TypeMirror type);
|
||||
|
||||
/**
|
||||
* Gets all the members of the given type, including members within the super
|
||||
* classes.
|
||||
*
|
||||
* @param typeElement the typeElement
|
||||
* @return a list of all the members
|
||||
*/
|
||||
List<Element> getAllMembers(TypeElement typeElement);
|
||||
|
||||
/**
|
||||
* Gets the type as a primitive type (by unboxing it) when possible.
|
||||
*
|
||||
* @param type the origin type
|
||||
* @return the origin type or the corresponding primitive type if possible
|
||||
*/
|
||||
TypeMirror toPrimitiveTypeOrType(TypeMirror type);
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
package org.jsweet.transpiler.model;
|
||||
|
||||
public interface VariableElement extends ExtendedElement, javax.lang.model.element.VariableElement {
|
||||
|
||||
javax.lang.model.element.VariableElement getStandardElement();
|
||||
|
||||
}
|
||||
@ -0,0 +1,123 @@
|
||||
package org.jsweet.transpiler.model.support;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.lang.model.element.AnnotationMirror;
|
||||
import javax.lang.model.element.AnnotationValue;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.ElementVisitor;
|
||||
import javax.lang.model.element.Modifier;
|
||||
import javax.lang.model.element.Name;
|
||||
import javax.lang.model.element.TypeParameterElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
|
||||
import org.jsweet.transpiler.model.ExecutableElement;
|
||||
|
||||
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
|
||||
|
||||
public class ExecutableElementSupport extends ExtendedElementSupport<JCMethodDecl> implements ExecutableElement {
|
||||
|
||||
public ExecutableElementSupport(JCMethodDecl tree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
@Override
|
||||
public javax.lang.model.element.ExecutableElement getStandardElement() {
|
||||
return tree.sym;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, P> R accept(ElementVisitor<R, P> v, P p) {
|
||||
return tree.sym.accept(v, p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeMirror asType() {
|
||||
return tree.sym.asType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
|
||||
return tree.sym.getAnnotation(annotationType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends AnnotationMirror> getAnnotationMirrors() {
|
||||
return tree.sym.getAnnotationMirrors();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) {
|
||||
return tree.sym.getAnnotationsByType(annotationType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationValue getDefaultValue() {
|
||||
return tree.sym.getDefaultValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Element> getEnclosedElements() {
|
||||
return tree.sym.getEnclosedElements();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Element getEnclosingElement() {
|
||||
return tree.sym.getEnclosingElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementKind getKind() {
|
||||
return tree.sym.getKind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Modifier> getModifiers() {
|
||||
return tree.sym.getModifiers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends VariableElement> getParameters() {
|
||||
return tree.sym.getParameters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeMirror getReceiverType() {
|
||||
return tree.sym.getReceiverType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeMirror getReturnType() {
|
||||
return tree.sym.getReturnType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Name getSimpleName() {
|
||||
return tree.sym.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends TypeMirror> getThrownTypes() {
|
||||
return tree.sym.getThrownTypes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends TypeParameterElement> getTypeParameters() {
|
||||
return tree.sym.getTypeParameters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVarArgs() {
|
||||
return tree.sym.isVarArgs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefault() {
|
||||
return tree.sym.isDefault();
|
||||
}
|
||||
|
||||
}
|
||||
@ -92,4 +92,10 @@ public class ExtendedElementSupport<T extends JCTree> implements ExtendedElement
|
||||
public boolean isStringLiteral() {
|
||||
return getTree().getKind() == Kind.STRING_LITERAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStartSourcePosition() {
|
||||
return getTree().getStartPosition();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -20,11 +20,19 @@ package org.jsweet.transpiler.model.support;
|
||||
|
||||
import javax.lang.model.element.VariableElement;
|
||||
|
||||
import org.jsweet.transpiler.ConstAnalyzer;
|
||||
import org.jsweet.transpiler.model.ExtendedElement;
|
||||
import org.jsweet.transpiler.model.ExtendedElementFactory;
|
||||
import org.jsweet.transpiler.model.ForeachLoopElement;
|
||||
|
||||
import com.sun.tools.javac.tree.JCTree.JCBreak;
|
||||
import com.sun.tools.javac.tree.JCTree.JCContinue;
|
||||
import com.sun.tools.javac.tree.JCTree.JCDoWhileLoop;
|
||||
import com.sun.tools.javac.tree.JCTree.JCEnhancedForLoop;
|
||||
import com.sun.tools.javac.tree.JCTree.JCForLoop;
|
||||
import com.sun.tools.javac.tree.JCTree.JCReturn;
|
||||
import com.sun.tools.javac.tree.JCTree.JCWhileLoop;
|
||||
import com.sun.tools.javac.tree.TreeScanner;
|
||||
|
||||
/**
|
||||
* See {@link ForeachLoopElement}.
|
||||
@ -52,4 +60,47 @@ public class ForeachLoopElementSupport extends ExtendedElementSupport<JCEnhanced
|
||||
return ExtendedElementFactory.INSTANCE.create(getTree().expr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasControlFlowStatement() {
|
||||
boolean[] hasControlFlowStatement = { false };
|
||||
new TreeScanner() {
|
||||
@Override
|
||||
public void visitBreak(JCBreak tree) {
|
||||
hasControlFlowStatement[0] = true;
|
||||
}
|
||||
@Override
|
||||
public void visitContinue(JCContinue tree) {
|
||||
hasControlFlowStatement[0] = true;
|
||||
}
|
||||
@Override
|
||||
public void visitReturn(JCReturn tree) {
|
||||
hasControlFlowStatement[0] = true;
|
||||
}
|
||||
@Override
|
||||
public void visitForeachLoop(JCEnhancedForLoop tree) {
|
||||
// do not scan inner loops
|
||||
}
|
||||
@Override
|
||||
public void visitDoLoop(JCDoWhileLoop tree) {
|
||||
// do not scan inner loops
|
||||
}
|
||||
@Override
|
||||
public void visitWhileLoop(JCWhileLoop tree) {
|
||||
// do not scan inner loops
|
||||
}
|
||||
@Override
|
||||
public void visitForLoop(JCForLoop tree) {
|
||||
// do not scan inner loops
|
||||
}
|
||||
}.scan(getTree().body);
|
||||
return hasControlFlowStatement[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIterationVariableModified() {
|
||||
ConstAnalyzer a = new ConstAnalyzer();
|
||||
a.scan(getTree().body);
|
||||
return a.getModifiedVariables().contains(getIterationVariable());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.model.support;
|
||||
|
||||
import org.jsweet.transpiler.model.TypeCastElement;
|
||||
import org.jsweet.transpiler.model.ExtendedElement;
|
||||
import org.jsweet.transpiler.model.ExtendedElementFactory;
|
||||
|
||||
import com.sun.tools.javac.tree.JCTree.JCTypeCast;
|
||||
|
||||
/**
|
||||
* See {@link TypeCastElement}.
|
||||
*
|
||||
* @author Renaud Pawlak
|
||||
*/
|
||||
public class TypeCastElementSupport extends ExtendedElementSupport<JCTypeCast> implements TypeCastElement {
|
||||
|
||||
public TypeCastElementSupport(JCTypeCast tree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtendedElement getTargetTypeExpression() {
|
||||
return (ExtendedElement) ExtendedElementFactory.INSTANCE.create(getTree().getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtendedElement getExpression() {
|
||||
return ExtendedElementFactory.INSTANCE.create(getTree().getExpression());
|
||||
}
|
||||
|
||||
}
|
||||
@ -18,6 +18,8 @@
|
||||
*/
|
||||
package org.jsweet.transpiler.model.support;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
@ -80,6 +82,8 @@ public class UtilSupport implements Util {
|
||||
@Override
|
||||
public TypeMirror getType(Class<?> clazz) {
|
||||
switch (clazz.getName()) {
|
||||
case "java.lang.Object":
|
||||
return context.symtab.objectType;
|
||||
case "java.lang.annotation.Annotation":
|
||||
return context.symtab.annotationType;
|
||||
case "java.lang.AssertionError":
|
||||
@ -153,6 +157,11 @@ public class UtilSupport implements Util {
|
||||
return org.jsweet.transpiler.util.Util.isNumber(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBoolean(TypeMirror type) {
|
||||
return org.jsweet.transpiler.util.Util.isBoolean(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeprecated(Element element) {
|
||||
return org.jsweet.transpiler.util.Util.isDeprecated(element);
|
||||
@ -207,4 +216,32 @@ public class UtilSupport implements Util {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Element> getAllMembers(TypeElement typeElement) {
|
||||
if(typeElement == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<Element> elements = new ArrayList<Element>();
|
||||
for(Element e : typeElement.getEnclosedElements()) {
|
||||
elements.add(e);
|
||||
}
|
||||
elements.addAll(getAllMembers(typeElement.getSuperclass()));
|
||||
return elements;
|
||||
}
|
||||
|
||||
private List<Element> getAllMembers(TypeMirror type) {
|
||||
if(type == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return getAllMembers((TypeElement)context.modelTypes.asElement(type));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeMirror toPrimitiveTypeOrType(TypeMirror type) {
|
||||
try {
|
||||
return context.types.unboxedTypeOrType((Type)type);
|
||||
} catch (Exception e) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,85 @@
|
||||
package org.jsweet.transpiler.model.support;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.lang.model.element.AnnotationMirror;
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ElementKind;
|
||||
import javax.lang.model.element.ElementVisitor;
|
||||
import javax.lang.model.element.Modifier;
|
||||
import javax.lang.model.element.Name;
|
||||
import javax.lang.model.type.TypeMirror;
|
||||
|
||||
import org.jsweet.transpiler.model.VariableElement;
|
||||
|
||||
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
|
||||
|
||||
public class VariableElementSupport extends ExtendedElementSupport<JCVariableDecl> implements VariableElement {
|
||||
|
||||
public VariableElementSupport(JCVariableDecl tree) {
|
||||
super(tree);
|
||||
}
|
||||
|
||||
@Override
|
||||
public javax.lang.model.element.VariableElement getStandardElement() {
|
||||
return tree.sym;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, P> R accept(ElementVisitor<R, P> v, P p) {
|
||||
return tree.sym.accept(v, p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeMirror asType() {
|
||||
return tree.sym.asType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
|
||||
return tree.sym.getAnnotation(annotationType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends AnnotationMirror> getAnnotationMirrors() {
|
||||
return tree.sym.getAnnotationMirrors();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) {
|
||||
return tree.sym.getAnnotationsByType(annotationType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<? extends Element> getEnclosedElements() {
|
||||
return tree.sym.getEnclosedElements();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Element getEnclosingElement() {
|
||||
return tree.sym.getEnclosingElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementKind getKind() {
|
||||
return tree.sym.getKind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Modifier> getModifiers() {
|
||||
return tree.sym.getModifiers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Name getSimpleName() {
|
||||
return tree.sym.getSimpleName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getConstantValue() {
|
||||
return tree.sym.getConstantValue();
|
||||
}
|
||||
|
||||
}
|
||||
@ -60,7 +60,7 @@ public abstract class AbstractTreeScanner extends TreeScanner {
|
||||
|
||||
private TranspilationHandler logHandler;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Report a JSweet problem on the given program element (tree).
|
||||
*
|
||||
* @param tree
|
||||
@ -468,4 +468,11 @@ public abstract class AbstractTreeScanner extends TreeScanner {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the transpilation handler for this scanner.
|
||||
*/
|
||||
public TranspilationHandler getLogHandler() {
|
||||
return logHandler;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1059,6 +1059,21 @@ public class Util {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true is the type is a boolean.
|
||||
*/
|
||||
public static boolean isBoolean(TypeMirror type) {
|
||||
if (type == null) {
|
||||
return false;
|
||||
}
|
||||
switch (type.getKind()) {
|
||||
case BOOLEAN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true is the type is a core.
|
||||
*/
|
||||
|
||||
@ -78,14 +78,21 @@ public class ApiTests extends AbstractTest {
|
||||
|
||||
@Test
|
||||
public void testJ4TSInvocations() {
|
||||
transpile(ModuleKind.none, logHandler -> {
|
||||
// with J4TS
|
||||
transpilerTest().getTranspiler().setUsingJavaRuntime(true);
|
||||
eval(ModuleKind.none, (logHandler, result) -> {
|
||||
logHandler.assertNoProblems();
|
||||
}, getSourceFile(J4TSInvocations.class));
|
||||
// without J4TS
|
||||
transpilerTest().getTranspiler().setUsingJavaRuntime(false);
|
||||
eval(ModuleKind.none, (logHandler, result) -> {
|
||||
logHandler.assertNoProblems();
|
||||
}, getSourceFile(J4TSInvocations.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJdkInvocations() {
|
||||
eval((logHandler, result) -> {
|
||||
eval(ModuleKind.none, (logHandler, result) -> {
|
||||
Assert.assertEquals("There should be no errors", 0, logHandler.reportedProblems.size());
|
||||
assertEquals("test", result.<String>get("s1"));
|
||||
assertEquals("m1", result.<String>get("s2"));
|
||||
@ -273,6 +280,7 @@ public class ApiTests extends AbstractTest {
|
||||
public void testDates() {
|
||||
eval(ModuleKind.none, (logHandler, r) -> {
|
||||
logHandler.assertNoProblems();
|
||||
System.out.println("result = " + r.get("localeString"));
|
||||
assertTrue(asList(
|
||||
"1/1/2020, 1:00:00 AM",
|
||||
"2020-1-1 1:00:00 AM").contains(
|
||||
|
||||
@ -2,10 +2,12 @@ package org.jsweet.test.transpiler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Comparator;
|
||||
import java.util.EventObject;
|
||||
|
||||
import javax.lang.model.element.Element;
|
||||
import javax.lang.model.element.ExecutableElement;
|
||||
import javax.lang.model.element.Modifier;
|
||||
import javax.lang.model.element.TypeElement;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
import javax.lang.model.type.TypeKind;
|
||||
@ -29,6 +31,7 @@ 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.model.ExtendedElement;
|
||||
import org.jsweet.transpiler.model.ImportElement;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
@ -41,6 +44,7 @@ import source.extension.HelloWorldDto;
|
||||
import source.extension.HelloWorldService;
|
||||
import source.extension.IAddNumber;
|
||||
import source.extension.Maps;
|
||||
import source.extension.ToBeSorted;
|
||||
import source.extension.UseOfGlobalVariable;
|
||||
|
||||
class TestFactory extends JSweetFactory {
|
||||
@ -106,6 +110,37 @@ class HelloWorldAdapter extends PrinterAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
class SortAdapter extends PrinterAdapter {
|
||||
|
||||
public SortAdapter(PrinterAdapter parentAdapter) {
|
||||
super(parentAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comparator<ExtendedElement> getClassMemberComparator() {
|
||||
|
||||
Comparator<ExtendedElement> defaultComparator = super.getClassMemberComparator();
|
||||
|
||||
return new Comparator<ExtendedElement>() {
|
||||
@Override
|
||||
public int compare(ExtendedElement e1, ExtendedElement e2) {
|
||||
if(e1 instanceof org.jsweet.transpiler.model.ExecutableElement &&
|
||||
e2 instanceof org.jsweet.transpiler.model.ExecutableElement) {
|
||||
ExecutableElement se1 = ((org.jsweet.transpiler.model.ExecutableElement)e1).getStandardElement();
|
||||
ExecutableElement se2 = ((org.jsweet.transpiler.model.ExecutableElement)e2).getStandardElement();
|
||||
if (se1.getModifiers().contains(Modifier.STATIC) && !se2.getModifiers().contains(Modifier.STATIC)) {
|
||||
return -1;
|
||||
} else if (se2.getModifiers().contains(Modifier.STATIC) && !se1.getModifiers().contains(Modifier.STATIC)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return defaultComparator.compare(e1, e2);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class JaxRSStubAdapter extends PrinterAdapter {
|
||||
|
||||
public JaxRSStubAdapter(PrinterAdapter parent) {
|
||||
@ -245,6 +280,31 @@ public class ExtensionTests extends AbstractTest {
|
||||
Assert.assertFalse(generatedCode.contains("date : Date"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSortAdapter() throws IOException {
|
||||
TranspilerTestRunner transpilerTest = new TranspilerTestRunner(getCurrentTestOutDir(), new JSweetFactory());
|
||||
SourceFile f = getSourceFile(ToBeSorted.class);
|
||||
transpilerTest.transpile(logHandler -> {
|
||||
logHandler.assertNoProblems();
|
||||
}, f);
|
||||
String generatedCode = FileUtils.readFileToString(f.getTsFile());
|
||||
Assert.assertTrue(generatedCode.indexOf("myStaticMethod") > generatedCode.indexOf("myMethod"));
|
||||
transpilerTest = new TranspilerTestRunner(getCurrentTestOutDir(), new JSweetFactory() {
|
||||
|
||||
@Override
|
||||
public PrinterAdapter createAdapter(JSweetContext context) {
|
||||
return new SortAdapter(super.createAdapter(context));
|
||||
}
|
||||
});
|
||||
transpilerTest.getTranspiler().setSortClassMembers(true);
|
||||
f = getSourceFile(ToBeSorted.class);
|
||||
transpilerTest.transpile(logHandler -> {
|
||||
logHandler.assertNoProblems();
|
||||
}, f);
|
||||
generatedCode = FileUtils.readFileToString(f.getTsFile());
|
||||
Assert.assertTrue(generatedCode.indexOf("myStaticMethod") < generatedCode.indexOf("myMethod"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisallowGlobalVariablesAdapter() {
|
||||
TranspilerTestRunner transpilerTest = new TranspilerTestRunner(getCurrentTestOutDir(), new JSweetFactory() {
|
||||
|
||||
@ -62,6 +62,8 @@ import source.overload.ConstructorOverloadWithFieldInitializer;
|
||||
import source.overload.InterfaceInheritance;
|
||||
import source.overload.LocalVariablesNameCollision;
|
||||
import source.overload.NonPublicRootMethod;
|
||||
import source.overload.OverLoadClassAndObject;
|
||||
import source.overload.OverLoadVarags;
|
||||
import source.overload.OverLoadWithClassParam;
|
||||
import source.overload.Overload;
|
||||
import source.overload.OverloadInInnerClass;
|
||||
@ -262,6 +264,31 @@ public class OverloadTests extends AbstractTest {
|
||||
}, getSourceFile(ConstructorOverloadWithFieldInitializer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverloadClassAndObjectWithJ4TS() {
|
||||
transpilerTest().getTranspiler().setUsingJavaRuntime(true);
|
||||
eval(ModuleKind.none, (logHandler, r) -> {
|
||||
logHandler.assertNoProblems();
|
||||
}, getSourceFile(OverLoadClassAndObject.class));
|
||||
transpilerTest().getTranspiler().setUsingJavaRuntime(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverloadClassAndObject() {
|
||||
eval(ModuleKind.none, (logHandler, r) -> {
|
||||
logHandler.assertNoProblems();
|
||||
}, getSourceFile(OverLoadClassAndObject.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverloadVarargs() {
|
||||
transpilerTest().getTranspiler().setUsingJavaRuntime(true);
|
||||
eval(ModuleKind.none, (logHandler, r) -> {
|
||||
logHandler.assertNoProblems();
|
||||
}, getSourceFile(OverLoadVarags.class));
|
||||
transpilerTest().getTranspiler().setUsingJavaRuntime(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructorOverloadWithArray() {
|
||||
eval(ModuleKind.none, (logHandler, r) -> {
|
||||
|
||||
@ -68,6 +68,7 @@ import source.structural.PrivateMethodNameClashes;
|
||||
import source.structural.ReplaceAnnotation;
|
||||
import source.structural.StaticMembersInInterfaces;
|
||||
import source.structural.SubAbstract;
|
||||
import source.structural.Transients;
|
||||
import source.structural.TwoClassesInSameFile;
|
||||
import source.structural.WrappedParametersOwner;
|
||||
import source.structural.WrongConstructsInInterfaces;
|
||||
@ -544,6 +545,20 @@ public class StructuralTests extends AbstractTest {
|
||||
}, getSourceFile(FieldInitialization.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransients() {
|
||||
eval(ModuleKind.none, (logHandler, r) -> {
|
||||
logHandler.assertNoProblems();
|
||||
assertEquals("a,b,c,d", r.get("keys"));
|
||||
}, getSourceFile(Transients.class));
|
||||
this.transpilerTest().getTranspiler().setNonEnumerableTransients(true);
|
||||
eval(ModuleKind.none, (logHandler, r) -> {
|
||||
logHandler.assertNoProblems();
|
||||
assertEquals("a,c", r.get("keys"));
|
||||
}, getSourceFile(Transients.class));
|
||||
this.transpilerTest().getTranspiler().setNonEnumerableTransients(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInheritanceWithGenerics() {
|
||||
transpile(logHandler -> {
|
||||
|
||||
@ -22,16 +22,22 @@ import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.jsweet.test.transpiler.util.TranspilerTestRunner;
|
||||
import org.jsweet.transpiler.JSweetContext;
|
||||
import org.jsweet.transpiler.JSweetFactory;
|
||||
import org.jsweet.transpiler.JSweetProblem;
|
||||
import org.jsweet.transpiler.ModuleKind;
|
||||
import org.jsweet.transpiler.SourceFile;
|
||||
import org.jsweet.transpiler.extension.PrinterAdapter;
|
||||
import org.jsweet.transpiler.util.EvaluationResult;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import source.extension.ToBeSorted;
|
||||
import source.syntax.AnnotationQualifiedNames;
|
||||
import source.syntax.Casts;
|
||||
import source.syntax.DocComments;
|
||||
@ -146,6 +152,25 @@ public class SyntaxTests extends AbstractTest {
|
||||
}, getSourceFile(FinalVariables.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstVariables() throws IOException {
|
||||
SourceFile f1 = getSourceFile(FinalVariables.class);
|
||||
SourceFile f2 = getSourceFile(GlobalsInvocation.class);
|
||||
transpilerTest().transpile(logHandler -> {
|
||||
logHandler.assertNoProblems();
|
||||
}, f1, f2);
|
||||
String generatedCode = FileUtils.readFileToString(f1.getTsFile());
|
||||
Assert.assertTrue(generatedCode.contains("const explicitFinalString"));
|
||||
Assert.assertTrue(generatedCode.contains("let explicitFinalStringWithDeferredAssignment"));
|
||||
Assert.assertFalse(generatedCode.contains("const explicitFinalStringWithDeferredAssignment"));
|
||||
Assert.assertTrue(generatedCode.contains("const implicitFinalString"));
|
||||
Assert.assertTrue(generatedCode.contains("let notFinalString"));
|
||||
generatedCode = FileUtils.readFileToString(f2.getTsFile());
|
||||
Assert.assertTrue(generatedCode.contains("const explicitFinalGlobal"));
|
||||
Assert.assertTrue(generatedCode.contains("let implicitFinalGlobal"));
|
||||
Assert.assertTrue(generatedCode.contains("let notFinalGlobal"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFinalVariablesRuntime() {
|
||||
try {
|
||||
|
||||
@ -96,6 +96,7 @@ public class TranspilerTestRunner {
|
||||
transpiler.setGenerateSourceMaps(false);
|
||||
transpiler.setUseTsserver(true);
|
||||
transpiler.setVerbose(verbose);
|
||||
transpiler.setUsingJavaRuntime(false);
|
||||
|
||||
FileUtils.deleteQuietly(transpiler.getWorkingDirectory());
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ public class Dates {
|
||||
double JANUARY = 0;
|
||||
Date d = new Date(Date.UTC(2020, JANUARY, 01, 1, 0, 0));
|
||||
|
||||
String localeString = d.toLocaleString("fr", new DateTimeFormatOptions() {
|
||||
String localeString = d.toLocaleString("en", new DateTimeFormatOptions() {
|
||||
{
|
||||
$set("timeZone", "UTC");
|
||||
}
|
||||
|
||||
@ -8,6 +8,12 @@ public class Equals {
|
||||
|
||||
static Array<String> trace = new Array<String>();
|
||||
|
||||
static Integer int1 = 0;
|
||||
static Integer int2 = 0;
|
||||
static Integer int3 = 0;
|
||||
static Integer int4 = 0;
|
||||
static Integer int5 = 0;
|
||||
|
||||
public static void main(String[] args) {
|
||||
trace.push("" + equals("a", "b"));
|
||||
trace.push("" + equals("a", "a"));
|
||||
@ -20,6 +26,11 @@ public class Equals {
|
||||
MyObject2 o = new MyObject2("a");
|
||||
trace.push("" + equals(o, o));
|
||||
$export("trace", trace.join(","));
|
||||
// ensures that this kind of test works fine
|
||||
if (!int1.equals(int2 == int3
|
||||
? int4
|
||||
: int5)) {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean equals(Object a, Object b) {
|
||||
|
||||
11
transpiler/src/test/java/source/extension/ToBeSorted.java
Normal file
11
transpiler/src/test/java/source/extension/ToBeSorted.java
Normal file
@ -0,0 +1,11 @@
|
||||
package source.extension;
|
||||
|
||||
public class ToBeSorted {
|
||||
|
||||
public void myMethod() {
|
||||
}
|
||||
|
||||
static void myStaticMethod() {
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
package source.overload;
|
||||
|
||||
import static jsweet.util.Lang.$apply;
|
||||
import static jsweet.util.Lang.object;
|
||||
|
||||
public class OverLoadClassAndObject {
|
||||
|
||||
public static void main(String[] args) {
|
||||
OverLoadClassAndObject overload = new OverLoadClassAndObject();
|
||||
|
||||
System.out.println(overload.m(AnInterface.class));
|
||||
System.out.println(overload.m(new AClass()));
|
||||
System.out.println((String)$apply(object(overload).$get("m"), new AClass()));
|
||||
System.out.println((String)$apply(object(overload).$get("m"), AClass.class));
|
||||
// Overload with strings cannot work because AnInterface.class is transpiled as a string
|
||||
System.out.println((String)$apply(object(overload).$get("m"), AnInterface.class));
|
||||
|
||||
System.out.println(overload.m2(AClass.class));
|
||||
System.out.println(overload.m2(new AClass()));
|
||||
System.out.println((String)$apply(object(overload).$get("m2"), new AClass()));
|
||||
System.out.println((String)$apply(object(overload).$get("m2"), AClass.class));
|
||||
|
||||
assert overload.m(AnInterface.class) == "2:source.overload.AnInterface";
|
||||
assert overload.m(new AClass()) == "1:object";
|
||||
assert $apply(object(overload).$get("m"), new AClass()) == "1:object";
|
||||
assert $apply(object(overload).$get("m"), AClass.class) == "2:source.overload.AClass";
|
||||
assert $apply(object(overload).$get("m"), AnInterface.class) == "2:source.overload.AnInterface";
|
||||
|
||||
assert overload.m2(AClass.class) == "2:source.overload.AClass";
|
||||
assert overload.m2(new AClass()) == "1:object";
|
||||
assert $apply(object(overload).$get("m2"), new AClass()) == "1:object";
|
||||
assert $apply(object(overload).$get("m2"), AClass.class) == "2:source.overload.AClass";
|
||||
|
||||
}
|
||||
|
||||
String m(AnInterface o) {
|
||||
return "1:" + o.getName();
|
||||
}
|
||||
|
||||
String m(Class<AnInterface> clazz) {
|
||||
return "2:" + clazz.getName();
|
||||
}
|
||||
|
||||
String m2(AClass o) {
|
||||
return "1:" + o.getName();
|
||||
}
|
||||
|
||||
String m2(Class<AClass> clazz) {
|
||||
return "2:" + clazz.getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
interface AnInterface {
|
||||
String getName();
|
||||
}
|
||||
|
||||
class AClass implements AnInterface {
|
||||
public String getName() {
|
||||
return "object";
|
||||
}
|
||||
}
|
||||
50
transpiler/src/test/java/source/overload/OverLoadVarags.java
Normal file
50
transpiler/src/test/java/source/overload/OverLoadVarags.java
Normal file
@ -0,0 +1,50 @@
|
||||
package source.overload;
|
||||
|
||||
import static jsweet.util.Lang.$insert;
|
||||
|
||||
public class OverLoadVarags {
|
||||
|
||||
public static void main(String[] args) {
|
||||
OverLoadVarags ov = new OverLoadVarags();
|
||||
System.out.println(ov.m(new AClass2()));
|
||||
System.out.println(ov.m(new AClass2(), true, "a", "b", "c"));
|
||||
System.out.println((String)$insert("ov.m(new AClass2())"));
|
||||
System.out.println((String)$insert("ov.m(new AClass2(), true, 'a', 'b', 'c')"));
|
||||
assert ov.m(new AClass2()) == "1:object";
|
||||
assert ov.m(new AClass2(), true, "a", "b", "c") == "objecta,b,c/3";
|
||||
assert $insert("ov.m(new AClass2())") == "1:object";
|
||||
assert $insert("ov.m(new AClass2(), true, 'a', 'b', 'c')") == "objecta,b,c/3";
|
||||
// passing an array does not work
|
||||
// TODO: when invoking org method, test if passed expression type is an array and use call
|
||||
//assert $insert("ov.m(new AClass2(), true, ['a', 'b', 'c'])") == "objecta,b,c/3";
|
||||
assert ov.mref(new AClass2(), "a", "b", "c") == "objecta,b,c/3";
|
||||
assert ov.mref(new AClass2(), new String[] {"a", "b", "c"}) == "objecta,b,c/3";
|
||||
}
|
||||
|
||||
String m(AnInterface2 dto, boolean b, String... options) {
|
||||
return dto.getName() + varM(options);
|
||||
}
|
||||
|
||||
String m(AnInterface2 dto) {
|
||||
return "1:" + dto.getName();
|
||||
}
|
||||
|
||||
String mref(AnInterface2 dto, String... options) {
|
||||
return dto.getName() + varM(options);
|
||||
}
|
||||
|
||||
String varM(String... options) {
|
||||
return "" + options + "/" + $insert("arguments.length");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
interface AnInterface2 {
|
||||
String getName();
|
||||
}
|
||||
|
||||
class AClass2 implements AnInterface2 {
|
||||
public String getName() {
|
||||
return "object";
|
||||
}
|
||||
}
|
||||
27
transpiler/src/test/java/source/structural/Transients.java
Normal file
27
transpiler/src/test/java/source/structural/Transients.java
Normal file
@ -0,0 +1,27 @@
|
||||
package source.structural;
|
||||
|
||||
import static jsweet.util.Lang.$export;
|
||||
|
||||
import def.js.Array;
|
||||
import jsweet.util.Lang;
|
||||
|
||||
public class Transients {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Array<String> keys = Lang.$insert("Object.keys(new ChildWithTransients())");
|
||||
System.out.println("keys = "+keys);
|
||||
$export("keys", keys.join(","));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ParentWithTransients {
|
||||
int a;
|
||||
transient int b;
|
||||
}
|
||||
|
||||
class ChildWithTransients extends ParentWithTransients {
|
||||
int c;
|
||||
transient int d;
|
||||
|
||||
}
|
||||
@ -33,7 +33,11 @@ import def.js.Math;
|
||||
|
||||
public class FinalVariables {
|
||||
|
||||
int finalField;
|
||||
int modifiedField;
|
||||
|
||||
void m1(HTMLElement e) {
|
||||
modifiedField++;
|
||||
NodeList nodes = document.querySelectorAll("form .form-control");
|
||||
for (int i = 0; i < nodes.length; i++) {
|
||||
HTMLElement element = (HTMLElement) nodes.$get(i);
|
||||
@ -98,25 +102,46 @@ public class FinalVariables {
|
||||
}
|
||||
|
||||
void explicitFinal() {
|
||||
final String s = "abc";
|
||||
final String explicitFinalString = "abc";
|
||||
handler(new ANonFunctionalInterface() {
|
||||
@Override
|
||||
public void m() {
|
||||
System.out.println(s);
|
||||
System.out.println(explicitFinalString);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void explicitFinalWithDeferredAssignment(boolean condition) {
|
||||
final String explicitFinalStringWithDeferredAssignment;
|
||||
if(condition) {
|
||||
explicitFinalStringWithDeferredAssignment = "1";
|
||||
} else {
|
||||
explicitFinalStringWithDeferredAssignment = "2";
|
||||
}
|
||||
handler(new ANonFunctionalInterface() {
|
||||
@Override
|
||||
public void m() {
|
||||
System.out.println(explicitFinalStringWithDeferredAssignment);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void implicitFinal() {
|
||||
String s = "abc";
|
||||
String implicitFinalString = "abc";
|
||||
handler(new ANonFunctionalInterface() {
|
||||
@Override
|
||||
public void m() {
|
||||
System.out.println(s);
|
||||
System.out.println(implicitFinalString);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
String notFinal() {
|
||||
String notFinalString = "abc";
|
||||
notFinalString = "bcd";
|
||||
return notFinalString;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// subset of promises API
|
||||
@ -133,3 +158,4 @@ interface Callback<T1, T2> {
|
||||
interface ANonFunctionalInterface {
|
||||
void m();
|
||||
}
|
||||
|
||||
|
||||
@ -50,4 +50,14 @@ class Globals {
|
||||
});
|
||||
}
|
||||
public static void m() {};
|
||||
|
||||
public final static int explicitFinalGlobal = 1;
|
||||
public static int implicitFinalGlobal = 1;
|
||||
public static int notFinalGlobal = 1;
|
||||
|
||||
public static void init() {
|
||||
notFinalGlobal = 1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
31761
transpiler/src/test/resources/j4ts.js
Normal file
31761
transpiler/src/test/resources/j4ts.js
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user