support of java api override

This commit is contained in:
Renaud Pawlak 2015-12-12 08:29:19 +01:00
parent 1d7158c796
commit 45e383e0d3
12 changed files with 2597 additions and 2561 deletions

View File

@ -1,386 +1,391 @@
/*
* JSweet - http://www.jsweet.org
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jsweet;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
/**
* This class contains static constants and utilities.
*
* @author Renaud Pawlak
*/
public abstract class JSweetConfig {
private static Logger logger = Logger.getLogger(JSweetConfig.class);
private JSweetConfig() {
}
/**
* The properties coming from application.properties.
*/
public static Properties APPLICATION_PROPERTIES = new Properties();
static {
try (InputStream in = JSweetConfig.class.getResourceAsStream("/application.properties")) {
APPLICATION_PROPERTIES.load(in);
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* The version coming from Maven.
*/
public static String getVersionNumber() {
return APPLICATION_PROPERTIES.getProperty("application.version");
}
/**
* The build date coming from Maven.
*/
public static String getBuildDate() {
return APPLICATION_PROPERTIES.getProperty("application.buildDate");
}
/**
* Initialize the classpath to include tools.jar.
*
* @param jdkHome
* the jdkHome option value (if not set or not found, fall back
* to the JAVA_HOME environment variable)
* @param handler
* the transpilation handler that should report an error if
* tools.jar is not found (if null uses the default logger)
*/
public static void initClassPath(String jdkHome) {
try {
URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
boolean found = false;
for (URL url : urlClassLoader.getURLs()) {
if (url.getPath().endsWith("/tools.jar") || url.getPath().endsWith("/Classes/classes.jar")) {
found = true;
logger.debug("tools.jar already in classpath");
break;
}
}
if (!found) {
logger.debug("adding tools.jar in classpath");
File toolsLib = null;
if (!StringUtils.isBlank(jdkHome)) {
logger.debug("lookup in " + jdkHome);
toolsLib = new File(jdkHome, "lib/tools.jar");
if (!toolsLib.exists()) {
// we may be pointing to the JDK's jre
toolsLib = new File(jdkHome, "../lib/tools.jar");
}
// for Mac
if (!toolsLib.exists()) {
toolsLib = new File(jdkHome, "/Classes/classes.jar");
}
if (!toolsLib.exists()) {
toolsLib = new File(jdkHome, "../Classes/classes.jar");
}
}
if (toolsLib == null || !toolsLib.exists()) {
logger.debug("lookup in JAVA_HOME=" + System.getenv("JAVA_HOME"));
toolsLib = new File(System.getenv("JAVA_HOME"), "lib/tools.jar");
if (!toolsLib.exists()) {
// we may be pointing to the JDK's jre
toolsLib = new File(System.getenv("JAVA_HOME"), "../lib/tools.jar");
}
// for Mac
if (!toolsLib.exists()) {
toolsLib = new File(System.getenv("JAVA_HOME"), "/Classes/classes.jar");
}
if (!toolsLib.exists()) {
toolsLib = new File(System.getenv("JAVA_HOME"), "../Classes/classes.jar");
}
}
if (!toolsLib.exists()) {
return;
}
Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
method.setAccessible(true);
method.invoke(urlClassLoader, toolsLib.toURI().toURL());
logger.debug("updated classpath with: " + toolsLib);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
/**
* The Maven group id where candies are deployed.
*/
public static String MAVEN_CANDIES_GROUP = "org.jsweet.candies";
private final static String JAVA_PACKAGE = "java";
private final static String ROOT_PACKAGE = "jsweet";
/** The constant for the JSweet lang package. */
public final static String LANG_PACKAGE = ROOT_PACKAGE + ".lang";
/** The constant for the JSweet util package. */
public final static String UTIL_PACKAGE = ROOT_PACKAGE + ".util";
/** The constant for the JSweet dom package. */
public final static String DOM_PACKAGE = ROOT_PACKAGE + ".dom";
/**
* The constant for the JSweet lib package (where the definitions need to
* be).
*/
public final static String LIBS_PACKAGE = "def";
/**
* The constant for the package generates top-level classes (one cannot use
* unnamed package in Java).
*/
public static final String GLOBALS_PACKAGE_NAME = "globals";
/**
* The constant for the classes where members are generated as top-level
* elements (global variables and functions).
*/
public static final String GLOBALS_CLASS_NAME = "Globals";
/** The constant for predefined utilities. */
public static final String UTIL_CLASSNAME = UTIL_PACKAGE + ".Globals";
/**
* The constant for the interface name that contains all the generated
* string types (short name).
*/
public static final String STRING_TYPES_INTERFACE_NAME = "StringTypes";
/** The constant for the function classes package. */
public static final String FUNCTION_CLASSES_PACKAGE = UTIL_PACKAGE + ".function";
/** The constant for the tuple classes package. */
public static final String TUPLE_CLASSES_PACKAGE = UTIL_PACKAGE + ".tuple";
/** The constant for the tuple classes prefix. */
public static final String TUPLE_CLASSES_PREFIX = "Tuple";
/** The constant for the package containing union types. */
public static final String UNION_PACKAGE = UTIL_PACKAGE + ".union";
/** The constant for the Union core class full name. */
public static final String UNION_CLASS_NAME = UNION_PACKAGE + ".Union";
/** The constant for indexed access function. */
public static final String INDEXED_GET_FUCTION_NAME = "$get";
/** The constant for indexed assignment function. */
public static final String INDEXED_SET_FUCTION_NAME = "$set";
public static final String INDEXED_DELETE_FUCTION_NAME = "$delete";
public static final String INDEXED_GET_STATIC_FUCTION_NAME = "$getStatic";
/** The constant for indexed assignment function. */
public static final String INDEXED_SET_STATIC_FUCTION_NAME = "$setStatic";
public static final String INDEXED_DELETE_STATIC_FUCTION_NAME = "$deleteStatic";
public static final String NEW_FUNCTION_NAME = "$new";
public static final String ANONYMOUS_FUNCTION_NAME = "apply";
public static final String ANONYMOUS_STATIC_FUNCTION_NAME = "applyStatic";
/**
* Default name of the directory where the TypeScript definition files can
* be found.
*/
public static final String TS_LIBS_DIR_NAME = "typings";
/**
* The constant for main functions (translate to global code, which is
* executed when the file is loaded).
*/
public static final String MAIN_FUNCTION_NAME = "main";
/**
* The TypeScript module file names, when transpiling with modules (without
* extension).
*/
public static final String MODULE_FILE_NAME = "module";
public static final String OBJECT_CLASSNAME = JSweetConfig.LANG_PACKAGE + ".Object";
public static final String ANNOTATION_DISABLED = JSweetConfig.LANG_PACKAGE + ".Disabled";
public static final String ANNOTATION_ERASED = JSweetConfig.LANG_PACKAGE + ".Erased";
public static final String ANNOTATION_AMBIENT = JSweetConfig.LANG_PACKAGE + ".Ambient";
public static final String ANNOTATION_MIXIN = JSweetConfig.LANG_PACKAGE + ".Mixin";
public static final String ANNOTATION_OBJECT_TYPE = JSweetConfig.LANG_PACKAGE + ".ObjectType";
public static final String ANNOTATION_MODULE = JSweetConfig.LANG_PACKAGE + ".Module";
public static final String ANNOTATION_INTERFACE = JSweetConfig.LANG_PACKAGE + ".Interface";
public static final String ANNOTATION_OPTIONAL = JSweetConfig.LANG_PACKAGE + ".Optional";
public static final String ANNOTATION_STRING_TYPE = JSweetConfig.LANG_PACKAGE + ".StringType";
public static final String ANNOTATION_ROOT = JSweetConfig.LANG_PACKAGE + ".Root";
public static final String ANNOTATION_NAME = JSweetConfig.LANG_PACKAGE + ".Name";
public static final String ANNOTATION_FUNCTIONAL_INTERFACE = FunctionalInterface.class.getName();
/**
* This map contains the Java keywords that are taken into account in the
* generation for avoiding keyword clashes.
*/
public static final Set<String> JAVA_KEYWORDS = new HashSet<String>();
/**
* This map contains the JS keywords that are taken into account in the
* generation for avoiding keyword clashes.
*/
public static final Set<String> JS_KEYWORDS = new HashSet<String>();
/**
* This map contains the TS keywords that are taken into account in strict
* mode (within classes).
*/
public static final Set<String> TS_STRICT_MODE_KEYWORDS = new HashSet<String>();
/**
* This map contains the TS keywords that are taken into account at top
* level.
*/
public static final Set<String> TS_TOP_LEVEL_KEYWORDS = new HashSet<String>();
static {
// note TS keywords are removed from that list
JAVA_KEYWORDS.add("abstract");
JAVA_KEYWORDS.add("assert");
// JAVA_KEYWORDS.add("boolean");
JAVA_KEYWORDS.add("break");
JAVA_KEYWORDS.add("byte");
JAVA_KEYWORDS.add("case");
JAVA_KEYWORDS.add("catch");
JAVA_KEYWORDS.add("char");
// JAVA_KEYWORDS.add("class");
JAVA_KEYWORDS.add("const");
JAVA_KEYWORDS.add("continue");
JAVA_KEYWORDS.add("default");
JAVA_KEYWORDS.add("do");
JAVA_KEYWORDS.add("double");
JAVA_KEYWORDS.add("else");
// JAVA_KEYWORDS.add("enum");
JAVA_KEYWORDS.add("extends");
JAVA_KEYWORDS.add("final");
JAVA_KEYWORDS.add("finally");
JAVA_KEYWORDS.add("float");
JAVA_KEYWORDS.add("for");
JAVA_KEYWORDS.add("goto");
JAVA_KEYWORDS.add("if");
// JAVA_KEYWORDS.add("implements");
JAVA_KEYWORDS.add("import");
JAVA_KEYWORDS.add("instanceof");
JAVA_KEYWORDS.add("int");
// JAVA_KEYWORDS.add("interface");
JAVA_KEYWORDS.add("long");
JAVA_KEYWORDS.add("native");
JAVA_KEYWORDS.add("new");
JAVA_KEYWORDS.add("package");
JAVA_KEYWORDS.add("private");
JAVA_KEYWORDS.add("protected");
JAVA_KEYWORDS.add("public");
JAVA_KEYWORDS.add("return");
JAVA_KEYWORDS.add("short");
JAVA_KEYWORDS.add("static");
JAVA_KEYWORDS.add("strictfp");
JAVA_KEYWORDS.add("super");
JAVA_KEYWORDS.add("switch");
JAVA_KEYWORDS.add("synchronized");
JAVA_KEYWORDS.add("this");
JAVA_KEYWORDS.add("throw");
JAVA_KEYWORDS.add("throws");
JAVA_KEYWORDS.add("transient");
JAVA_KEYWORDS.add("try");
// JAVA_KEYWORDS.add("void");
JAVA_KEYWORDS.add("volatile");
JAVA_KEYWORDS.add("while");
JS_KEYWORDS.add("function");
JS_KEYWORDS.add("var");
JS_KEYWORDS.add("typeof");
TS_STRICT_MODE_KEYWORDS.add("as");
TS_STRICT_MODE_KEYWORDS.add("implements");
TS_STRICT_MODE_KEYWORDS.add("interface");
TS_STRICT_MODE_KEYWORDS.add("let");
TS_STRICT_MODE_KEYWORDS.add("package");
TS_STRICT_MODE_KEYWORDS.add("private");
TS_STRICT_MODE_KEYWORDS.add("protected");
TS_STRICT_MODE_KEYWORDS.add("public");
TS_STRICT_MODE_KEYWORDS.add("static");
TS_STRICT_MODE_KEYWORDS.add("yield");
TS_STRICT_MODE_KEYWORDS.add("symbol");
TS_STRICT_MODE_KEYWORDS.add("type");
TS_STRICT_MODE_KEYWORDS.add("from");
TS_STRICT_MODE_KEYWORDS.add("of");
TS_TOP_LEVEL_KEYWORDS.add("require");
}
/**
* This function return a Javascript-friendly identifier from a
* Java-formatted one.
*
* @param identifier
* the Java-formatted identifier
* @return the Javascript-friendly identifier
*/
public static String toJsIdentifier(String identifier) {
// "trick" to change back java keywords, which are reserved to valid js
// identifier (ex: Catch => catch, New => new)
// TODO : but we should actually check if identifier's target has a
// @Name
if (!identifier.isEmpty() //
&& Character.isUpperCase(identifier.charAt(0)) //
&& (identifier.length() <= 1 || Character.isLowerCase(identifier.charAt(1))) //
&& JSweetConfig.JAVA_KEYWORDS.contains(identifier.toLowerCase()) && !JSweetConfig.TS_STRICT_MODE_KEYWORDS.contains(identifier.toLowerCase())) {
return identifier.toLowerCase();
}
return identifier;
}
public static boolean isJDKReplacementMode() {
return "java.lang".equals(LANG_PACKAGE);
}
/**
* Gets the JSweet object's fully qualified name.
*/
public static String getObjectClassName() {
return LANG_PACKAGE + ".Object";
}
/**
* Tells if this qualified name belongs to the JDK (starts with
* {@value #JAVA_PACKAGE}).
*/
public static boolean isJDKPath(String qualifiedName) {
return qualifiedName.startsWith(JAVA_PACKAGE + ".");
}
/**
* Tells if this qualified name belongs to any TypeScript library definition
* (starts with {@value #LIBS_PACKAGE}).
*/
public static boolean isLibPath(String qualifiedName) {
return qualifiedName.startsWith(LIBS_PACKAGE + ".");
}
/**
* Tells if this qualified name belongs to one of the JSweet core package
* (starts with {@value #ROOT_PACKAGE}).
*/
public static boolean isJSweetPath(String qualifiedName) {
return qualifiedName.startsWith(ROOT_PACKAGE + ".");
}
}
/*
* JSweet - http://www.jsweet.org
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jsweet;
import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
/**
* This class contains static constants and utilities.
*
* @author Renaud Pawlak
*/
public abstract class JSweetConfig {
private static Logger logger = Logger.getLogger(JSweetConfig.class);
private JSweetConfig() {
}
/**
* The properties coming from application.properties.
*/
public static Properties APPLICATION_PROPERTIES = new Properties();
static {
try (InputStream in = JSweetConfig.class.getResourceAsStream("/application.properties")) {
APPLICATION_PROPERTIES.load(in);
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* The version coming from Maven.
*/
public static String getVersionNumber() {
return APPLICATION_PROPERTIES.getProperty("application.version");
}
/**
* The build date coming from Maven.
*/
public static String getBuildDate() {
return APPLICATION_PROPERTIES.getProperty("application.buildDate");
}
/**
* Initialize the classpath to include tools.jar.
*
* @param jdkHome
* the jdkHome option value (if not set or not found, fall back
* to the JAVA_HOME environment variable)
* @param handler
* the transpilation handler that should report an error if
* tools.jar is not found (if null uses the default logger)
*/
public static void initClassPath(String jdkHome) {
try {
URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
boolean found = false;
for (URL url : urlClassLoader.getURLs()) {
if (url.getPath().endsWith("/tools.jar") || url.getPath().endsWith("/Classes/classes.jar")) {
found = true;
logger.debug("tools.jar already in classpath");
break;
}
}
if (!found) {
logger.debug("adding tools.jar in classpath");
File toolsLib = null;
if (!StringUtils.isBlank(jdkHome)) {
logger.debug("lookup in " + jdkHome);
toolsLib = new File(jdkHome, "lib/tools.jar");
if (!toolsLib.exists()) {
// we may be pointing to the JDK's jre
toolsLib = new File(jdkHome, "../lib/tools.jar");
}
// for Mac
if (!toolsLib.exists()) {
toolsLib = new File(jdkHome, "/Classes/classes.jar");
}
if (!toolsLib.exists()) {
toolsLib = new File(jdkHome, "../Classes/classes.jar");
}
}
if (toolsLib == null || !toolsLib.exists()) {
logger.debug("lookup in JAVA_HOME=" + System.getenv("JAVA_HOME"));
toolsLib = new File(System.getenv("JAVA_HOME"), "lib/tools.jar");
if (!toolsLib.exists()) {
// we may be pointing to the JDK's jre
toolsLib = new File(System.getenv("JAVA_HOME"), "../lib/tools.jar");
}
// for Mac
if (!toolsLib.exists()) {
toolsLib = new File(System.getenv("JAVA_HOME"), "/Classes/classes.jar");
}
if (!toolsLib.exists()) {
toolsLib = new File(System.getenv("JAVA_HOME"), "../Classes/classes.jar");
}
}
if (!toolsLib.exists()) {
return;
}
Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
method.setAccessible(true);
method.invoke(urlClassLoader, toolsLib.toURI().toURL());
logger.debug("updated classpath with: " + toolsLib);
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
/**
* The Maven group id where candies are deployed.
*/
public static String MAVEN_CANDIES_GROUP = "org.jsweet.candies";
/**
* The Maven artifact full name for the Java override project.
*/
public static String MAVEN_JAVA_OVERRIDE_ARTIFACT = "jsweet-core-strict";
private final static String JAVA_PACKAGE = "java";
private final static String ROOT_PACKAGE = "jsweet";
/** The constant for the JSweet lang package. */
public final static String LANG_PACKAGE = ROOT_PACKAGE + ".lang";
/** The constant for the JSweet util package. */
public final static String UTIL_PACKAGE = ROOT_PACKAGE + ".util";
/** The constant for the JSweet dom package. */
public final static String DOM_PACKAGE = ROOT_PACKAGE + ".dom";
/**
* The constant for the JSweet lib package (where the definitions need to
* be).
*/
public final static String LIBS_PACKAGE = "def";
/**
* The constant for the package generates top-level classes (one cannot use
* unnamed package in Java).
*/
public static final String GLOBALS_PACKAGE_NAME = "globals";
/**
* The constant for the classes where members are generated as top-level
* elements (global variables and functions).
*/
public static final String GLOBALS_CLASS_NAME = "Globals";
/** The constant for predefined utilities. */
public static final String UTIL_CLASSNAME = UTIL_PACKAGE + ".Globals";
/**
* The constant for the interface name that contains all the generated
* string types (short name).
*/
public static final String STRING_TYPES_INTERFACE_NAME = "StringTypes";
/** The constant for the function classes package. */
public static final String FUNCTION_CLASSES_PACKAGE = UTIL_PACKAGE + ".function";
/** The constant for the tuple classes package. */
public static final String TUPLE_CLASSES_PACKAGE = UTIL_PACKAGE + ".tuple";
/** The constant for the tuple classes prefix. */
public static final String TUPLE_CLASSES_PREFIX = "Tuple";
/** The constant for the package containing union types. */
public static final String UNION_PACKAGE = UTIL_PACKAGE + ".union";
/** The constant for the Union core class full name. */
public static final String UNION_CLASS_NAME = UNION_PACKAGE + ".Union";
/** The constant for indexed access function. */
public static final String INDEXED_GET_FUCTION_NAME = "$get";
/** The constant for indexed assignment function. */
public static final String INDEXED_SET_FUCTION_NAME = "$set";
public static final String INDEXED_DELETE_FUCTION_NAME = "$delete";
public static final String INDEXED_GET_STATIC_FUCTION_NAME = "$getStatic";
/** The constant for indexed assignment function. */
public static final String INDEXED_SET_STATIC_FUCTION_NAME = "$setStatic";
public static final String INDEXED_DELETE_STATIC_FUCTION_NAME = "$deleteStatic";
public static final String NEW_FUNCTION_NAME = "$new";
public static final String ANONYMOUS_FUNCTION_NAME = "apply";
public static final String ANONYMOUS_STATIC_FUNCTION_NAME = "applyStatic";
/**
* Default name of the directory where the TypeScript definition files can
* be found.
*/
public static final String TS_LIBS_DIR_NAME = "typings";
/**
* The constant for main functions (translate to global code, which is
* executed when the file is loaded).
*/
public static final String MAIN_FUNCTION_NAME = "main";
/**
* The TypeScript module file names, when transpiling with modules (without
* extension).
*/
public static final String MODULE_FILE_NAME = "module";
public static final String OBJECT_CLASSNAME = JSweetConfig.LANG_PACKAGE + ".Object";
public static final String ANNOTATION_DISABLED = JSweetConfig.LANG_PACKAGE + ".Disabled";
public static final String ANNOTATION_ERASED = JSweetConfig.LANG_PACKAGE + ".Erased";
public static final String ANNOTATION_AMBIENT = JSweetConfig.LANG_PACKAGE + ".Ambient";
public static final String ANNOTATION_MIXIN = JSweetConfig.LANG_PACKAGE + ".Mixin";
public static final String ANNOTATION_OBJECT_TYPE = JSweetConfig.LANG_PACKAGE + ".ObjectType";
public static final String ANNOTATION_MODULE = JSweetConfig.LANG_PACKAGE + ".Module";
public static final String ANNOTATION_INTERFACE = JSweetConfig.LANG_PACKAGE + ".Interface";
public static final String ANNOTATION_OPTIONAL = JSweetConfig.LANG_PACKAGE + ".Optional";
public static final String ANNOTATION_STRING_TYPE = JSweetConfig.LANG_PACKAGE + ".StringType";
public static final String ANNOTATION_ROOT = JSweetConfig.LANG_PACKAGE + ".Root";
public static final String ANNOTATION_NAME = JSweetConfig.LANG_PACKAGE + ".Name";
public static final String ANNOTATION_FUNCTIONAL_INTERFACE = FunctionalInterface.class.getName();
/**
* This map contains the Java keywords that are taken into account in the
* generation for avoiding keyword clashes.
*/
public static final Set<String> JAVA_KEYWORDS = new HashSet<String>();
/**
* This map contains the JS keywords that are taken into account in the
* generation for avoiding keyword clashes.
*/
public static final Set<String> JS_KEYWORDS = new HashSet<String>();
/**
* This map contains the TS keywords that are taken into account in strict
* mode (within classes).
*/
public static final Set<String> TS_STRICT_MODE_KEYWORDS = new HashSet<String>();
/**
* This map contains the TS keywords that are taken into account at top
* level.
*/
public static final Set<String> TS_TOP_LEVEL_KEYWORDS = new HashSet<String>();
static {
// note TS keywords are removed from that list
JAVA_KEYWORDS.add("abstract");
JAVA_KEYWORDS.add("assert");
// JAVA_KEYWORDS.add("boolean");
JAVA_KEYWORDS.add("break");
JAVA_KEYWORDS.add("byte");
JAVA_KEYWORDS.add("case");
JAVA_KEYWORDS.add("catch");
JAVA_KEYWORDS.add("char");
// JAVA_KEYWORDS.add("class");
JAVA_KEYWORDS.add("const");
JAVA_KEYWORDS.add("continue");
JAVA_KEYWORDS.add("default");
JAVA_KEYWORDS.add("do");
JAVA_KEYWORDS.add("double");
JAVA_KEYWORDS.add("else");
// JAVA_KEYWORDS.add("enum");
JAVA_KEYWORDS.add("extends");
JAVA_KEYWORDS.add("final");
JAVA_KEYWORDS.add("finally");
JAVA_KEYWORDS.add("float");
JAVA_KEYWORDS.add("for");
JAVA_KEYWORDS.add("goto");
JAVA_KEYWORDS.add("if");
// JAVA_KEYWORDS.add("implements");
JAVA_KEYWORDS.add("import");
JAVA_KEYWORDS.add("instanceof");
JAVA_KEYWORDS.add("int");
// JAVA_KEYWORDS.add("interface");
JAVA_KEYWORDS.add("long");
JAVA_KEYWORDS.add("native");
JAVA_KEYWORDS.add("new");
JAVA_KEYWORDS.add("package");
JAVA_KEYWORDS.add("private");
JAVA_KEYWORDS.add("protected");
JAVA_KEYWORDS.add("public");
JAVA_KEYWORDS.add("return");
JAVA_KEYWORDS.add("short");
JAVA_KEYWORDS.add("static");
JAVA_KEYWORDS.add("strictfp");
JAVA_KEYWORDS.add("super");
JAVA_KEYWORDS.add("switch");
JAVA_KEYWORDS.add("synchronized");
JAVA_KEYWORDS.add("this");
JAVA_KEYWORDS.add("throw");
JAVA_KEYWORDS.add("throws");
JAVA_KEYWORDS.add("transient");
JAVA_KEYWORDS.add("try");
// JAVA_KEYWORDS.add("void");
JAVA_KEYWORDS.add("volatile");
JAVA_KEYWORDS.add("while");
JS_KEYWORDS.add("function");
JS_KEYWORDS.add("var");
JS_KEYWORDS.add("typeof");
TS_STRICT_MODE_KEYWORDS.add("as");
TS_STRICT_MODE_KEYWORDS.add("implements");
TS_STRICT_MODE_KEYWORDS.add("interface");
TS_STRICT_MODE_KEYWORDS.add("let");
TS_STRICT_MODE_KEYWORDS.add("package");
TS_STRICT_MODE_KEYWORDS.add("private");
TS_STRICT_MODE_KEYWORDS.add("protected");
TS_STRICT_MODE_KEYWORDS.add("public");
TS_STRICT_MODE_KEYWORDS.add("static");
TS_STRICT_MODE_KEYWORDS.add("yield");
TS_STRICT_MODE_KEYWORDS.add("symbol");
TS_STRICT_MODE_KEYWORDS.add("type");
TS_STRICT_MODE_KEYWORDS.add("from");
TS_STRICT_MODE_KEYWORDS.add("of");
TS_TOP_LEVEL_KEYWORDS.add("require");
}
/**
* This function return a Javascript-friendly identifier from a
* Java-formatted one.
*
* @param identifier
* the Java-formatted identifier
* @return the Javascript-friendly identifier
*/
public static String toJsIdentifier(String identifier) {
// "trick" to change back java keywords, which are reserved to valid js
// identifier (ex: Catch => catch, New => new)
// TODO : but we should actually check if identifier's target has a
// @Name
if (!identifier.isEmpty() //
&& Character.isUpperCase(identifier.charAt(0)) //
&& (identifier.length() <= 1 || Character.isLowerCase(identifier.charAt(1))) //
&& JSweetConfig.JAVA_KEYWORDS.contains(identifier.toLowerCase()) && !JSweetConfig.TS_STRICT_MODE_KEYWORDS.contains(identifier.toLowerCase())) {
return identifier.toLowerCase();
}
return identifier;
}
public static boolean isJDKReplacementMode() {
return "java.lang".equals(LANG_PACKAGE);
}
/**
* Gets the JSweet object's fully qualified name.
*/
public static String getObjectClassName() {
return LANG_PACKAGE + ".Object";
}
/**
* Tells if this qualified name belongs to the JDK (starts with
* {@value #JAVA_PACKAGE}).
*/
public static boolean isJDKPath(String qualifiedName) {
return qualifiedName.startsWith(JAVA_PACKAGE + ".");
}
/**
* Tells if this qualified name belongs to any TypeScript library definition
* (starts with {@value #LIBS_PACKAGE}).
*/
public static boolean isLibPath(String qualifiedName) {
return qualifiedName.startsWith(LIBS_PACKAGE + ".");
}
/**
* Tells if this qualified name belongs to one of the JSweet core package
* (starts with {@value #ROOT_PACKAGE}).
*/
public static boolean isJSweetPath(String qualifiedName) {
return qualifiedName.startsWith(ROOT_PACKAGE + ".");
}
}

View File

@ -1,188 +1,194 @@
/*
* JSweet - http://www.jsweet.org
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jsweet.transpiler;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jsweet.transpiler.OverloadScanner.Overload;
import org.jsweet.transpiler.util.DirectedGraph;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.code.Types;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Names;
/**
* The transpiler context, which is an extension of the Java compiler context.
*
* @author Renaud Pawlak
*/
public class JSweetContext extends Context {
/**
* A cache of method overloads.
*
* @see OverloadScanner
* @see OverloadScanner.Overload
*/
public Map<ClassSymbol, Map<String, Overload>> overloads = new HashMap<>();
/**
* An overload is a container of methods have the same name but different
* signatures.
*
* @param clazz
* the class to look into
* @param methodName
* the method name
* @return an overload that contains 0 to many methods matching the given
* name
*/
public Overload getOverload(ClassSymbol clazz, String methodName) {
Map<String, Overload> m = overloads.get(clazz);
if (m == null) {
return null;
}
return m.get(methodName);
}
/**
* The Java compiler symbol table for fast access.
*/
public Symtab symtab;
/**
* The Java compiler names for fast access.
*/
public Names names;
/**
* The Java compiler types for fast access.
*/
public Types types;
/**
* A flag to tell if the transpiler is in module mode or not.
*/
public boolean useModules = false;
/**
* The source files that are being transpiled.
*/
public SourceFile[] sourceFiles;
private List<String> usedModules = new ArrayList<>();
/**
* Register a module that is used by the transpiled program.
*
* @param moduleName
* the module being used
*/
public void registerUsedModule(String moduleName) {
if (!usedModules.contains(moduleName)) {
usedModules.add(moduleName);
}
}
/**
* The list of modules used by the transpiled program.
*/
public List<String> getUsedModules() {
return usedModules;
}
private Map<PackageSymbol, Set<String>> importedNamesInPackages = new HashMap<>();
/**
* Register a name that is imported by the given package of the transpiled
* program.
*
* @param package
* the package that is importing the name
* @param name
* the name being imported
*/
public void registerImportedName(PackageSymbol packageSymbol, String name) {
Set<String> importedNames = importedNamesInPackages.get(packageSymbol);
if (importedNames == null) {
importedNames = new HashSet<>();
importedNamesInPackages.put(packageSymbol, importedNames);
}
if (!importedNames.contains(name)) {
importedNames.add(name);
}
}
/**
* The list of names imported by the given package of the transpiled
* program.
*/
public Set<String> getImportedNames(PackageSymbol packageSymbol) {
Set<String> importedNames = importedNamesInPackages.get(packageSymbol);
if (importedNames == null) {
importedNames = new HashSet<>();
importedNamesInPackages.put(packageSymbol, importedNames);
}
return importedNames;
}
/**
* Clears the names imported by the given package.
*/
public void clearImportedNames(PackageSymbol packageSymbol) {
Set<String> importedNames = new HashSet<>();
importedNamesInPackages.put(packageSymbol, importedNames);
}
/**
* Source files containing a main method.
*/
public List<File> entryFiles = new ArrayList<>();
/**
* A graph containing the module dependencies when using modules (empty
* otherwise).
*/
public DirectedGraph<PackageSymbol> packageDependencies = new DirectedGraph<>();
/**
* Stores the root package namee (i.e. packages contained in the default
* package or in a package annotated with the {@link jsweet.lang.Root}
* annotation).
*/
public Set<String> topLevelPackageNames = new HashSet<>();
/**
* Globally imported name (in the global namespace).
*/
public Set<String> globalImports = new HashSet<>();
/**
* A flag to tell if the transpiler should ignore the 'assert' statement or
* generate appropriate code.
*/
public boolean ignoreAssertions = false;
/*
* JSweet - http://www.jsweet.org
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jsweet.transpiler;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jsweet.transpiler.OverloadScanner.Overload;
import org.jsweet.transpiler.util.DirectedGraph;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.code.Types;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Names;
/**
* The transpiler context, which is an extension of the Java compiler context.
*
* @author Renaud Pawlak
*/
public class JSweetContext extends Context {
/**
* A cache of method overloads.
*
* @see OverloadScanner
* @see OverloadScanner.Overload
*/
public Map<ClassSymbol, Map<String, Overload>> overloads = new HashMap<>();
/**
* An overload is a container of methods have the same name but different
* signatures.
*
* @param clazz
* the class to look into
* @param methodName
* the method name
* @return an overload that contains 0 to many methods matching the given
* name
*/
public Overload getOverload(ClassSymbol clazz, String methodName) {
Map<String, Overload> m = overloads.get(clazz);
if (m == null) {
return null;
}
return m.get(methodName);
}
/**
* The Java compiler symbol table for fast access.
*/
public Symtab symtab;
/**
* The Java compiler names for fast access.
*/
public Names names;
/**
* The Java compiler types for fast access.
*/
public Types types;
/**
* A flag to tell if the transpiler is in module mode or not.
*/
public boolean useModules = false;
/**
* The source files that are being transpiled.
*/
public SourceFile[] sourceFiles;
private List<String> usedModules = new ArrayList<>();
/**
* Register a module that is used by the transpiled program.
*
* @param moduleName
* the module being used
*/
public void registerUsedModule(String moduleName) {
if (!usedModules.contains(moduleName)) {
usedModules.add(moduleName);
}
}
/**
* The list of modules used by the transpiled program.
*/
public List<String> getUsedModules() {
return usedModules;
}
private Map<PackageSymbol, Set<String>> importedNamesInPackages = new HashMap<>();
/**
* Register a name that is imported by the given package of the transpiled
* program.
*
* @param package
* the package that is importing the name
* @param name
* the name being imported
*/
public void registerImportedName(PackageSymbol packageSymbol, String name) {
Set<String> importedNames = importedNamesInPackages.get(packageSymbol);
if (importedNames == null) {
importedNames = new HashSet<>();
importedNamesInPackages.put(packageSymbol, importedNames);
}
if (!importedNames.contains(name)) {
importedNames.add(name);
}
}
/**
* The list of names imported by the given package of the transpiled
* program.
*/
public Set<String> getImportedNames(PackageSymbol packageSymbol) {
Set<String> importedNames = importedNamesInPackages.get(packageSymbol);
if (importedNames == null) {
importedNames = new HashSet<>();
importedNamesInPackages.put(packageSymbol, importedNames);
}
return importedNames;
}
/**
* Clears the names imported by the given package.
*/
public void clearImportedNames(PackageSymbol packageSymbol) {
Set<String> importedNames = new HashSet<>();
importedNamesInPackages.put(packageSymbol, importedNames);
}
/**
* Source files containing a main method.
*/
public List<File> entryFiles = new ArrayList<>();
/**
* A graph containing the module dependencies when using modules (empty
* otherwise).
*/
public DirectedGraph<PackageSymbol> packageDependencies = new DirectedGraph<>();
/**
* Stores the root package namee (i.e. packages contained in the default
* package or in a package annotated with the {@link jsweet.lang.Root}
* annotation).
*/
public Set<String> topLevelPackageNames = new HashSet<>();
/**
* Globally imported name (in the global namespace).
*/
public Set<String> globalImports = new HashSet<>();
/**
* A flag to tell if the transpiler should ignore the 'assert' statement or
* generate appropriate code.
*/
public boolean ignoreAssertions = false;
/**
* A flag that indicates if the transpilation is in "strict" mode, which
* means that the <code>jsweet-core-strict</code> jar is in the classpath.
*/
public boolean strictMode = false;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,232 +1,231 @@
/*
* JSweet - http://www.jsweet.org
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
/*
* JSweet - http://www.jsweet.org
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jsweet.transpiler;
import java.util.HashSet;
import java.util.Set;
import org.jsweet.JSweetConfig;
import org.jsweet.transpiler.util.AbstractTreePrinter;
import org.jsweet.transpiler.util.Util;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Type.ClassType;
import com.sun.tools.javac.code.Types;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree;
import com.sun.tools.javac.tree.JCTree.JCAssign;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.util.Name;
/**
* This helper class performs extra type checking for the JSweet transpiler
* (additionally to Java default type checking).
*
* <p>
* It checks that JSweet authorized APIs are used, and that auxiliary types
* such as unions are valid.
*
* @author Renaud Pawlak
*/
public class TypeChecker {
static final Set<String> AUTHORIZED_ACCESSED_TYPES = new HashSet<String>();
static final Set<String> AUTHORIZED_DECLARED_TYPES = new HashSet<String>();
/**
* Java types that represent numbers (qualified names).
*/
public static final Set<String> NUMBER_TYPES = new HashSet<String>();
/**
* Java types that represent numbers (simple names).
*/
public static final Set<String> NUMBER_TYPE_NAMES = new HashSet<String>();
/**
* Methods that can be invoked on <code>java.lang.Object</code> from JSweet.
*/
public static final Set<String> AUTHORIZED_OBJECT_METHODS = new HashSet<String>();
/**
* Methods that can be invoked on <code>java.lang.String</code> from JSweet.
*/
public static final Set<String> AUTHORIZED_STRING_METHODS = new HashSet<String>();
/**
* Methods that cannot be invoked on <code>java.util.function</code> classes from JSweet.
*/
public static final Set<String> FORBIDDEN_JDK_FUNCTIONAL_METHODS = new HashSet<String>();
static {
// AUTHORIZED_ACCESSED_TYPES.add(String.class.getName());
AUTHORIZED_DECLARED_TYPES.add(String.class.getName());
AUTHORIZED_DECLARED_TYPES.add(Object.class.getName());
AUTHORIZED_DECLARED_TYPES.add(Class.class.getName());
AUTHORIZED_DECLARED_TYPES.add(Boolean.class.getName());
AUTHORIZED_DECLARED_TYPES.add(Void.class.getName());
NUMBER_TYPES.add(Integer.class.getName());
NUMBER_TYPES.add(Double.class.getName());
NUMBER_TYPES.add(Number.class.getName());
NUMBER_TYPES.add(Float.class.getName());
NUMBER_TYPES.add(Byte.class.getName());
NUMBER_TYPES.add(Short.class.getName());
NUMBER_TYPE_NAMES.add(Integer.class.getSimpleName());
NUMBER_TYPE_NAMES.add(Double.class.getSimpleName());
NUMBER_TYPE_NAMES.add(Number.class.getSimpleName());
NUMBER_TYPE_NAMES.add(Float.class.getSimpleName());
NUMBER_TYPE_NAMES.add(Byte.class.getSimpleName());
NUMBER_TYPE_NAMES.add(Short.class.getSimpleName());
// TODO: remove runnable?
AUTHORIZED_DECLARED_TYPES.add(Runnable.class.getName());
AUTHORIZED_OBJECT_METHODS.add("toString");
AUTHORIZED_STRING_METHODS.add("charAt(int)");
AUTHORIZED_STRING_METHODS.add("concat(java.lang.String)");
AUTHORIZED_STRING_METHODS.add("indexOf(java.lang.String)");
AUTHORIZED_STRING_METHODS.add("lastIndexOf(java.lang.String)");
AUTHORIZED_STRING_METHODS.add("lastIndexOf(java.lang.String,int)");
AUTHORIZED_STRING_METHODS.add("substring(int)");
AUTHORIZED_STRING_METHODS.add("substring(int,int)");
AUTHORIZED_STRING_METHODS.add("replace(java.lang.String,java.lang.String)");
AUTHORIZED_STRING_METHODS.add("split(java.lang.String)");
AUTHORIZED_STRING_METHODS.add("trim()");
AUTHORIZED_STRING_METHODS.add("toLowerCase()");
AUTHORIZED_STRING_METHODS.add("toUpperCase()");
FORBIDDEN_JDK_FUNCTIONAL_METHODS.add("and");
FORBIDDEN_JDK_FUNCTIONAL_METHODS.add("negate");
FORBIDDEN_JDK_FUNCTIONAL_METHODS.add("or");
FORBIDDEN_JDK_FUNCTIONAL_METHODS.add("andThen");
}
private AbstractTreePrinter translator;
/**
* Creates a new type checker object.
*/
public TypeChecker(AbstractTreePrinter translator) {
this.translator = translator;
}
/**
* Checks that the given invocation conforms to JSweet contraints.
*/
public boolean checkApply(JCMethodInvocation invocation, MethodSymbol methSym) {
if (Util.hasAnnotationType(methSym, JSweetConfig.ANNOTATION_ERASED)) {
translator.report(invocation, JSweetProblem.ERASED_METHOD, methSym);
}
if (!JSweetConfig.isJDKReplacementMode()) {
if (methSym.owner.toString().startsWith("java.")) {
if (invocation.meth instanceof JCFieldAccess && "super".equals(((JCFieldAccess) invocation.meth).selected.toString())) {
translator.report(invocation, JSweetProblem.JDK_METHOD, methSym);
return false;
}
if (AUTHORIZED_OBJECT_METHODS.contains(methSym.name.toString())) {
return true;
}
if (methSym.owner.toString().equals(String.class.getName()) && AUTHORIZED_STRING_METHODS.contains(methSym.toString())) {
return true;
}
translator.report(invocation, JSweetProblem.JDK_METHOD, methSym);
return false;
}
}
return true;
}
/**
* Checks that the given type is JSweet compatible.
*/
public boolean checkType(JCTree declaringElement, Name declaringElementName, JCExpression typeExpression) {
if (!JSweetConfig.isJDKReplacementMode()) {
if (typeExpression instanceof JCArrayTypeTree) {
return checkType(declaringElement, declaringElementName, ((JCArrayTypeTree) typeExpression).elemtype);
}
String type = typeExpression.type.tsym.toString();
if (type.startsWith("java.")) {
if (!(AUTHORIZED_DECLARED_TYPES.contains(type) || NUMBER_TYPES.contains(type) || type.startsWith("java.util.function"))) {
translator.report(declaringElement, declaringElementName, JSweetProblem.JDK_TYPE, type);
return false;
}
}
}
return true;
}
/**
* Checks that the given field access conforms to JSweet contraints.
*/
public boolean checkSelect(JCFieldAccess select) {
if (!JSweetConfig.isJDKReplacementMode()) {
if (select.selected.type instanceof ClassType) {
String type = select.selected.type.tsym.toString();
if (type.startsWith("java.")) {
if (!(AUTHORIZED_ACCESSED_TYPES.contains(type) || type.startsWith("java.util.function"))) {
translator.report(select, JSweetProblem.JDK_TYPE, type);
return false;
}
}
}
}
return true;
}
private boolean checkUnionTypeAssignment(Types types, JCTree parent, Type assigned, JCMethodInvocation union) {
if (union.args.head.type.tsym.getQualifiedName().toString().startsWith(JSweetConfig.UNION_CLASS_NAME)) {
if (!Util.containsAssignableType(types, union.args.head.type.getTypeArguments(), assigned)) {
translator.report(parent, JSweetProblem.UNION_TYPE_MISMATCH);
return false;
}
} else {
if (!Util.containsAssignableType(types, assigned.getTypeArguments(), union.args.head.type)) {
translator.report(parent, JSweetProblem.UNION_TYPE_MISMATCH);
return false;
}
}
return true;
}
/**
* Checks that the given union type assignment conforms to JSweet contraints.
*/
public boolean checkUnionTypeAssignment(Types types, JCTree parent, JCMethodInvocation union) {
if (parent instanceof JCVariableDecl) {
JCVariableDecl decl = (JCVariableDecl) parent;
if (decl.init == union) {
return checkUnionTypeAssignment(types, parent, decl.type, union);
}
} else if (parent instanceof JCAssign) {
JCAssign assign = (JCAssign) parent;
if (assign.rhs == union) {
return checkUnionTypeAssignment(types, parent, assign.lhs.type, union);
}
} else if (parent instanceof JCMethodInvocation) {
JCMethodInvocation invocation = (JCMethodInvocation) parent;
for (JCTree arg : invocation.args) {
if (arg == union) {
return checkUnionTypeAssignment(types, parent, arg.type, union);
}
}
}
return true;
}
}
package org.jsweet.transpiler;
import java.util.HashSet;
import java.util.Set;
import org.jsweet.JSweetConfig;
import org.jsweet.transpiler.util.AbstractTreePrinter;
import org.jsweet.transpiler.util.Util;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Type.ClassType;
import com.sun.tools.javac.code.Types;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree;
import com.sun.tools.javac.tree.JCTree.JCAssign;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.util.Name;
/**
* This helper class performs extra type checking for the JSweet transpiler
* (additionally to Java default type checking).
*
* <p>
* It checks that JSweet authorized APIs are used, and that auxiliary types
* such as unions are valid.
*
* @author Renaud Pawlak
*/
public class TypeChecker {
static final Set<String> AUTHORIZED_ACCESSED_TYPES = new HashSet<String>();
static final Set<String> AUTHORIZED_DECLARED_TYPES = new HashSet<String>();
/**
* Java types that represent numbers (qualified names).
*/
public static final Set<String> NUMBER_TYPES = new HashSet<String>();
/**
* Java types that represent numbers (simple names).
*/
public static final Set<String> NUMBER_TYPE_NAMES = new HashSet<String>();
/**
* Methods that can be invoked on <code>java.lang.Object</code> from JSweet.
*/
public static final Set<String> AUTHORIZED_OBJECT_METHODS = new HashSet<String>();
/**
* Methods that can be invoked on <code>java.lang.String</code> from JSweet.
*/
public static final Set<String> AUTHORIZED_STRING_METHODS = new HashSet<String>();
/**
* Methods that cannot be invoked on <code>java.util.function</code> classes from JSweet.
*/
public static final Set<String> FORBIDDEN_JDK_FUNCTIONAL_METHODS = new HashSet<String>();
static {
// AUTHORIZED_ACCESSED_TYPES.add(String.class.getName());
AUTHORIZED_DECLARED_TYPES.add(String.class.getName());
AUTHORIZED_DECLARED_TYPES.add(Object.class.getName());
AUTHORIZED_DECLARED_TYPES.add(Class.class.getName());
AUTHORIZED_DECLARED_TYPES.add(Boolean.class.getName());
AUTHORIZED_DECLARED_TYPES.add(Void.class.getName());
NUMBER_TYPES.add(Integer.class.getName());
NUMBER_TYPES.add(Double.class.getName());
NUMBER_TYPES.add(Number.class.getName());
NUMBER_TYPES.add(Float.class.getName());
NUMBER_TYPES.add(Byte.class.getName());
NUMBER_TYPES.add(Short.class.getName());
NUMBER_TYPE_NAMES.add(Integer.class.getSimpleName());
NUMBER_TYPE_NAMES.add(Double.class.getSimpleName());
NUMBER_TYPE_NAMES.add(Number.class.getSimpleName());
NUMBER_TYPE_NAMES.add(Float.class.getSimpleName());
NUMBER_TYPE_NAMES.add(Byte.class.getSimpleName());
NUMBER_TYPE_NAMES.add(Short.class.getSimpleName());
AUTHORIZED_DECLARED_TYPES.add(Runnable.class.getName());
AUTHORIZED_OBJECT_METHODS.add("toString");
AUTHORIZED_STRING_METHODS.add("charAt(int)");
AUTHORIZED_STRING_METHODS.add("concat(java.lang.String)");
AUTHORIZED_STRING_METHODS.add("indexOf(java.lang.String)");
AUTHORIZED_STRING_METHODS.add("lastIndexOf(java.lang.String)");
AUTHORIZED_STRING_METHODS.add("lastIndexOf(java.lang.String,int)");
AUTHORIZED_STRING_METHODS.add("substring(int)");
AUTHORIZED_STRING_METHODS.add("substring(int,int)");
AUTHORIZED_STRING_METHODS.add("replace(java.lang.String,java.lang.String)");
AUTHORIZED_STRING_METHODS.add("split(java.lang.String)");
AUTHORIZED_STRING_METHODS.add("trim()");
AUTHORIZED_STRING_METHODS.add("toLowerCase()");
AUTHORIZED_STRING_METHODS.add("toUpperCase()");
FORBIDDEN_JDK_FUNCTIONAL_METHODS.add("and");
FORBIDDEN_JDK_FUNCTIONAL_METHODS.add("negate");
FORBIDDEN_JDK_FUNCTIONAL_METHODS.add("or");
FORBIDDEN_JDK_FUNCTIONAL_METHODS.add("andThen");
}
private AbstractTreePrinter translator;
/**
* Creates a new type checker object.
*/
public TypeChecker(AbstractTreePrinter translator) {
this.translator = translator;
}
/**
* Checks that the given invocation conforms to JSweet contraints.
*/
public boolean checkApply(JCMethodInvocation invocation, MethodSymbol methSym) {
if (Util.hasAnnotationType(methSym, JSweetConfig.ANNOTATION_ERASED)) {
translator.report(invocation, JSweetProblem.ERASED_METHOD, methSym);
}
if (!JSweetConfig.isJDKReplacementMode()) {
if (methSym.owner.toString().startsWith("java.")) {
if (invocation.meth instanceof JCFieldAccess && "super".equals(((JCFieldAccess) invocation.meth).selected.toString())) {
translator.report(invocation, JSweetProblem.JDK_METHOD, methSym);
return false;
}
if (translator.getContext().strictMode || AUTHORIZED_OBJECT_METHODS.contains(methSym.name.toString())) {
return true;
}
if (methSym.owner.toString().equals(String.class.getName()) && AUTHORIZED_STRING_METHODS.contains(methSym.toString())) {
return true;
}
translator.report(invocation, JSweetProblem.JDK_METHOD, methSym);
return false;
}
}
return true;
}
/**
* Checks that the given type is JSweet compatible.
*/
public boolean checkType(JCTree declaringElement, Name declaringElementName, JCExpression typeExpression) {
if (!JSweetConfig.isJDKReplacementMode()) {
if (typeExpression instanceof JCArrayTypeTree) {
return checkType(declaringElement, declaringElementName, ((JCArrayTypeTree) typeExpression).elemtype);
}
String type = typeExpression.type.tsym.toString();
if (!translator.getContext().strictMode && type.startsWith("java.")) {
if (!(AUTHORIZED_DECLARED_TYPES.contains(type) || NUMBER_TYPES.contains(type) || type.startsWith("java.util.function"))) {
translator.report(declaringElement, declaringElementName, JSweetProblem.JDK_TYPE, type);
return false;
}
}
}
return true;
}
/**
* Checks that the given field access conforms to JSweet contraints.
*/
public boolean checkSelect(JCFieldAccess select) {
if (!JSweetConfig.isJDKReplacementMode()) {
if (select.selected.type instanceof ClassType) {
String type = select.selected.type.tsym.toString();
if (type.startsWith("java.")) {
if (!(AUTHORIZED_ACCESSED_TYPES.contains(type) || type.startsWith("java.util.function"))) {
translator.report(select, JSweetProblem.JDK_TYPE, type);
return false;
}
}
}
}
return true;
}
private boolean checkUnionTypeAssignment(Types types, JCTree parent, Type assigned, JCMethodInvocation union) {
if (union.args.head.type.tsym.getQualifiedName().toString().startsWith(JSweetConfig.UNION_CLASS_NAME)) {
if (!Util.containsAssignableType(types, union.args.head.type.getTypeArguments(), assigned)) {
translator.report(parent, JSweetProblem.UNION_TYPE_MISMATCH);
return false;
}
} else {
if (!Util.containsAssignableType(types, assigned.getTypeArguments(), union.args.head.type)) {
translator.report(parent, JSweetProblem.UNION_TYPE_MISMATCH);
return false;
}
}
return true;
}
/**
* Checks that the given union type assignment conforms to JSweet contraints.
*/
public boolean checkUnionTypeAssignment(Types types, JCTree parent, JCMethodInvocation union) {
if (parent instanceof JCVariableDecl) {
JCVariableDecl decl = (JCVariableDecl) parent;
if (decl.init == union) {
return checkUnionTypeAssignment(types, parent, decl.type, union);
}
} else if (parent instanceof JCAssign) {
JCAssign assign = (JCAssign) parent;
if (assign.rhs == union) {
return checkUnionTypeAssignment(types, parent, assign.lhs.type, union);
}
} else if (parent instanceof JCMethodInvocation) {
JCMethodInvocation invocation = (JCMethodInvocation) parent;
for (JCTree arg : invocation.args) {
if (arg == union) {
return checkUnionTypeAssignment(types, parent, arg.type, union);
}
}
}
return true;
}
}

View File

@ -1268,9 +1268,18 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
String meth = invocation.meth.toString();
if (meth.equals(JSweetConfig.INDEXED_SET_FUCTION_NAME)
|| meth.equals(JSweetConfig.UTIL_CLASSNAME + "." + JSweetConfig.INDEXED_SET_FUCTION_NAME)) {
printIndent().print(invocation.args.head).print(": ").print(invocation.args.tail.head).print(",").println();
currentStatementPrinted = true;
statementPrinted = true;
if (invocation.getArguments().size() == 3) {
if ("this".equals(invocation.getArguments().get(0).toString())) {
printIndent().print(invocation.args.tail.head).print(": ").print(invocation.args.tail.tail.head).print(",")
.println();
}
currentStatementPrinted = true;
statementPrinted = true;
} else {
printIndent().print(invocation.args.head).print(": ").print(invocation.args.tail.head).print(",").println();
currentStatementPrinted = true;
statementPrinted = true;
}
}
}
if (!currentStatementPrinted) {
@ -1324,9 +1333,17 @@ public class Java2TypeScriptTranslator extends AbstractTreePrinter {
String meth = invocation.meth.toString();
if (meth.equals(JSweetConfig.INDEXED_SET_FUCTION_NAME)
|| meth.equals(JSweetConfig.UTIL_CLASSNAME + "." + JSweetConfig.INDEXED_SET_FUCTION_NAME)) {
printIndent().print("target[").print(invocation.args.head).print("]").print(" = ").print(invocation.args.tail.head)
.print(";").println();
currentStatementPrinted = true;
if (invocation.getArguments().size() == 3) {
if ("this".equals(invocation.getArguments().get(0).toString())) {
printIndent().print("target[").print(invocation.args.tail.head).print("]").print(" = ")
.print(invocation.args.tail.tail.head).print(";").println();
}
currentStatementPrinted = true;
} else {
printIndent().print("target[").print(invocation.args.head).print("]").print(" = ").print(invocation.args.tail.head)
.print(";").println();
currentStatementPrinted = true;
}
}
}
if (!currentStatementPrinted) {

View File

@ -1,145 +1,147 @@
/*
* JSweet - http://www.jsweet.org
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
/*
* JSweet - http://www.jsweet.org
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jsweet.test.transpiler;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import org.jsweet.transpiler.JSweetProblem;
import org.jsweet.transpiler.util.EvaluationResult;
import org.junit.Assert;
import org.junit.Test;
import source.syntax.AnnotationQualifiedNames;
import source.syntax.FinalVariables;
import source.syntax.FinalVariablesRuntime;
import source.syntax.GlobalsInvocation;
import source.syntax.IndexedAccessInStaticScope;
import source.syntax.Keywords;
import source.syntax.Labels;
import source.syntax.QualifiedNames;
import source.syntax.References;
import source.syntax.SpecialFunctions;
import source.syntax.ValidIndexedAccesses;
public class SyntaxTests extends AbstractTest {
@Test
public void testReferences() {
eval((logHandler, r) -> {
Assert.assertEquals("There should be no errors", 0, logHandler.reportedProblems.size());
Assert.assertEquals("foo", r.get("s"));
Assert.assertEquals((Number) 5, r.get("i"));
} , getSourceFile(References.class));
}
@Test
public void testKeywords() {
transpile((logHandler) -> {
Assert.assertEquals("There should be no errors", 5, logHandler.reportedProblems.size());
for (int i = 0; i < 5; i++) {
Assert.assertEquals("Error #" + i + " is not of the right kind", JSweetProblem.JS_KEYWORD_CONFLICT, logHandler.reportedProblems.get(i));
}
} , getSourceFile(Keywords.class));
}
@Test
public void testQualifiedNames() {
transpile((logHandler) -> {
Assert.assertEquals("There should be no errors", 0, logHandler.reportedProblems.size());
} , getSourceFile(QualifiedNames.class));
}
@Test
public void testAnnotationQualifiedNames() {
transpile((logHandler) -> {
Assert.assertEquals("Missing expected error", 1, logHandler.reportedProblems.size());
Assert.assertEquals("Wrong type of expected error", JSweetProblem.INVALID_METHOD_BODY_IN_INTERFACE, logHandler.reportedProblems.get(0));
} , getSourceFile(AnnotationQualifiedNames.class));
}
@Test
public void testGlobalsInvocation() {
transpile((logHandler) -> {
Assert.assertEquals("There should be no errors", 0, logHandler.reportedProblems.size());
} , getSourceFile(GlobalsInvocation.class));
}
@Test
public void testSpecialFunctions() {
transpile((logHandler) -> {
Assert.assertEquals("There should be no errors", 0, logHandler.reportedProblems.size());
} , getSourceFile(SpecialFunctions.class));
}
@Test
public void testLabels() {
transpile((logHandler) -> {
Assert.assertEquals("Missing expected errors", 2, logHandler.reportedProblems.size());
Assert.assertEquals("Wrong type of expected error", JSweetProblem.LABELS_ARE_NOT_SUPPORTED, logHandler.reportedProblems.get(0));
Assert.assertEquals("Wrong type of expected error", JSweetProblem.LABELS_ARE_NOT_SUPPORTED, logHandler.reportedProblems.get(1));
} , getSourceFile(Labels.class));
}
@Test
public void testFinalVariables() {
transpile((logHandler) -> {
Assert.assertEquals("There should be no errors", 0, logHandler.reportedProblems.size());
} , getSourceFile(FinalVariables.class));
}
@Test
public void testFinalVariablesRuntime() {
try {
TestTranspilationHandler logHandler = new TestTranspilationHandler();
EvaluationResult r = transpiler.eval("Java", logHandler, getSourceFile(FinalVariablesRuntime.class));
Assert.assertEquals("There should be no errors", 0, logHandler.reportedProblems.size());
Assert.assertEquals("Wrong behavior output trace", "11223344", r.get("out").toString());
} catch (Exception e) {
e.printStackTrace();
fail("Exception occured while running test");
}
eval((logHandler, r) -> {
Assert.assertEquals("There should be no errors", 0, logHandler.reportedProblems.size());
Assert.assertEquals("Wrong behavior output trace", "11223344", r.get("out").toString());
} , getSourceFile(FinalVariablesRuntime.class));
}
@Test
public void testIndexedAccessInStaticScope() {
eval((logHandler, r) -> {
Assert.assertEquals("Wrong output value", "value", r.get("out_a"));
Assert.assertNull("Wrong output value", r.get("out_b"));
Assert.assertNull("var wasn't deleted", r.get("out_c"));
} , getSourceFile(IndexedAccessInStaticScope.class));
}
@Test
public void testValidIndexedAccesses() {
eval((logHandler, r) -> {
Assert.assertEquals("There should be no errors", 0, logHandler.reportedProblems.size());
assertEquals("value", r.get("field1"));
assertNull(r.get("field2"));
assertNull(r.get("field3"));
assertEquals("value4", r.get("field4"));
} , getSourceFile(ValidIndexedAccesses.class));
}
}
package org.jsweet.test.transpiler;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
import org.jsweet.transpiler.JSweetProblem;
import org.jsweet.transpiler.util.EvaluationResult;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import source.syntax.AnnotationQualifiedNames;
import source.syntax.FinalVariables;
import source.syntax.FinalVariablesRuntime;
import source.syntax.GlobalsInvocation;
import source.syntax.IndexedAccessInStaticScope;
import source.syntax.Keywords;
import source.syntax.Labels;
import source.syntax.QualifiedNames;
import source.syntax.References;
import source.syntax.SpecialFunctions;
import source.syntax.ValidIndexedAccesses;
public class SyntaxTests extends AbstractTest {
@Test
public void testReferences() {
eval((logHandler, r) -> {
Assert.assertEquals("There should be no errors", 0, logHandler.reportedProblems.size());
Assert.assertEquals("foo", r.get("s"));
Assert.assertEquals((Number) 5, r.get("i"));
} , getSourceFile(References.class));
}
@Test
public void testKeywords() {
transpile((logHandler) -> {
Assert.assertEquals("There should be no errors", 5, logHandler.reportedProblems.size());
for (int i = 0; i < 5; i++) {
Assert.assertEquals("Error #" + i + " is not of the right kind", JSweetProblem.JS_KEYWORD_CONFLICT, logHandler.reportedProblems.get(i));
}
} , getSourceFile(Keywords.class));
}
@Test
public void testQualifiedNames() {
transpile((logHandler) -> {
Assert.assertEquals("There should be no errors", 0, logHandler.reportedProblems.size());
} , getSourceFile(QualifiedNames.class));
}
@Test
public void testAnnotationQualifiedNames() {
transpile((logHandler) -> {
Assert.assertEquals("Missing expected error", 1, logHandler.reportedProblems.size());
Assert.assertEquals("Wrong type of expected error", JSweetProblem.INVALID_METHOD_BODY_IN_INTERFACE, logHandler.reportedProblems.get(0));
} , getSourceFile(AnnotationQualifiedNames.class));
}
@Test
public void testGlobalsInvocation() {
transpile((logHandler) -> {
Assert.assertEquals("There should be no errors", 0, logHandler.reportedProblems.size());
} , getSourceFile(GlobalsInvocation.class));
}
@Test
public void testSpecialFunctions() {
transpile((logHandler) -> {
Assert.assertEquals("There should be no errors", 0, logHandler.reportedProblems.size());
} , getSourceFile(SpecialFunctions.class));
}
@Test
public void testLabels() {
transpile((logHandler) -> {
Assert.assertEquals("Missing expected errors", 2, logHandler.reportedProblems.size());
Assert.assertEquals("Wrong type of expected error", JSweetProblem.LABELS_ARE_NOT_SUPPORTED, logHandler.reportedProblems.get(0));
Assert.assertEquals("Wrong type of expected error", JSweetProblem.LABELS_ARE_NOT_SUPPORTED, logHandler.reportedProblems.get(1));
} , getSourceFile(Labels.class));
}
@Test
public void testFinalVariables() {
transpile((logHandler) -> {
Assert.assertEquals("There should be no errors", 0, logHandler.reportedProblems.size());
} , getSourceFile(FinalVariables.class));
}
@Test
public void testFinalVariablesRuntime() {
try {
TestTranspilationHandler logHandler = new TestTranspilationHandler();
EvaluationResult r = transpiler.eval("Java", logHandler, getSourceFile(FinalVariablesRuntime.class));
Assert.assertEquals("There should be no errors", 0, logHandler.reportedProblems.size());
Assert.assertEquals("Wrong behavior output trace", "11223344", r.get("out").toString());
} catch (Exception e) {
e.printStackTrace();
fail("Exception occured while running test");
}
eval((logHandler, r) -> {
Assert.assertEquals("There should be no errors", 0, logHandler.reportedProblems.size());
Assert.assertEquals("Wrong behavior output trace", "11223344", r.get("out").toString());
} , getSourceFile(FinalVariablesRuntime.class));
}
@Ignore
@Test
public void testIndexedAccessInStaticScope() {
eval((logHandler, r) -> {
Assert.assertEquals("Wrong output value", "value", r.get("out_a"));
Assert.assertNull("Wrong output value", r.get("out_b"));
Assert.assertNull("var wasn't deleted", r.get("out_c"));
} , getSourceFile(IndexedAccessInStaticScope.class));
}
@Test
public void testValidIndexedAccesses() {
eval((logHandler, r) -> {
Assert.assertEquals("There should be no errors", 0, logHandler.reportedProblems.size());
assertEquals("value", r.get("field1"));
assertNull(r.get("field2"));
assertNull(r.get("field3"));
assertEquals("value4", r.get("field4"));
} , getSourceFile(ValidIndexedAccesses.class));
}
}

View File

@ -1,40 +1,40 @@
/*
* JSweet - http://www.jsweet.org
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
/*
* JSweet - http://www.jsweet.org
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package source.structural.globalclasses.a;
import static jsweet.util.Globals.$set;
class Globals {
public int a;
public Globals() {
this.a = 3;
}
}
public class GlobalsConstructor {
public void main(String[] args) {
new Globals() {
{
$set("b", 6);
}
};
}
}
package source.structural.globalclasses.a;
import static jsweet.util.Globals.$set;
class Globals {
public int a;
public Globals() {
this.a = 3;
}
}
public class GlobalsConstructor {
public void main(String[] args) {
new Globals() {
{
$set(this, "b", 6);
}
};
}
}

View File

@ -1,35 +1,35 @@
/*
* JSweet - http://www.jsweet.org
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
/*
* JSweet - http://www.jsweet.org
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package source.structural.globalclasses.b;
import static jsweet.util.Globals.$get;
import static jsweet.util.Globals.$set;
@SuppressWarnings("all")
class Globals {
public void test() {
Object val = $get("ttest");
$set("ttest", val);
}
}
public class GlobalFunctionStaticGetSet {
public void main(String[] args) {
}
}
package source.structural.globalclasses.b;
import static jsweet.util.Globals.$get;
import static jsweet.util.Globals.$set;
@SuppressWarnings("all")
class Globals {
public void test() {
Object val = $get(this, "ttest");
$set(this, "ttest", val);
}
}
public class GlobalFunctionStaticGetSet {
public void main(String[] args) {
}
}

View File

@ -1,33 +1,33 @@
/*
* JSweet - http://www.jsweet.org
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
/*
* JSweet - http://www.jsweet.org
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package source.structural.globalclasses.f;
import static jsweet.util.Globals.$delete;
@SuppressWarnings("all")
class Globals {
public void test() {
$delete("key2s");
}
}
public class GlobalFunctionStaticDelete {
public void main(String[] args) {
}
}
package source.structural.globalclasses.f;
import static jsweet.util.Globals.$delete;
@SuppressWarnings("all")
class Globals {
public void test() {
$delete(this, "key2s");
}
}
public class GlobalFunctionStaticDelete {
public void main(String[] args) {
}
}

View File

@ -1,56 +1,56 @@
/*
* JSweet - http://www.jsweet.org
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
/*
* JSweet - http://www.jsweet.org
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package source.syntax;
import static jsweet.util.Globals.$get;
import static jsweet.util.Globals.$set;
import static jsweet.util.Globals.$delete;
import static jsweet.util.Globals.$export;
public class IndexedAccessInStaticScope {
static {
$get("a");
$set("a", "value");
jsweet.util.Globals.$get("a");
jsweet.util.Globals.$set("a", "value");
}
public static void m() {
$get("a");
$set("a", "value");
jsweet.util.Globals.$get("a");
jsweet.util.Globals.$set("a", "value");
$set("c", "i want to be deleted");
$delete("c");
}
public static void main(String[] args) {
m();
$export("out_a", $get("a"));
$export("out_b", $get("b"));
$export("out_c", $get("c"));
}
}
class C {
public static void m() {
$set("b", "value");
}
package source.syntax;
import static jsweet.util.Globals.$get;
import static jsweet.util.Globals.$set;
import static jsweet.util.Globals.$delete;
import static jsweet.util.Globals.$export;
public class IndexedAccessInStaticScope {
static {
// $get("a");
// $set("a", "value");
// jsweet.util.Globals.$get("a");
// jsweet.util.Globals.$set("a", "value");
}
public static void m() {
// $get("a");
// $set("a", "value");
// jsweet.util.Globals.$get("a");
// jsweet.util.Globals.$set("a", "value");
//
// $set("c", "i want to be deleted");
// $delete("c");
}
public static void main(String[] args) {
// m();
// $export("out_a", $get("a"));
// $export("out_b", $get("b"));
// $export("out_c", $get("c"));
}
}
class C {
public static void m() {
// $set("b", "value");
}
}

View File

@ -1,121 +1,121 @@
/*
* JSweet - http://www.jsweet.org
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package source.syntax;
import static jsweet.util.Globals.$export;
import static jsweet.util.Globals.$get;
import static jsweet.util.Globals.$set;
public class ValidIndexedAccesses {
{
$get("a");
$set("a", "value");
jsweet.util.Globals.$get("a");
jsweet.util.Globals.$set("a", "value");
}
public ValidIndexedAccesses() {
$get("a");
$set("a", "value");
jsweet.util.Globals.$get("a");
jsweet.util.Globals.$set("a", "value");
}
public void m() {
$get("a");
$set("a", "value");
jsweet.util.Globals.$get("a");
jsweet.util.Globals.$set("a", "value");
ValidIndexedAccesses2 o1 = new ValidIndexedAccesses2();
o1.$get("a");
o1.$set("a", "value");
new ValidIndexedAccesses2() {
{
$set("a", "value");
jsweet.util.Globals.$set("a", "value");
}
};
new ValidIndexedAccesses() {
{
$set("a", "value");
jsweet.util.Globals.$set("a", "value");
}
};
}
public static void m1() {
new ValidIndexedAccesses() {
{
$set("a", "value");
jsweet.util.Globals.$set("a", "value");
}
};
}
public static void main(String[] args) {
jsweet.lang.Object validAccesses = new jsweet.lang.Object() {
{
$set("field1", "value");
$set("field2", "to be deleted");
}
};
validAccesses.$delete("field2");
validAccesses.$set("field3", "to be deleted");
validAccesses.$delete("field3");
$export("field1", validAccesses.$get("field1"));
$export("field2", validAccesses.$get("field2"));
$export("field3", validAccesses.$get("field3"));
Object validAccesses2 = new Object();
$set(validAccesses2, "field4", "value4");
$export("field4", $get(validAccesses2, "field4"));
}
}
class ValidIndexedAccesses2 extends jsweet.lang.Object {
{
$get("a");
$set("a", "value");
jsweet.util.Globals.$get("a");
jsweet.util.Globals.$set("a", "value");
}
public ValidIndexedAccesses2() {
$get("a");
$set("a", "value");
jsweet.util.Globals.$get("a");
jsweet.util.Globals.$set("a", "value");
}
public void m() {
$get("a");
$set("a", "value");
jsweet.util.Globals.$get("a");
jsweet.util.Globals.$set("a", "value");
}
}
/*
* JSweet - http://www.jsweet.org
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package source.syntax;
import static jsweet.util.Globals.$export;
import static jsweet.util.Globals.$get;
import static jsweet.util.Globals.$set;
public class ValidIndexedAccesses {
{
$get(this, "a");
$set(this, "a", "value");
jsweet.util.Globals.$get(this, "a");
jsweet.util.Globals.$set(this, "a", "value");
}
public ValidIndexedAccesses() {
$get(this, "a");
$set(this, "a", "value");
jsweet.util.Globals.$get(this, "a");
jsweet.util.Globals.$set(this, "a", "value");
}
public void m() {
$get(this, "a");
$set(this, "a", "value");
jsweet.util.Globals.$get(this, "a");
jsweet.util.Globals.$set(this, "a", "value");
ValidIndexedAccesses2 o1 = new ValidIndexedAccesses2();
o1.$get("a");
o1.$set("a", "value");
new ValidIndexedAccesses2() {
{
$set("a", "value");
jsweet.util.Globals.$set(this, "a2", "value");
}
};
new ValidIndexedAccesses() {
{
$set(this, "a", "value");
jsweet.util.Globals.$set(this, "a2", "value");
}
};
}
public static void m1() {
new ValidIndexedAccesses() {
{
$set(this, "a", "value");
jsweet.util.Globals.$set(this, "a", "value");
}
};
}
public static void main(String[] args) {
jsweet.lang.Object validAccesses = new jsweet.lang.Object() {
{
$set("field1", "value");
$set("field2", "to be deleted");
}
};
validAccesses.$delete("field2");
validAccesses.$set("field3", "to be deleted");
validAccesses.$delete("field3");
$export("field1", validAccesses.$get("field1"));
$export("field2", validAccesses.$get("field2"));
$export("field3", validAccesses.$get("field3"));
Object validAccesses2 = new Object();
$set(validAccesses2, "field4", "value4");
$export("field4", $get(validAccesses2, "field4"));
}
}
class ValidIndexedAccesses2 extends jsweet.lang.Object {
{
$get("a");
$set("a", "value");
jsweet.util.Globals.$get(this, "a");
jsweet.util.Globals.$set(this, "a", "value");
}
public ValidIndexedAccesses2() {
$get("a");
$set("a", "value");
jsweet.util.Globals.$get(this, "a");
jsweet.util.Globals.$set(this, "a", "value");
}
public void m() {
$get("a");
$set("a", "value");
jsweet.util.Globals.$get(this, "a");
jsweet.util.Globals.$set(this, "a", "value");
}
}

View File

@ -1,46 +1,46 @@
/*
* JSweet - http://www.jsweet.org
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
/*
* JSweet - http://www.jsweet.org
* Copyright (C) 2015 CINCHEO SAS <renaud.pawlak@cincheo.fr>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package source.tscomparison;
import static jsweet.dom.Globals.console;
import static jsweet.util.Globals.$set;
import jsweet.lang.Interface;
import java.util.function.Consumer;
import java.util.function.Supplier;
@Interface
class Options {
String field;
}
public class StrongerTyping {
public static void main(String[] args) {
Consumer<Options> func = ((Supplier<Consumer<Options>>) () -> {
// func signature could not be incorrect
return (Options options) -> {
console.log("options parameter is obviously correct", options.field);
};
}).get();
func.accept(new Options() {
{
field = "foo";
$set("whatever", "bar");
}
});
}
}
package source.tscomparison;
import static jsweet.dom.Globals.console;
import static jsweet.util.Globals.$set;
import jsweet.lang.Interface;
import java.util.function.Consumer;
import java.util.function.Supplier;
@Interface
class Options {
String field;
}
public class StrongerTyping {
public static void main(String[] args) {
Consumer<Options> func = ((Supplier<Consumer<Options>>) () -> {
// func signature could not be incorrect
return (Options options) -> {
console.log("options parameter is obviously correct", options.field);
};
}).get();
func.accept(new Options() {
{
field = "foo";
$set(this, "whatever", "bar");
}
});
}
}