org.apache.royale.compiler.internal.css.CSSDocument Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of compiler Show documentation
Show all versions of compiler Show documentation
The Apache Royale Compiler
/*
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.royale.compiler.internal.css;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.TokenStream;
import org.antlr.runtime.tree.CommonTree;
import org.antlr.runtime.tree.CommonTreeNodeStream;
import org.apache.royale.compiler.css.ICSSDocument;
import org.apache.royale.compiler.css.ICSSFontFace;
import org.apache.royale.compiler.css.ICSSNamespaceDefinition;
import org.apache.royale.compiler.css.ICSSRule;
import org.apache.royale.compiler.internal.css.CSSLexer;
import org.apache.royale.compiler.internal.css.CSSParser;
import org.apache.royale.compiler.internal.css.CSSTree;
import org.apache.royale.compiler.problems.ICompilerProblem;
import org.apache.royale.compiler.problems.UnexpectedExceptionProblem;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
/**
* Implementation of a CSS model.
*/
public class CSSDocument extends CSSNodeBase implements ICSSDocument
{
/** The short name for the default namespace is an empty string. */
private static final String DEFAULT_NAMESPACE_SHORT_NAME = "";
/**
* Parse a CSS document into {@link ICSSDocument} model.
*
* @param input ANTLR input stream. The {@code CharStream#getSourceName()}
* must be implemented in order to make source location work.
* @param problems Parsing problems will be aggregated in this collection.
* @return CSS DOM object.
*/
public static CSSDocument parse(final CharStream input, final Collection problems)
{
assert input != null : "CSS input can't be null";
assert problems != null : "Problem collection can't be null";
try
{
// parse and build tree
final CSSLexer lexer = new CSSLexer(input);
final CommonTokenStream tokens = new CommonTokenStream(lexer);
final CSSParser parser = new CSSParser(tokens);
final CSSParser.stylesheet_return stylesheet = parser.stylesheet();
final CommonTree ast = (CommonTree)stylesheet.getTree();
final CommonTreeNodeStream nodes = new CommonTreeNodeStream(ast);
nodes.setTokenStream(tokens);
// walk the tree and build definitions
final CSSTree treeWalker = new CSSTree(nodes);
treeWalker.stylesheet();
problems.addAll(lexer.problems);
problems.addAll(parser.problems);
problems.addAll(treeWalker.problems);
// definition models
return treeWalker.model;
}
catch (RecognitionException e)
{
assert false : "RecognitionException must be collected as ICompilerProblem.";
problems.add(new UnexpectedExceptionProblem(e));
return null;
}
}
/**
* Create a root CSS definition.
*
* @param rules CSS rules
* @param namespaces {@code @namespace} statements
* @param fontFaces {@code @font-face} statements
* @param tree root of the AST
*/
protected CSSDocument(final List rules,
final List namespaces,
final List fontFaces,
final CommonTree tree,
final TokenStream tokenStream)
{
super(tree, tokenStream, CSSModelTreeType.DOCUMENT);
assert rules != null : "Rules can't be null.";
assert namespaces != null : "Namespace definitions can't be null";
assert fontFaces != null : "Font face definitions can't be null";
this.rules = new ImmutableList.Builder().addAll(rules).build();
this.namespaces = new ImmutableList.Builder().addAll(namespaces).build();
this.fontFaces = new ImmutableList.Builder().addAll(fontFaces).build();
Map namespaceMap = new HashMap();
for (CSSNamespaceDefinition namespace : namespaces)
{
final String prefix = namespace.getPrefix();
final String key = prefix != null ? prefix : DEFAULT_NAMESPACE_SHORT_NAME;
namespaceMap.put(key, namespace);
}
this.namespacesLookup = ImmutableMap.copyOf(namespaceMap);
// setup tree
children.add(new CSSTypedNode(CSSModelTreeType.NAMESPACE_LIST, this.namespaces));
children.add(new CSSTypedNode(CSSModelTreeType.FONT_FACE_LIST, this.fontFaces));
children.add(new CSSTypedNode(CSSModelTreeType.RULE_LIST, this.rules));
}
private final ImmutableList rules;
private final ImmutableList namespaces;
private final ImmutableList fontFaces;
private final ImmutableMap namespacesLookup;
@Override
public ImmutableList getRules()
{
return rules;
}
@Override
public ImmutableList getAtNamespaces()
{
return namespaces;
}
@Override
public String toString()
{
return Joiner.on("\n").join(
Joiner.on("\n").join(namespaces),
Joiner.on("\n").join(fontFaces),
Joiner.on("\n").join(rules));
}
@Override
public ImmutableList getFontFaces()
{
return fontFaces;
}
@Override
public ICSSNamespaceDefinition getNamespaceDefinition(String prefix)
{
return namespacesLookup.get(prefix);
}
@Override
public ICSSNamespaceDefinition getDefaultNamespaceDefinition()
{
return namespacesLookup.get(DEFAULT_NAMESPACE_SHORT_NAME);
}
}