Added DeclarationExtractor logic.
This commit is contained in:
@@ -14,211 +14,225 @@ import java.util.List;
|
||||
*/
|
||||
public final class JsFunction extends JsLiteral implements HasName {
|
||||
|
||||
private static void trace(String title, String code) {
|
||||
System.out.println("---------------------------");
|
||||
System.out.println(title + ":");
|
||||
System.out.println("---------------------------");
|
||||
System.out.println(code);
|
||||
}
|
||||
private static void trace(String title, String code) {
|
||||
System.out.println("---------------------------");
|
||||
System.out.println(title + ":");
|
||||
System.out.println("---------------------------");
|
||||
System.out.println(code);
|
||||
}
|
||||
|
||||
protected JsBlock body;
|
||||
protected final List<JsParameter> params = new ArrayList<JsParameter>();
|
||||
protected final JsScope scope;
|
||||
private boolean artificiallyRescued;
|
||||
private boolean executeOnce;
|
||||
private boolean fromDart;
|
||||
private JsFunction impliedExecute;
|
||||
private JsName name;
|
||||
private boolean trace = false;
|
||||
private boolean traceFirst = true;
|
||||
private boolean hoisted = false;
|
||||
private boolean constructor = false;
|
||||
protected JsBlock body;
|
||||
protected final List<JsParameter> params = new ArrayList<JsParameter>();
|
||||
protected final JsScope scope;
|
||||
private boolean artificiallyRescued;
|
||||
private boolean executeOnce;
|
||||
private boolean fromDart;
|
||||
private JsFunction impliedExecute;
|
||||
private JsName name;
|
||||
private boolean trace = false;
|
||||
private boolean traceFirst = true;
|
||||
private boolean hoisted = false;
|
||||
private boolean constructor = false;
|
||||
|
||||
/**
|
||||
* Creates an anonymous function.
|
||||
*/
|
||||
public JsFunction(JsScope parent) {
|
||||
this(parent, null, false);
|
||||
}
|
||||
/**
|
||||
* Creates an anonymous function.
|
||||
*/
|
||||
public JsFunction(JsScope parent) {
|
||||
this(parent, null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a function that is not derived from Dart source.
|
||||
*/
|
||||
public JsFunction(JsScope parent, JsName name) {
|
||||
this(parent, name, false);
|
||||
}
|
||||
/**
|
||||
* Creates a function that is not derived from Dart source.
|
||||
*/
|
||||
public JsFunction(JsScope parent, JsName name) {
|
||||
this(parent, name, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a named function, possibly derived from Dart source.
|
||||
*/
|
||||
public JsFunction(JsScope parent, JsName name, boolean fromDart) {
|
||||
assert (parent != null);
|
||||
this.fromDart = fromDart;
|
||||
setName(name);
|
||||
String scopeName = (name == null) ? "<anonymous>" : name.getIdent();
|
||||
scopeName = "function " + scopeName;
|
||||
this.scope = new JsScope(parent, scopeName);
|
||||
}
|
||||
/**
|
||||
* Creates a named function, possibly derived from Dart source.
|
||||
*/
|
||||
public JsFunction(JsScope parent, JsName name, boolean fromDart) {
|
||||
assert (parent != null);
|
||||
this.fromDart = fromDart;
|
||||
setName(name);
|
||||
String scopeName = (name == null) ? "<anonymous>" : name.getIdent();
|
||||
scopeName = "function " + scopeName;
|
||||
this.scope = new JsScope(parent, scopeName);
|
||||
}
|
||||
|
||||
public JsBlock getBody() {
|
||||
return body;
|
||||
}
|
||||
public JsBlock getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
/**
|
||||
* If true, this indicates that only the first invocation of the function will
|
||||
* have any effects. Subsequent invocations may be considered to be no-op
|
||||
* calls whose return value is ignored.
|
||||
*/
|
||||
public boolean getExecuteOnce() {
|
||||
return executeOnce;
|
||||
}
|
||||
/**
|
||||
* If true, this indicates that only the first invocation of the function will
|
||||
* have any effects. Subsequent invocations may be considered to be no-op
|
||||
* calls whose return value is ignored.
|
||||
*/
|
||||
public boolean getExecuteOnce() {
|
||||
return executeOnce;
|
||||
}
|
||||
|
||||
public JsFunction getImpliedExecute() {
|
||||
return impliedExecute;
|
||||
}
|
||||
public JsFunction getImpliedExecute() {
|
||||
return impliedExecute;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsName getName() {
|
||||
return name;
|
||||
}
|
||||
@Override
|
||||
public JsName getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setParameters(List<JsParameter> params) {
|
||||
this.params.clear();
|
||||
this.params.addAll(params);
|
||||
}
|
||||
|
||||
public List<JsParameter> getParameters() {
|
||||
return params;
|
||||
}
|
||||
|
||||
public JsScope getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSideEffects() {
|
||||
// If there's a name, the name is assigned to.
|
||||
return name != null;
|
||||
}
|
||||
|
||||
public boolean isArtificiallyRescued() {
|
||||
return artificiallyRescued;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBooleanFalse() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBooleanTrue() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefinitelyNotNull() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDefinitelyNull() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isFromDart() {
|
||||
return fromDart;
|
||||
}
|
||||
|
||||
public void setArtificiallyRescued(boolean rescued) {
|
||||
this.artificiallyRescued = rescued;
|
||||
}
|
||||
|
||||
public void setBody(JsBlock body) {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public void setExecuteOnce(boolean executeOnce) {
|
||||
this.executeOnce = executeOnce;
|
||||
}
|
||||
|
||||
public void setFromDart(boolean fromDart) {
|
||||
this.fromDart = fromDart;
|
||||
}
|
||||
|
||||
public void setImpliedExecute(JsFunction impliedExecute) {
|
||||
this.impliedExecute = impliedExecute;
|
||||
}
|
||||
|
||||
public void setName(JsName name) {
|
||||
this.name = name;
|
||||
if (name != null) {
|
||||
if (isFromDart()) {
|
||||
name.setStaticRef(this);
|
||||
}
|
||||
public List<JsParameter> getParameters() {
|
||||
return params;
|
||||
}
|
||||
}
|
||||
|
||||
public void setTrace() {
|
||||
this.trace = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void traverse(JsVisitor v, JsContext ctx) {
|
||||
String before = null;
|
||||
if (trace && v instanceof JsModVisitor) {
|
||||
before = this.toSource();
|
||||
if (traceFirst) {
|
||||
traceFirst = false;
|
||||
trace("SCRIPT INITIAL", before);
|
||||
}
|
||||
public JsScope getScope() {
|
||||
return scope;
|
||||
}
|
||||
if (v.visit(this, ctx)) {
|
||||
v.acceptWithInsertRemove(params);
|
||||
body = v.accept(body);
|
||||
|
||||
@Override
|
||||
public boolean hasSideEffects() {
|
||||
// If there's a name, the name is assigned to.
|
||||
return name != null;
|
||||
}
|
||||
v.endVisit(this, ctx);
|
||||
if (trace && v instanceof JsModVisitor) {
|
||||
String after = this.toSource();
|
||||
if (!after.equals(before)) {
|
||||
String title = v.getClass().getSimpleName();
|
||||
trace(title, after);
|
||||
}
|
||||
|
||||
public boolean isArtificiallyRescued() {
|
||||
return artificiallyRescued;
|
||||
}
|
||||
}
|
||||
|
||||
public void setHoisted() {
|
||||
hoisted = true;
|
||||
}
|
||||
@Override
|
||||
public boolean isBooleanFalse() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Whether the function has been hoisted */
|
||||
public boolean isHoisted() {
|
||||
return hoisted;
|
||||
}
|
||||
@Override
|
||||
public boolean isBooleanTrue() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebase the function to a new scope.
|
||||
* @param newScopeParent The scope to add the function to.
|
||||
*/
|
||||
public void rebaseScope(JsScope newScopeParent) {
|
||||
this.scope.rebase(newScopeParent);
|
||||
}
|
||||
@Override
|
||||
public boolean isDefinitelyNotNull() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsFunction setSourceRef(SourceInfo info) {
|
||||
super.setSourceRef(info);
|
||||
return this;
|
||||
}
|
||||
@Override
|
||||
public boolean isDefinitelyNull() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isConstructor() {
|
||||
return this.constructor;
|
||||
}
|
||||
public boolean isFromDart() {
|
||||
return fromDart;
|
||||
}
|
||||
|
||||
public boolean setIsConstructor(boolean constructor) {
|
||||
return this.constructor = constructor;
|
||||
}
|
||||
public void setArtificiallyRescued(boolean rescued) {
|
||||
this.artificiallyRescued = rescued;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeKind getKind() {
|
||||
return NodeKind.FUNCTION;
|
||||
}
|
||||
public void setBody(JsBlock body) {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public void setExecuteOnce(boolean executeOnce) {
|
||||
this.executeOnce = executeOnce;
|
||||
}
|
||||
|
||||
public void setFromDart(boolean fromDart) {
|
||||
this.fromDart = fromDart;
|
||||
}
|
||||
|
||||
public void setImpliedExecute(JsFunction impliedExecute) {
|
||||
this.impliedExecute = impliedExecute;
|
||||
}
|
||||
|
||||
public void setName(JsName name) {
|
||||
this.name = name;
|
||||
if (name != null) {
|
||||
if (isFromDart()) {
|
||||
name.setStaticRef(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setTrace() {
|
||||
this.trace = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void traverse(JsVisitor v, JsContext ctx) {
|
||||
String before = null;
|
||||
if (trace && v instanceof JsModVisitor) {
|
||||
before = this.toSource();
|
||||
if (traceFirst) {
|
||||
traceFirst = false;
|
||||
trace("SCRIPT INITIAL", before);
|
||||
}
|
||||
}
|
||||
if (v.visit(this, ctx)) {
|
||||
v.acceptWithInsertRemove(params);
|
||||
body = v.accept(body);
|
||||
}
|
||||
v.endVisit(this, ctx);
|
||||
if (trace && v instanceof JsModVisitor) {
|
||||
String after = this.toSource();
|
||||
if (!after.equals(before)) {
|
||||
String title = v.getClass().getSimpleName();
|
||||
trace(title, after);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setHoisted() {
|
||||
hoisted = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the function has been hoisted
|
||||
*/
|
||||
public boolean isHoisted() {
|
||||
return hoisted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebase the function to a new scope.
|
||||
*
|
||||
* @param newScopeParent The scope to add the function to.
|
||||
*/
|
||||
public void rebaseScope(JsScope newScopeParent) {
|
||||
this.scope.rebase(newScopeParent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsFunction setSourceRef(SourceInfo info) {
|
||||
super.setSourceRef(info);
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isConstructor() {
|
||||
return this.constructor;
|
||||
}
|
||||
|
||||
public boolean setIsConstructor(boolean constructor) {
|
||||
return this.constructor = constructor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeKind getKind() {
|
||||
return NodeKind.FUNCTION;
|
||||
}
|
||||
|
||||
// Pavel Talanov
|
||||
// dummy parameter to distinguish from other constructors
|
||||
private JsFunction(Void dummy, JsScope functionScope) {
|
||||
this.fromDart = false;
|
||||
this.scope = functionScope;
|
||||
}
|
||||
|
||||
public static JsFunction getAnonymousFunctionWithScope(JsScope scope) {
|
||||
return new JsFunction(null, scope);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user