JS: added type parameter to JsContext

This commit is contained in:
Alexey Tsvetkov
2015-03-27 15:58:39 +03:00
parent efba2a2372
commit e94c79f838
13 changed files with 50 additions and 52 deletions
@@ -11,21 +11,21 @@ import org.jetbrains.annotations.Nullable;
* possible operations a JsVisitor subclass can perform on the currently visited
* node.
*/
public interface JsContext {
boolean canInsert();
public abstract class JsContext<T extends JsNode> {
public abstract boolean canInsert();
boolean canRemove();
public abstract boolean canRemove();
void insertAfter(JsNode node);
public abstract <R extends T> void insertAfter(R node);
void insertBefore(JsNode node);
public abstract <R extends T> void insertBefore(R node);
boolean isLvalue();
public abstract boolean isLvalue();
void removeMe();
public abstract void removeMe();
void replaceMe(JsNode node);
public abstract <R extends T> void replaceMe(R node);
@Nullable
JsNode getCurrentNode();
public abstract T getCurrentNode();
}
@@ -10,7 +10,7 @@ public object JsEmpty : SourceInfoAwareJsNode(), JsStatement {
v.visitEmpty(this)
}
override fun traverse(v: JsVisitorWithContext, ctx: JsContext) {
override fun traverse(v: JsVisitorWithContext, ctx: JsContext<*>) {
v.visit(this, ctx)
v.endVisit(this, ctx)
}
@@ -47,7 +47,7 @@ public abstract class JsVisitorWithContext {
return (T) doAcceptStatement(statement);
}
public final <T extends JsStatement> void acceptStatementList(List<T> statements) {
public final void acceptStatementList(List<JsStatement> statements) {
doAcceptStatementList(statements);
}
@@ -360,7 +360,7 @@ public abstract class JsVisitorWithContext {
protected abstract <T extends JsStatement> JsStatement doAcceptStatement(T statement);
protected abstract <T extends JsStatement> void doAcceptStatementList(List<T> statements);
protected abstract void doAcceptStatementList(List<JsStatement> statements);
protected abstract <T extends JsNode> void doTraverse(T node, JsContext ctx) ;
}
@@ -34,9 +34,9 @@ import java.util.Stack;
*/
public class JsVisitorWithContextImpl extends JsVisitorWithContext {
private final Stack<JsContext> statementContexts = new Stack<JsContext>();
private final Stack<JsContext<JsStatement>> statementContexts = new Stack<JsContext<JsStatement>>();
public class ListContext<T extends JsNode> implements JsContext {
public class ListContext<T extends JsNode> extends JsContext<T> {
private List<T> collection;
private int index;
@@ -51,13 +51,13 @@ public class JsVisitorWithContextImpl extends JsVisitorWithContext {
}
@Override
public void insertAfter(JsNode node) {
public <R extends T> void insertAfter(R node) {
//noinspection unchecked
collection.add(index + 1, (T) node);
}
@Override
public void insertBefore(JsNode node) {
public <R extends T> void insertBefore(R node) {
//noinspection unchecked
collection.add(index++, (T) node);
}
@@ -73,15 +73,14 @@ public class JsVisitorWithContextImpl extends JsVisitorWithContext {
}
@Override
public void replaceMe(JsNode node) {
public <R extends T> void replaceMe(R node) {
checkReplacement(collection.get(index), node);
//noinspection unchecked
collection.set(index, (T) node);
collection.set(index, node);
}
@Nullable
@Override
public JsNode getCurrentNode() {
public T getCurrentNode() {
if (index < collection.size()) {
return collection.get(index);
}
@@ -105,8 +104,7 @@ public class JsVisitorWithContextImpl extends JsVisitorWithContext {
}
}
@SuppressWarnings("unchecked")
private class NodeContext<T extends JsNode> implements JsContext {
private class NodeContext<T extends JsNode> extends JsContext<T> {
protected T node;
@Override
@@ -120,12 +118,12 @@ public class JsVisitorWithContextImpl extends JsVisitorWithContext {
}
@Override
public void insertAfter(JsNode node) {
public <R extends T> void insertAfter(R node) {
throw new UnsupportedOperationException();
}
@Override
public void insertBefore(JsNode node) {
public <R extends T> void insertBefore(R node) {
throw new UnsupportedOperationException();
}
@@ -140,14 +138,14 @@ public class JsVisitorWithContextImpl extends JsVisitorWithContext {
}
@Override
public void replaceMe(JsNode node) {
public <R extends T> void replaceMe(R node) {
checkReplacement(this.node, node);
this.node = (T) node;
this.node = node;
}
@Nullable
@Override
public JsNode getCurrentNode() {
public T getCurrentNode() {
return node;
}
@@ -185,8 +183,8 @@ public class JsVisitorWithContextImpl extends JsVisitorWithContext {
}
@Override
protected <T extends JsStatement> void doAcceptStatementList(List<T> statements) {
ListContext<T> context = new ListContext<T>();
protected void doAcceptStatementList(List<JsStatement> statements) {
ListContext<JsStatement> context = new ListContext<JsStatement>();
statementContexts.push(context);
context.traverse(statements);
statementContexts.pop();
@@ -198,7 +196,7 @@ public class JsVisitorWithContextImpl extends JsVisitorWithContext {
}
@NotNull
protected JsContext getLastStatementLevelContext() {
protected JsContext<JsStatement> getLastStatementLevelContext() {
return statementContexts.peek();
}
@@ -149,7 +149,7 @@ private fun JsFunction.markInlineArguments(descriptor: CallableDescriptor) {
}
val visitor = object: JsVisitorWithContextImpl() {
override fun endVisit(x: JsInvocation?, ctx: JsContext?) {
override fun endVisit(x: JsInvocation?, ctx: JsContext<*>?) {
if (x == null || ctx == null) return
val qualifier: JsExpression?
@@ -180,7 +180,7 @@ private fun replaceExternalNames(function: JsFunction, externalReplacements: Map
if (replacements.isEmpty()) return
val visitor = object: JsVisitorWithContextImpl() {
override fun endVisit(x: JsNameRef?, ctx: JsContext?) {
override fun endVisit(x: JsNameRef?, ctx: JsContext<*>?) {
if (x == null || x.getQualifier() != null) return
replacements[x.getIdent()]?.let {
@@ -22,7 +22,7 @@ import com.google.dart.compiler.backend.js.ast.JsContext
private class NodeRemover<T>(val klass: Class<T>, val predicate: (T) -> Boolean): JsVisitorWithContextImpl() {
override fun <T : JsNode?> doTraverse(node: T?, ctx: JsContext?) {
override fun <T : JsNode?> doTraverse(node: T?, ctx: JsContext<*>?) {
if (node == null || ctx == null) return
if (klass.isInstance(node)) {
@@ -66,7 +66,7 @@ private class UnusedLocalFunctionsCollector(functions: Map<JsName, JsFunction>)
}
}
override fun visit(x: JsPropertyInitializer?, ctx: JsContext?): Boolean {
override fun visit(x: JsPropertyInitializer?, ctx: JsContext<*>?): Boolean {
val value = x?.getValueExpr()
return when (value) {
@@ -75,17 +75,17 @@ private class UnusedLocalFunctionsCollector(functions: Map<JsName, JsFunction>)
}
}
override fun visit(x: JsFunction?, ctx: JsContext?): Boolean {
override fun visit(x: JsFunction?, ctx: JsContext<*>?): Boolean {
return !(wasProcessed(x))
}
override fun endVisit(x: JsFunction?, ctx: JsContext?) {
override fun endVisit(x: JsFunction?, ctx: JsContext<*>?) {
if (x == null) return
processed.add(x)
}
override fun endVisit(x: JsNameRef?, ctx: JsContext?) {
override fun endVisit(x: JsNameRef?, ctx: JsContext<*>?) {
val name = x?.getName()
if (isFunctionReference(x) && name != null) {
tracker.markReachable(name)
@@ -45,7 +45,7 @@ private class UnusedInstanceCollector : JsVisitorWithContextImpl() {
public val removableDeclarations: List<JsStatement>
get() = tracker.removable
override fun visit(x: JsVars.JsVar?, ctx: JsContext?): Boolean {
override fun visit(x: JsVars.JsVar?, ctx: JsContext<*>?): Boolean {
if (x == null) return false
if (!isLocalFunctionDeclaration(x)) return super.visit(x, ctx)
@@ -64,7 +64,7 @@ private class UnusedInstanceCollector : JsVisitorWithContextImpl() {
return false
}
override fun visit(x: JsNameRef?, ctx: JsContext?): Boolean {
override fun visit(x: JsNameRef?, ctx: JsContext<*>?): Boolean {
val name = x?.getName()
if (name != null) {
@@ -28,7 +28,7 @@ class ReferenceNameCollector : JsVisitorWithContextImpl() {
public val references: List<JsName>
get() = referenceSet.toList()
override fun endVisit(x: JsNameRef?, ctx: JsContext?) {
override fun endVisit(x: JsNameRef?, ctx: JsContext<*>?) {
val name = x?.getName()
if (name != null) {
referenceSet.add(name)
@@ -24,9 +24,9 @@ import com.google.dart.compiler.backend.js.ast.JsContext
import com.google.dart.compiler.backend.js.ast.JsLabel
class LabelNameRefreshingVisitor(val context: NamingContext, val functionScope: JsFunctionScope) : JsVisitorWithContextImpl() {
override fun visit(x: JsFunction?, ctx: JsContext?): Boolean = false
override fun visit(x: JsFunction?, ctx: JsContext<*>?): Boolean = false
override fun visit(x: JsLabel?, ctx: JsContext?): Boolean {
override fun visit(x: JsLabel?, ctx: JsContext<*>?): Boolean {
val labelName = x!!.getName()
val freshName = functionScope.enterLabel(labelName.getIdent())
@@ -37,7 +37,7 @@ class LabelNameRefreshingVisitor(val context: NamingContext, val functionScope:
return super.visit(x, ctx)
}
override fun endVisit(x: JsLabel?, ctx: JsContext?) {
override fun endVisit(x: JsLabel?, ctx: JsContext<*>?) {
super.endVisit(x, ctx)
functionScope.exitLabel()
}
@@ -27,7 +27,7 @@ import com.google.dart.compiler.backend.js.ast.JsLabel
class NameReplacingVisitor(private val replaceMap: Map<JsName, JsExpression>) : JsVisitorWithContextImpl() {
override fun endVisit(x: JsNameRef?, ctx: JsContext?) {
override fun endVisit(x: JsNameRef?, ctx: JsContext<*>?) {
if (x == null || ctx == null) return
val replacement = replaceMap[x.getName()]
@@ -36,7 +36,7 @@ class NameReplacingVisitor(private val replaceMap: Map<JsName, JsExpression>) :
ctx.replaceMe(replacement)
}
override fun endVisit(x: JsVars.JsVar?, ctx: JsContext?) {
override fun endVisit(x: JsVars.JsVar?, ctx: JsContext<*>?) {
if (x == null || ctx == null) return
val replacement = replaceMap[x.getName()]
@@ -46,7 +46,7 @@ class NameReplacingVisitor(private val replaceMap: Map<JsName, JsExpression>) :
}
}
override fun endVisit(x: JsLabel?, ctx: JsContext?) {
override fun endVisit(x: JsLabel?, ctx: JsContext<*>?) {
if (x == null || ctx == null) return
val replacement = replaceMap[x.getName()]
@@ -33,14 +33,14 @@ class ReturnReplacingVisitor(private val resultRef: JsNameRef?, private val brea
/**
* Prevents replacing returns in object literal
*/
override fun visit(x: JsObjectLiteral?, ctx: JsContext?): Boolean = false
override fun visit(x: JsObjectLiteral?, ctx: JsContext<*>?): Boolean = false
/**
* Prevents replacing returns in inner function
*/
override fun visit(x: JsFunction?, ctx: JsContext?): Boolean = false
override fun visit(x: JsFunction?, ctx: JsContext<*>?): Boolean = false
override fun endVisit(x: JsReturn?, ctx: JsContext?) {
override fun endVisit(x: JsReturn?, ctx: JsContext<*>?) {
if (x == null || ctx == null) return
if (breakLabel != null) {
@@ -24,11 +24,11 @@ import com.google.dart.compiler.backend.js.ast.JsObjectLiteral
import com.google.dart.compiler.backend.js.ast.JsVisitorWithContextImpl
class ThisReplacingVisitor(private val thisReplacement: JsExpression) : JsVisitorWithContextImpl() {
override fun endVisit(x: JsLiteral.JsThisRef?, ctx: JsContext?) {
override fun endVisit(x: JsLiteral.JsThisRef?, ctx: JsContext<*>?) {
ctx?.replaceMe(thisReplacement)
}
override fun visit(x: JsFunction?, ctx: JsContext?) = false
override fun visit(x: JsFunction?, ctx: JsContext<*>?) = false
override fun visit(x: JsObjectLiteral?, ctx: JsContext?) = false
override fun visit(x: JsObjectLiteral?, ctx: JsContext<*>?) = false
}