/*
* 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.common.css.compiler.ast;
import javax.annotation.Nullable;
public class CssComponentNode extends CssAtRuleNode {
/** Indicates how we want to construct the prefix strings for this component. */
public enum PrefixStyle {
/** Means use the name as-is without any transformation. */
LITERAL,
/** Means case-convert the name before use. */
CASE_CONVERT,
}
// Sentinel value used to indicate that the node name should be derived
// from the @provide package name.
public static final String IMPLICIT_NODE_NAME = "$package";
private final CssLiteralNode parentName;
private final PrefixStyle prefixStyle;
/**
* Constructor of a component.
*
* @param name Name of the component
* @param parentName Name of the parent component (may be null)
* @param isAbstract Whether this component is declared abstract
* @param block The body of the component
*/
public CssComponentNode(CssLiteralNode name, @Nullable CssLiteralNode parentName,
boolean isAbstract, PrefixStyle prefixStyle, CssBlockNode block) {
super(isAbstract ? CssAtRuleNode.Type.ABSTRACT_COMPONENT : CssAtRuleNode.Type.COMPONENT,
name,
block);
this.parentName = parentName;
this.prefixStyle = prefixStyle;
}
/**
* Copy constructor.
*
* @param node The node to copy
*/
public CssComponentNode(CssComponentNode node) {
super(node);
this.parentName = node.parentName;
this.prefixStyle = node.prefixStyle;
}
@Override
public CssNode deepCopy() {
return new CssComponentNode(this);
}
public CssLiteralNode getParentName() {
return parentName;
}
public boolean isAbstract() {
return getType() == CssAtRuleNode.Type.ABSTRACT_COMPONENT;
}
@SuppressWarnings("ReferenceEquality")
public boolean isImplicitlyNamed() {
// Test against the exact string instance.
return getName().getValue() == IMPLICIT_NODE_NAME;
}
/** Return how the prefix strings should be handled. */
public PrefixStyle getPrefixStyle() {
return prefixStyle;
}
/**
* For debugging only.
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getType().toString()).append(' ');
if (!isImplicitlyNamed()) {
sb.append(getName().getValue()).append(' ');
}
if (parentName != null) {
sb.append("extends ").append(parentName.getValue()).append(' ');
}
sb.append('{').append(getBlock().toString()).append('}');
return sb.toString();
}
@Override
public CssBlockNode getBlock() {
// This type is ensured by the constructor.
return (CssBlockNode) super.getBlock();
}
}