package xapi.dev.ui;
import com.github.javaparser.ast.expr.*;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
import xapi.fu.Do;
import xapi.util.api.Destroyable;
import static xapi.fu.In2.reduceAll;
/**
* @author James X. Nelson (james@wetheinter.net)
* Created on 5/29/16.
*/
public class ComponentMetadataFinder extends VoidVisitorAdapter<ComponentMetadataQuery> implements Destroyable {
private ComponentGraph head, scope;
@Override
public void visit(UiContainerExpr n, ComponentMetadataQuery query) {
// always recurse into the root container
boolean recurse = head == null;
if (recurse) {
head = scope = new ComponentGraph(n);
super.visit(n, query);
return;
}
// if we aren't the root, check the query to see if we should recurse
recurse = scope.isAttributeChild() ?
query.isVisitAttributeContainers() :
query.isVisitChildContainers() ;
if (recurse) {
recurse(n, reduceAll(super::visit, n, query));
}
}
protected void recurse(UiExpr n, Do recurse) {
final ComponentGraph was = scope;
scope = was.appendChild(n);
try {
recurse.done();
} finally {
scope = was;
}
}
@Override
public void visit(UiAttrExpr n, ComponentMetadataQuery query) {
recurse(n, reduceAll(super::visit, n, query)
.doBefore(()->
query.notifyUiAttrExpr(scope, n)
));
}
@Override
public void visit(NameExpr n, ComponentMetadataQuery query) {
super.visit(n, query);
if (query.isTemplateName(n.getName())) {
query.notifyNameExpr(scope, n);
}
}
@Override
public void visit(MethodReferenceExpr n, ComponentMetadataQuery query) {
query.notifyMethodReference(scope, n);
super.visit(n, query);
}
public void visit(StringLiteralExpr n, ComponentMetadataQuery query) {
super.visit(n, query);
}
public void visit(TemplateLiteralExpr n, ComponentMetadataQuery query) {
super.visit(n, query);
}
@Override
public void visit(CssBlockExpr n, ComponentMetadataQuery query) {
query.notifyCssExpr(scope, n);
super.visit(n, query);
}
@Override
public void visit(CssContainerExpr n, ComponentMetadataQuery query) {
query.notifyCssExpr(scope, n);
super.visit(n, query);
}
@Override
public void visit(CssSelectorExpr n, ComponentMetadataQuery query) {
query.notifyCssExpr(scope, n);
super.visit(n, query);
}
@Override
public void visit(CssRuleExpr n, ComponentMetadataQuery query) {
query.notifyCssExpr(scope, n);
super.visit(n, query);
}
@Override
public void visit(CssValueExpr n, ComponentMetadataQuery query) {
query.notifyCssExpr(scope, n);
super.visit(n, query);
}
@Override
public void destroy() {
head = scope = null;
}
}