/* * Copyright 2008 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.common.css.compiler.ast; import com.google.common.collect.Sets; import com.google.common.css.SourceCode; import java.util.Collection; import java.util.LinkedHashSet; import javax.annotation.Nullable; /** * A mutable abstract syntax tree that corresponds to a CSS input file. * * @author oana@google.com (Oana Florescu) */ public class CssTree { /** The root of the tree. */ private final CssRootNode root; /** The source code corresponding to the tree. */ private final SourceCode sourceCode; /** A reference to the collection of ruleset nodes to remove. */ private RulesetNodesToRemove rulesetNodesToRemove; // TODO(oana): Maybe make this part of some generic information we want to // store for the tree. public static class RulesetNodesToRemove { private final LinkedHashSet<CssRulesetNode> rulesetNodes = Sets.newLinkedHashSet(); public void addRulesetNode(CssRulesetNode node) { rulesetNodes.add(node); } public Collection<CssRulesetNode> getRulesetNodes() { return rulesetNodes; } } /** * Constructor of a tree. * * @param sourceCode the source location associated with the tree (probably * the start of the file) * @param root the root node of the tree */ public CssTree(SourceCode sourceCode, CssRootNode root) { this.root = root; this.sourceCode = sourceCode; this.rulesetNodesToRemove = new RulesetNodesToRemove(); } /** * Constructor of a tree. * * @param sourceCode the source location associated with the tree (probably * the start of the file). Can be {@code null}. */ public CssTree(@Nullable SourceCode sourceCode) { this(sourceCode, new CssRootNode()); } /** * Copy constructor. This also copies the ruleset nodes to remove. The * collection of ruleset node to remove can be cleared if it is not desired * without affecting the original tree. * * @param tree the tree to copy. Must not be {@code null}. */ public CssTree(CssTree tree) { root = tree.root.deepCopy(); sourceCode = tree.sourceCode; rulesetNodesToRemove = new RulesetNodesToRemove(); rulesetNodesToRemove.rulesetNodes.addAll( tree.rulesetNodesToRemove.rulesetNodes); } public CssRootNode getRoot() { return root; } public SourceCode getSourceCode() { return sourceCode; } public RulesetNodesToRemove getRulesetNodesToRemove() { return rulesetNodesToRemove; } public void resetRulesetNodesToRemove() { this.rulesetNodesToRemove = new RulesetNodesToRemove(); } public MutatingVisitController getMutatingVisitController() { return new DefaultVisitController(this, true /* allowMutating */); } public VisitController getVisitController() { return new DefaultVisitController(this, false /* allowMutating */); } // TODO(user): Add a method that merges two trees and produces a new one as // a result. This method might belong to a compiler pass. }