Package com.github.sommeri.less4j.core.compiler.stages

Source Code of com.github.sommeri.less4j.core.compiler.stages.PropertiesMerger

package com.github.sommeri.less4j.core.compiler.stages;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.github.sommeri.less4j.core.ast.ASTCssNode;
import com.github.sommeri.less4j.core.ast.ASTCssNodeType;
import com.github.sommeri.less4j.core.ast.Body;
import com.github.sommeri.less4j.core.ast.Declaration;
import com.github.sommeri.less4j.core.ast.Expression;
import com.github.sommeri.less4j.core.ast.ListExpression;
import com.github.sommeri.less4j.core.ast.ListExpressionOperator;
import com.github.sommeri.less4j.core.ast.ListExpressionOperator.Operator;
import com.github.sommeri.less4j.core.ast.RuleSet;
import com.github.sommeri.less4j.core.parser.HiddenTokenAwareTree;

/**
* Preconditions:
* 1.) properties names must be interpolated,
* 2.) rulesets bodies must be fully solved.  
*
*/
public class PropertiesMerger {

  private Map<String, Declaration> mergingProperties = new HashMap<String, Declaration>();
  private ASTManipulator manipulator = new ASTManipulator();

  public PropertiesMerger() {
  }

  public void propertiesMerger(ASTCssNode node) {
    switch (node.getType()) {
    case RULE_SET:
      RuleSet ruleset = (RuleSet) node;
      rulesetsBodyPropertiesMerger(ruleset.getBody());
      break;

    case CHARSET_DECLARATION:
    case IMPORT:
      break;

    default:
      mergeKidsProperties(node);
    }

  }

  private void mergeKidsProperties(ASTCssNode node) {
    List<ASTCssNode> childs = new ArrayList<ASTCssNode>(node.getChilds());
    for (ASTCssNode kid : childs) {
      propertiesMerger(kid);
    }
  }

  private void rulesetsBodyPropertiesMerger(Body node) {
    enteringBody(node);

    List<? extends ASTCssNode> childs = node.getChilds();
    for (ASTCssNode kid : childs) {
      switch (kid.getType()) {
      case DECLARATION:
        Declaration declaration = (Declaration) kid;
        if (declaration.isMerging())
          addToPrevious(declaration);
        break;

      default:
        mergeKidsProperties(kid);
        break;
      }
    }

    //leavingRuleset(node);
  }

  private void addToPrevious(Declaration declaration) {
    if (declaration.getExpression() == null)
      return;
    String key = toMergingPropertiesKey(declaration);
    if (mergingProperties.containsKey(key)) {
      Declaration previousDeclaration = mergingProperties.get(key);
      Expression previousExpression = previousDeclaration.getExpression();
     
      ListExpressionOperator.Operator mergeOperator = declaration.getMergeOperator();
      Expression mergedExpression = mergeWithPrevious(declaration.getUnderlyingStructure(), previousExpression, mergeOperator, declaration.getExpression());
     
      previousDeclaration.setExpression(mergedExpression);
      mergedExpression.setParent(previousDeclaration);
      manipulator.removeFromBody(declaration);
    } else {
      mergingProperties.put(key, declaration);
    }
  }

  private Expression mergeWithPrevious(HiddenTokenAwareTree underlying, Expression previousExpression, Operator mergeOperator, Expression expression) {
    if (previousExpression.getType()==ASTCssNodeType.LIST_EXPRESSION) {
      ListExpression list = (ListExpression) previousExpression;
      if (list.getOperator().getOperator()==mergeOperator) {
        list.addExpression(expression);
        return list;
      }
    }
  
    List<Expression> expressions = new ArrayList<Expression>();
    expressions.add(previousExpression);
    expressions.add(expression);
    ListExpression result = new ListExpression(underlying, expressions, new ListExpressionOperator(underlying, mergeOperator));
    result.configureParentToAllChilds();
    return result;
  }

  private String toMergingPropertiesKey(Declaration declaration) {
    String cssPropertyName = declaration.getNameAsString();
    boolean important = declaration.isImportant();
    return cssPropertyName + " " + important;
  }

  private void enteringBody(Body node) {
    mergingProperties = new HashMap<String, Declaration>();
  }
}
TOP

Related Classes of com.github.sommeri.less4j.core.compiler.stages.PropertiesMerger

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.