package com.github.sommeri.less4j.core.compiler.stages; import java.util.ArrayList; import java.util.List; import com.github.sommeri.less4j.core.ast.ASTCssNode; import com.github.sommeri.less4j.core.ast.ASTCssNode.Visibility; import com.github.sommeri.less4j.core.ast.ASTCssNodeType; import com.github.sommeri.less4j.core.ast.Body; import com.github.sommeri.less4j.core.ast.BodyOwner; import com.github.sommeri.less4j.core.ast.RuleSet; import com.github.sommeri.less4j.core.ast.Selector; public class FinalVisibilitySolver { /* * A node can be visible either because it is visible in its own right or something inside it * wants be visible. */ private final ASTManipulator manipulator = new ASTManipulator(); public void resolveVisibility(ASTCssNode node) { if (node.getVisibility() == Visibility.DEFAULT) { return; } if (node.getType() == ASTCssNodeType.RULE_SET) { handleRuleset((RuleSet) node); } else if (node instanceof Body) { handleBodyKids((Body) node); } else if (node instanceof BodyOwner) { Body body = ((BodyOwner<?>) node).getBody(); handleBodyKids(body); } } private void handleRuleset(RuleSet node) { List<Selector> removeSelectors = null; for (Selector selector : node.getSelectors()) { switch (selector.getVisibility()) { case DEFAULT: if (removeSelectors == null) { removeSelectors = new ArrayList<Selector>(); } removeSelectors.add(selector); break; case VISIBLE: break; } } if (removeSelectors != null) { node.getSelectors().removeAll(removeSelectors); } handleBodyKids(node.getBody()); } private void handleBodyKids(Body body) { if (body == null) return ; List<ASTCssNode> removeKids = null; for (ASTCssNode kid : body.getMembers()) { switch (kid.getVisibility()) { case DEFAULT: if (removeKids == null) { removeKids = new ArrayList<ASTCssNode>(); } removeKids.add(kid); break; case VISIBLE: resolveVisibility(kid); break; } } if (removeKids != null) { manipulator.removeFromBody(body, removeKids); } } }