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

Source Code of com.github.sommeri.less4j.core.compiler.expressions.StringFunctions

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

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

import com.github.sommeri.less4j.core.ast.ASTCssNodeType;
import com.github.sommeri.less4j.core.ast.ColorExpression;
import com.github.sommeri.less4j.core.ast.CssString;
import com.github.sommeri.less4j.core.ast.EscapedValue;
import com.github.sommeri.less4j.core.ast.Expression;
import com.github.sommeri.less4j.core.ast.FaultyExpression;
import com.github.sommeri.less4j.core.ast.FunctionExpression;
import com.github.sommeri.less4j.core.ast.IdentifierExpression;
import com.github.sommeri.less4j.core.ast.NumberExpression;
import com.github.sommeri.less4j.core.compiler.expressions.strings.StringFormatter;
import com.github.sommeri.less4j.core.parser.HiddenTokenAwareTree;
import com.github.sommeri.less4j.core.problems.ProblemsHandler;
import com.github.sommeri.less4j.js.JsRegExp;
import com.github.sommeri.less4j.utils.InStringCssPrinter;
import com.github.sommeri.less4j.utils.PrintUtils;

public class StringFunctions extends BuiltInFunctionsPack {

  protected static final String ESCAPE = "escape";
  protected static final String E = "e";
  protected static final String FORMAT = "%";
  protected static final String REPLACE = "replace";

  private static Map<String, Function> FUNCTIONS = new HashMap<String, Function>();
  static {
    FUNCTIONS.put(ESCAPE, new Escape());
    FUNCTIONS.put(E, new E());
    FUNCTIONS.put(FORMAT, new Format());
    FUNCTIONS.put(REPLACE, new Replace());
  }

  public StringFunctions(ProblemsHandler problemsHandler) {
    super(problemsHandler);
  }

  @Override
  protected Map<String, Function> getFunctions() {
    return FUNCTIONS;
  }

}

class E extends AbstractFunction {

  @Override
  public Expression evaluate(List<Expression> parameters, ProblemsHandler problemsHandler, FunctionExpression call, Expression evaluatedParameter) {
    if (parameters.size() > 1)
      problemsHandler.wrongNumberOfArgumentsToFunctionMin(call.getParameter(), call.getName(), 1);

    Expression parameter = parameters.get(0);
    if (parameter.getType() == ASTCssNodeType.STRING_EXPRESSION)
      return evaluate((CssString) parameter);

    if (parameter.getType() == ASTCssNodeType.ESCAPED_VALUE)
      return evaluate((EscapedValue) parameter);

    if (parameter.getType() == ASTCssNodeType.NUMBER)
      return evaluate((NumberExpression) parameter);

    problemsHandler.warnEFunctionArgument(parameter);

    return new FaultyExpression(call.getParameter());
  }

  private Expression evaluate(NumberExpression parameters) {
    InStringCssPrinter printer = new InStringCssPrinter();
    printer.append(parameters);
    return new CssString(parameters.getUnderlyingStructure(), printer.toString(), "");
  }

  private Expression evaluate(EscapedValue parameters) {
    return parameters;
  }

  private CssString evaluate(CssString parameters) {
    return new CssString(parameters.getUnderlyingStructure(), parameters.getValue(), "");
  }

}

class Escape extends AbstractFunction {

  @Override
  public Expression evaluate(List<Expression> parameters, ProblemsHandler problemsHandler, FunctionExpression call, Expression evaluatedParameter) {
    if (parameters.size() > 1)
      problemsHandler.wrongNumberOfArgumentsToFunctionMax(call.getParameter(), call.getName(), 1);

    Expression parameter = parameters.get(0);
    if (parameter.getType() == ASTCssNodeType.STRING_EXPRESSION)
      return evaluate((CssString) parameter);

    if (parameter.getType() == ASTCssNodeType.ESCAPED_VALUE)
      return evaluate((EscapedValue) parameter);

    problemsHandler.warnEscapeFunctionArgument(call.getParameter());

    if (parameter.getType() == ASTCssNodeType.COLOR_EXPRESSION)
      return evaluate((ColorExpression) parameter);

    return call.getParameter();
  }

  private Expression evaluate(ColorExpression parameters) {
    return new CssString(parameters.getUnderlyingStructure(), "undefined", "");
  }

  private CssString evaluate(EscapedValue parameters) {
    String newValue = PrintUtils.toUtf8ExceptURL(parameters.getValue());
    return new CssString(parameters.getUnderlyingStructure(), newValue, "");
  }

  private CssString evaluate(CssString parameters) {
    String newValue = PrintUtils.toUtf8ExceptURL(parameters.getValue());
    return new CssString(parameters.getUnderlyingStructure(), newValue, "");
  }

}

