Package com.google.template.soy.parsepasses

Source Code of com.google.template.soy.parsepasses.HandleCssCommandVisitor

/*
* Copyright 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.google.template.soy.parsepasses;

import com.google.common.collect.Lists;
import com.google.template.soy.base.IdGenerator;
import com.google.template.soy.exprtree.DataRefNode;
import com.google.template.soy.exprtree.ExprNode;
import com.google.template.soy.exprtree.GlobalNode;
import com.google.template.soy.shared.SoyGeneralOptions.CssHandlingScheme;
import com.google.template.soy.soytree.AbstractSoyNodeVisitor;
import com.google.template.soy.soytree.CssNode;
import com.google.template.soy.soytree.PrintDirectiveNode;
import com.google.template.soy.soytree.PrintNode;
import com.google.template.soy.soytree.RawTextNode;
import com.google.template.soy.soytree.SoyFileSetNode;
import com.google.template.soy.soytree.SoyNode;
import com.google.template.soy.soytree.SoyNode.ParentSoyNode;
import com.google.template.soy.soytree.SoyNode.StandaloneNode;
import com.google.template.soy.soytree.SoySyntaxExceptionUtils;

import java.util.List;


/**
* Visitor for handling 'css' commands.
*
* <p> Important: Do not use outside of Soy code (treat as superpackage-private).
*
* <p> {@link #exec} must be called on a full parse tree.
*
* <p> Each scheme is handled as follows:
* (a) LITERAL: Turn each CssNode into a RawTextNode.
* (b) REFERENCE: Turn each CssNode into a PrintNode.
* (c) BACKEND_SPECIFIC: Don't change anything. Let backend handle 'css' commands.
*
* @author Kai Huang
*/
public class HandleCssCommandVisitor extends AbstractSoyNodeVisitor<Void> {


  /** Scheme for handling 'css' commands. */
  private final CssHandlingScheme cssHandlingScheme;

  /** The list of CssNodes found in the tree. */
  private List<CssNode> cssNodes;


  /**
   * @param cssHandlingScheme Scheme for handling 'css' commands.
   */
  public HandleCssCommandVisitor(CssHandlingScheme cssHandlingScheme) {
    this.cssHandlingScheme = cssHandlingScheme;
  }


  @Override public Void exec(SoyNode node) {
    cssNodes = Lists.newArrayList();
    visit(node);
    return null;
  }


  // -----------------------------------------------------------------------------------------------
  // Implementations for specific nodes.


  @Override protected void visitSoyFileSetNode(SoyFileSetNode node) {

    if (cssHandlingScheme == CssHandlingScheme.BACKEND_SPECIFIC) {
      return// leave CssNodes alone to be handled by backend
    }

    // We find all the CssNodes before replacing them because we don't want the modifications to
    // interfere with the traversal.

    // This pass simply finds all the CssNodes.
    visitChildren(node);

    // Perform the replacments.
    IdGenerator nodeIdGen = node.getNearestAncestor(SoyFileSetNode.class).getNodeIdGenerator();
    for (CssNode cssNode : cssNodes) {

      StandaloneNode newNode;

      if (cssHandlingScheme == CssHandlingScheme.LITERAL) {
        newNode = new RawTextNode(nodeIdGen.genId(), cssNode.getCommandText());

      } else if (cssHandlingScheme == CssHandlingScheme.REFERENCE) {
        PrintNode newPrintNode =
            new PrintNode(nodeIdGen.genId(), false, cssNode.getCommandText(), null);
        newPrintNode.addChild(new PrintDirectiveNode(nodeIdGen.genId(), "|noAutoescape", ""));
        newNode = newPrintNode;
        // Check that the expression is a valid reference.
        boolean isInvalidExpr = false;
        if (newPrintNode.getExprUnion().getExpr() == null) {
          isInvalidExpr = true;
        } else {
          ExprNode exprNode = newPrintNode.getExprUnion().getExpr().getChild(0);
          if (! (exprNode instanceof DataRefNode || exprNode instanceof GlobalNode)) {
            isInvalidExpr = true;
          }
        }
        if (isInvalidExpr) {
          throw SoySyntaxExceptionUtils.createWithNode(
              "The css-handling scheme is 'reference', but tag " + cssNode.getTagString() +
                  " does not contain a valid reference.",
              node);
        }

      } else {
        throw new AssertionError();
      }

      cssNode.getParent().replaceChild(cssNode, newNode);
    }
  }


  @Override protected void visitCssNode(CssNode node) {
    cssNodes.add(node);
  }


  // -----------------------------------------------------------------------------------------------
  // Fallback implementation.


  @Override protected void visitSoyNode(SoyNode node) {
    if (node instanceof ParentSoyNode<?>) {
      visitChildren((ParentSoyNode<?>) node);
    }
  }

}
TOP

Related Classes of com.google.template.soy.parsepasses.HandleCssCommandVisitor

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.