diff --git a/javascript/extractor/src/com/semmle/js/parser/JSObjectDecoder.java b/javascript/extractor/src/com/semmle/js/parser/JSObjectDecoder.java deleted file mode 100644 index 269127e363e..00000000000 --- a/javascript/extractor/src/com/semmle/js/parser/JSObjectDecoder.java +++ /dev/null @@ -1,196 +0,0 @@ -package com.semmle.js.parser; - -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.mozilla.javascript.NativeArray; -import org.mozilla.javascript.NativeObject; -import org.mozilla.javascript.UniqueTag; - -import com.semmle.js.ast.Position; -import com.semmle.js.ast.SourceElement; -import com.semmle.js.ast.SourceLocation; -import com.semmle.util.exception.CatastrophicError; - -/** - * Decode SpiderMonkey AST objects into their Java equivalents. - * - * We assume that every AST node has a type property uniquely identifying its - * type, which is also the name of the corresponding Java class. - * - * For each Java class, a list of properties to read from the SpiderMonkey AST object has to be provided. - * It is assumed that the Java class has a single constructor which takes exactly those - * properties as arguments. - */ -public class JSObjectDecoder { - private final ScriptLoader loader; - private final String source; - private final String pkg; - private final Map, List> spec; - - /** - * Construct a new object decoder. - * - * @param source the source code from which the AST was parsed - * @param loader the Rhino instance to use - * @param pkg the package in which to look for Java classes - * @param spec a mapping from Java classes to properties - */ - public JSObjectDecoder(String source, ScriptLoader loader, String pkg, Map, List> spec) { - this.source = source; - this.loader = loader; - this.pkg = pkg; - this.spec = spec; - } - - /** - * Decode a given SpiderMonkey AST object. - * - * Any exceptions that occur during conversion are caught and re-thrown as {@link CatastrophicError}, - * except for {@link ClassNotFoundException}s resulting from unsupported AST node types, which are - * re-thrown as {@link ParseError}s. - */ - @SuppressWarnings("unchecked") - public T decodeObject(NativeObject object) throws ParseError { - String type = (String) loader.readProperty(object, "type"); - try { - Class clazz = (Class)Class.forName(pkg + "." + type); - return decodeObject(object, clazz); - } catch (ClassNotFoundException e) { - throw new ParseError("Unexpected node type " + e, decodeLocation(object).getStart()); - } - } - - /** - * Decode a given SpiderMonkey AST object as an instance of a given class. - * - * Any exceptions that occur during conversion are caught and re-thrown as {@link CatastrophicError}, - * except for {@link ClassNotFoundException}s resulting from unsupported AST node types, which are - * re-thrown as {@link ParseError}s. - */ - @SuppressWarnings("unchecked") - public V decodeObject(NativeObject object, Class clazz) throws ParseError { - SourceLocation loc = decodeLocation(object); - Object[] ctorArgs = null; - try { - List props = spec.get(clazz); - if (props == null) - throw new CatastrophicError("Unsupported node type " + clazz.getName()); - ctorArgs = new Object[props.size()+1]; - ctorArgs[0] = loc; - for (int i=1; i decodeObjects(NativeArray objects) throws ParseError { - List result = new ArrayList(objects.size()); - for (Object object : objects) { - if (object == null) - result.add(null); - else - result.add(decodeObject((NativeObject)object)); - } - return result; - } - - /** - * Decode an array of SpiderMonkey AST objects as instances of a given class. - */ - public List decodeObjects(Class clazz, NativeArray objects) throws ParseError { - List result = new ArrayList(objects.size()); - for (Object object : objects) { - if (object == null) - result.add(null); - else - result.add(decodeObject((NativeObject)object, clazz)); - } - return result; - } - - /** - * Bound x between lo and hi, inclusive. - */ - private int bound(int x, int lo, int hi) { - if (x < lo) - return lo; - if (x > hi) - return hi; - return x; - } - - /** - * Decode a SpiderMonkey location object into a {@link SourceLocation}. - */ - public SourceLocation decodeLocation(NativeObject object) { - Integer startOffset, endOffset; - Position start, end; - Object loc = loader.readProperty(object, "loc"); - - if (loc == null) { - // no 'loc' property; check whether we have 'range' - Object range = loader.readProperty(object, "range"); - if (range instanceof NativeArray) { - // good; make up a source location on line 0 - startOffset = loader.readIntProperty(range, 0); - endOffset = loader.readIntProperty(range, 1); - start = new Position(1, startOffset, startOffset); - end = new Position(1, endOffset, endOffset); - return new SourceLocation(getSource(startOffset, endOffset), start, end); - } - return null; - } - - startOffset = loader.readIntProperty(object, "start"); - endOffset = loader.readIntProperty(object, "end"); - start = decodePosition((NativeObject)loader.readProperty(loc, "start"), startOffset); - end = decodePosition((NativeObject)loader.readProperty(loc, "end"), endOffset); - return new SourceLocation(getSource(startOffset, endOffset), start, end); - } - - /** - * Extract the source code between a given start and end offset. - */ - public String getSource(Integer startOffset, Integer endOffset) { - if (startOffset == null || endOffset == null || startOffset > endOffset) - return ""; - return source.substring(bound(startOffset, 0, source.length()), bound(endOffset, 0, source.length())); - } - - /** - * Decode a SpiderMonkey position object into a {@link SourceLocation}. - */ - private Position decodePosition(NativeObject object, int offset) { - return new Position(loader.readIntProperty(object, "line"), loader.readIntProperty(object, "column"), offset); - } -} diff --git a/javascript/extractor/src/com/semmle/js/parser/ScriptLoader.java b/javascript/extractor/src/com/semmle/js/parser/ScriptLoader.java deleted file mode 100644 index f7ae305f21c..00000000000 --- a/javascript/extractor/src/com/semmle/js/parser/ScriptLoader.java +++ /dev/null @@ -1,152 +0,0 @@ -package com.semmle.js.parser; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.URL; - -import org.mozilla.javascript.Context; -import org.mozilla.javascript.Function; -import org.mozilla.javascript.NativeArray; -import org.mozilla.javascript.NativeJSON; -import org.mozilla.javascript.NativeObject; -import org.mozilla.javascript.ScriptableObject; -import org.mozilla.javascript.Undefined; -import org.mozilla.javascript.UniqueTag; - -import com.semmle.util.exception.CatastrophicError; -import com.semmle.util.files.FileUtil; - -/** - * Helper class for executing JavaScript programs through Rhino and reading out values from the - * resulting environment. - */ -public class ScriptLoader { - private final Context cx; - private final ScriptableObject scope; - - public ScriptLoader(String scriptPath) { - InputStreamReader inputStreamReader = null; - - this.cx = Context.enter(); - this.scope = cx.initStandardObjects(); - try { - URL script = ScriptLoader.class.getResource(scriptPath); - if (script == null) - throw new IOException(); - InputStream scriptStream = script.openStream(); - inputStreamReader = new InputStreamReader(scriptStream, FileUtil.UTF8); - cx.evaluateReader(scope, inputStreamReader, scriptPath, 1, null); - } catch (IOException e) { - throw new CatastrophicError("Could not load script " + scriptPath + ".", e); - } finally { - if (inputStreamReader != null) - FileUtil.close(inputStreamReader); - } - } - - /** - * Read a global variable. - */ - public Object readGlobal(String name) { - return scope.get(name, scope); - } - - /** - * Read an object property; the property name may be a path of several individual - * names separated by dots. - * - * @return The value of the property, or {@literal null} if it could not be found. - */ - public Object readProperty(Object obj, String prop) { - Object res = obj; - for (String p : prop.split("\\.")) - res = ScriptableObject.getProperty((ScriptableObject)res, p); - if (res == UniqueTag.NOT_FOUND) - return null; - return res; - } - - /** - * Read an array element. - * - * @return The value of the element, or {@literal null} if it could not be found. - */ - public Object readProperty(Object obj, int idx) { - Object res = ((ScriptableObject)obj).get(idx, scope); - if (res == UniqueTag.NOT_FOUND) - return null; - return res; - } - - /** - * Read an object property and return its value cast to an integer. - */ - public Integer readIntProperty(Object obj, String prop) { - Object res = readProperty(obj, prop); - if (res == null || res == Undefined.instance) - return null; - return ((Number)res).intValue(); - } - - /** - * Read an array element and return its value cast to an integer. - */ - public Integer readIntProperty(Object obj, int idx) { - Object res = readProperty(obj, idx); - if (res == null || res == Undefined.instance) - return null; - return ((Number)res).intValue(); - } - - /** - * Read an object property and return its value cast to a string. - */ - public String readStringProperty(Object obj, String prop) { - Object val = readProperty(obj, prop); - if (val == null || val == Undefined.instance) - return null; - return String.valueOf(val); - } - - /** - * Create an empty JavaScript array. - */ - public NativeArray mkArray() { - return (NativeArray)cx.newArray(scope, 0); - } - - /** - * Create a JavaScript object. - * - * @param properties a list of alternating keys and values to populate the object with - */ - public NativeObject mkObject(Object... properties) { - NativeObject obj = new NativeObject(); - for (int i=0; i+1