class Format extends AbstractFunction {

  @Override
  public Expression evaluate(List<Expression> parameters, ProblemsHandler problemsHandler, FunctionExpression call, Expression evaluatedParameter) {
    if (parameters.isEmpty())
      problemsHandler.errFormatWrongFirstParameter(call.getParameter());

    Expression format = parameters.get(0);
    if (format.getType() == ASTCssNodeType.STRING_EXPRESSION)
      return evaluate((CssString) format, parameters.subList(1, parameters.size()), problemsHandler, call.getUnderlyingStructure());

    if (format.getType() == ASTCssNodeType.ESCAPED_VALUE)
      return evaluate((EscapedValue) format, parameters.subList(1, parameters.size()), problemsHandler, call.getUnderlyingStructure());

    if (!format.isFaulty())
      problemsHandler.errFormatWrongFirstParameter(call.getParameter());

    return new FaultyExpression(call);
  }

  private Expression evaluate(EscapedValue format, List<Expression> parameters, ProblemsHandler problemsHandler, HiddenTokenAwareTree technicalUnderlying) {
    String newValue = format(format.getValue(), parameters, problemsHandler, technicalUnderlying);
    return new CssString(format.getUnderlyingStructure(), newValue, "\"");
  }

  private Expression evaluate(CssString format, List<Expression> parameters, ProblemsHandler problemsHandler, HiddenTokenAwareTree technicalUnderlying) {
    String newValue = format(format.getValue(), parameters, problemsHandler, technicalUnderlying);
    return new CssString(format.getUnderlyingStructure(), newValue, "\"");
  }

  private String format(String value, List<Expression> parameters, ProblemsHandler problemsHandler, HiddenTokenAwareTree technicalUnderlying) {
    StringFormatter formatter = new StringFormatter(problemsHandler);
    return formatter.replaceIn(value, parameters.iterator(), technicalUnderlying);
  }

}

class Replace extends AbstractMultiParameterFunction {

  private TypesConversionUtils conversions = new TypesConversionUtils();

  @Override
  public Expression evaluate(List<Expression> parameters, ProblemsHandler problemsHandler, FunctionExpression call, Expression evaluatedParameter) {
    Expression targetExpression = parameters.get(0);
    String string = conversions.contentToString(targetExpression);
    String pattern = conversions.contentToString(parameters.get(1));
    String replacement = conversions.contentToString(parameters.get(2));
    String flags = parameters.size() > 3 ? conversions.contentToString(parameters.get(3)) : "";

    Expression replaced = regexp(targetExpression, string, pattern, replacement, flags, problemsHandler, call);
    return replaced;
  }

  private Expression regexp(Expression targetExpression, String string, String pattern, String replacement, String flags, ProblemsHandler problemsHandler, FunctionExpression call) {
    try {
      JsRegExp exp = JsRegExp.compile(pattern, flags);
      String replaced = exp.replace(string, replacement);
      return buildResult(targetExpression, replaced);
    } catch (IllegalArgumentException ex) {
      problemsHandler.regexpFunctionError(call, ex.getMessage());
      return new FaultyExpression(call.getUnderlyingStructure());
    }
  }

  private Expression buildResult(Expression targetExpression, String replaced) {
    HiddenTokenAwareTree token = targetExpression.getUnderlyingStructure();
    switch (targetExpression.getType()) {
    case IDENTIFIER_EXPRESSION:
      return new IdentifierExpression(token, replaced);

    case STRING_EXPRESSION:
      CssString string = (CssString) targetExpression;
      return new CssString(token, replaced, string.getQuoteType());

    case ESCAPED_VALUE:
      return new EscapedValue(token, replaced);

    default:
      return new CssString(token, replaced, "'");
    }
  }

  @Override
  protected int getMinParameters() {
    return 3;
  }

  @Override
  protected int getMaxParameters() {
    return 4;
  }

  @Override
  protected String getName() {
    return StringFunctions.REPLACE;
  }

  @Override
  protected boolean validateParameter(Expression parameter, int position, ProblemsHandler problemsHandler) {
    return conversions.canConvertToString(parameter);
  }

  //  @Override
  //  public Expression evaluate(List<Expression> parameters, ProblemsHandler problemsHandler, FunctionExpression call, Expression evaluatedParameter) {
  //    if (parameters.size()>4)
  //      problemsHandler.wrongNumberOfArgumentsToFunctionMax(call.getParameter(), call.getName(), 4);
  //
  //    if (parameters.size()<3)
  //      problemsHandler.wrongNumberOfArgumentsToFunctionMin(call.getParameter(), call.getName(), 3);
  //  }

}
TOP

Related Classes of com.github.sommeri.less4j.core.compiler.expressions.StringFunctions

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.