| Index: utils/css/parser.dart
|
| diff --git a/utils/css/parser.dart b/utils/css/parser.dart
|
| index 1fea22c21f52d9df58eff1b93afd8409a0bd6201..bb15466a7b8a2bc53fa8985a215cc9c12cd55ce6 100644
|
| --- a/utils/css/parser.dart
|
| +++ b/utils/css/parser.dart
|
| @@ -10,11 +10,15 @@ class Parser {
|
| var _fs; // If non-null filesystem to read files.
|
| String _basePath; // Base path of CSS file.
|
|
|
| - final lang.SourceFile source;
|
| + final SourceFile source;
|
| +
|
| + Token _previousToken;
|
| + Token _peekToken;
|
| +
|
| +// Communicating errors back to template parser.
|
| +// TODO(terry): Need a better mechanism (e.g., common World).
|
| + var _erroMsgRedirector;
|
|
|
| - lang.Token _previousToken;
|
| - lang.Token _peekToken;
|
| -
|
| Parser(this.source, [int start = 0, this._fs = null, this._basePath = null]) {
|
| tokenizer = new Tokenizer(source, true, start);
|
| _peekToken = tokenizer.next();
|
| @@ -22,17 +26,38 @@ class Parser {
|
| }
|
|
|
| // Main entry point for parsing an entire CSS file.
|
| - Stylesheet parse() {
|
| - List<lang.Node> productions = [];
|
| + // If nestedCSS is true when we're back at processing directives from top and
|
| + // we encounter a } then stop we're inside of a template e.g.,
|
| + //
|
| + // template ... {
|
| + // css {
|
| + // .item {
|
| + // left: 10px;
|
| + // }
|
| + // }
|
| + // <div>...</div>
|
| + // }
|
| + //
|
| + Stylesheet parse([bool nestedCSS = false, var erroMsgRedirector = null]) {
|
| + // TODO(terry): Hack for migrating CSS errors back to template errors.
|
| + _erroMsgRedirector = erroMsgRedirector;
|
| +
|
| + List<ASTNode> productions = [];
|
|
|
| int start = _peekToken.start;
|
| - while (!_maybeEat(TokenKind.END_OF_FILE)) {
|
| + while (!_maybeEat(TokenKind.END_OF_FILE) &&
|
| + (!nestedCSS && !_peekKind(TokenKind.RBRACE))) {
|
| // TODO(terry): Need to handle charset, import, media and page.
|
| var directive = processDirective();
|
| if (directive != null) {
|
| productions.add(directive);
|
| } else {
|
| - productions.add(processRuleSet());
|
| + RuleSet ruleset = processRuleSet();
|
| + if (ruleset != null) {
|
| + productions.add(ruleset);
|
| + } else {
|
| + break;
|
| + }
|
| }
|
| }
|
|
|
| @@ -64,7 +89,7 @@ class Parser {
|
| return _peekToken.kind;
|
| }
|
|
|
| - lang.Token _next() {
|
| + Token _next() {
|
| _previousToken = _peekToken;
|
| _peekToken = tokenizer.next();
|
| return _previousToken;
|
| @@ -110,24 +135,32 @@ class Parser {
|
| _error(message, tok.span);
|
| }
|
|
|
| - void _error(String message, [lang.SourceSpan location=null]) {
|
| + void _error(String message, [SourceSpan location=null]) {
|
| if (location === null) {
|
| location = _peekToken.span;
|
| }
|
|
|
| - lang.world.fatal(message, location); // syntax errors are fatal for now
|
| + if (_erroMsgRedirector == null) {
|
| + world.fatal(message, location); // syntax errors are fatal for now
|
| + } else {
|
| + String text = "";
|
| + if (location != null) {
|
| + text = location.toMessageString("");
|
| + }
|
| + _erroMsgRedirector.displayError("CSS error: \r${text}\r${message}");
|
| + }
|
| }
|
|
|
| - void _warning(String message, [lang.SourceSpan location=null]) {
|
| + void _warning(String message, [SourceSpan location=null]) {
|
| if (location === null) {
|
| location = _peekToken.span;
|
| }
|
|
|
| - lang.world.warning(message, location);
|
| + world.warning(message, location);
|
| }
|
|
|
| - lang.SourceSpan _makeSpan(int start) {
|
| - return new lang.SourceSpan(source, start, _previousToken.end);
|
| + SourceSpan _makeSpan(int start) {
|
| + return new SourceSpan(source, start, _previousToken.end);
|
| }
|
|
|
| ///////////////////////////////////////////////////////////////////
|
| @@ -313,7 +346,7 @@ class Parser {
|
| // Yes, let's parse this file as well.
|
| String fullFN = '${basePath}${filename}';
|
| String contents = _fs.readAll(fullFN);
|
| - Parser parser = new Parser(new lang.SourceFile(fullFN, contents), 0,
|
| + Parser parser = new Parser(new SourceFile(fullFN, contents), 0,
|
| _fs, basePath);
|
| Stylesheet stylesheet = parser.parse();
|
| return new IncludeDirective(filename, stylesheet, _makeSpan(start));
|
| @@ -340,9 +373,9 @@ class Parser {
|
|
|
| _eat(TokenKind.LBRACE);
|
|
|
| - List<lang.Node> productions = [];
|
| + List<ASTNode> productions = [];
|
|
|
| - int start = _peekToken.start;
|
| + start = _peekToken.start;
|
| while (!_maybeEat(TokenKind.END_OF_FILE)) {
|
| RuleSet ruleset = processRuleSet();
|
| if (ruleset == null) {
|
| @@ -360,7 +393,7 @@ class Parser {
|
| }
|
| }
|
|
|
| - processRuleSet() {
|
| + RuleSet processRuleSet() {
|
| int start = _peekToken.start;
|
|
|
| SelectorGroup selGroup = processSelectorGroup();
|
| @@ -698,7 +731,7 @@ class Parser {
|
| //
|
| processTerm() {
|
| int start = _peekToken.start;
|
| - lang.Token t; // token for term's value
|
| + Token t; // token for term's value
|
| var value; // value of term (numeric values)
|
|
|
| var unary = "";
|
| @@ -778,24 +811,27 @@ class Parser {
|
| }
|
|
|
| // What kind of identifier is it?
|
| - int value;
|
| try {
|
| // Named color?
|
| - value = TokenKind.matchColorName(nameValue.name);
|
| + int colorValue = TokenKind.matchColorName(nameValue.name);
|
|
|
| // Yes, process the color as an RGB value.
|
| - String rgbColor = TokenKind.decimalToHex(value);
|
| - int value;
|
| + String rgbColor = TokenKind.decimalToHex(colorValue);
|
| try {
|
| - value = parseHex(rgbColor);
|
| + colorValue = parseHex(rgbColor);
|
| } catch (HexNumberException hne) {
|
| _error('Bad hex number', _makeSpan(start));
|
| }
|
| - return new HexColorTerm(value, rgbColor, _makeSpan(start));
|
| + return new HexColorTerm(colorValue, rgbColor, _makeSpan(start));
|
| } catch (final error) {
|
| if (error is NoColorMatchException) {
|
| // TODO(terry): Other named things to match with validator?
|
| - _warning('Unknown property value ${error.name}', _makeSpan(start));
|
| +
|
| + // TODO(terry): Disable call to _warning need one World class for
|
| + // both CSS parser and other parser (e.g., template)
|
| + // so all warnings, errors, options, etc. are driven
|
| + // from the one World.
|
| +// _warning('Unknown property value ${error.name}', _makeSpan(start));
|
| return new LiteralTerm(nameValue, nameValue.name, _makeSpan(start));
|
| }
|
| }
|
|
|