| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library csslib.parser; | 5 library csslib.parser; |
| 6 | 6 |
| 7 import 'dart:math' as math; | 7 import 'dart:math' as math; |
| 8 | 8 |
| 9 import 'package:source_maps/span.dart' show SourceFile, Span, FileSpan; | 9 import 'package:source_span/source_span.dart'; |
| 10 | 10 |
| 11 import "visitor.dart"; | 11 import "visitor.dart"; |
| 12 import 'src/messages.dart'; | 12 import 'src/messages.dart'; |
| 13 import 'src/options.dart'; | 13 import 'src/options.dart'; |
| 14 | 14 |
| 15 part 'src/analyzer.dart'; | 15 part 'src/analyzer.dart'; |
| 16 part 'src/polyfill.dart'; | 16 part 'src/polyfill.dart'; |
| 17 part 'src/property.dart'; | 17 part 'src/property.dart'; |
| 18 part 'src/token.dart'; | 18 part 'src/token.dart'; |
| 19 part 'src/tokenizer_base.dart'; | 19 part 'src/tokenizer_base.dart'; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 List<StyleSheet> includes: null}) { | 52 List<StyleSheet> includes: null}) { |
| 53 | 53 |
| 54 if (includes == null) { | 54 if (includes == null) { |
| 55 includes = []; | 55 includes = []; |
| 56 } | 56 } |
| 57 | 57 |
| 58 var source = _inputAsString(input); | 58 var source = _inputAsString(input); |
| 59 | 59 |
| 60 _createMessages(errors: errors, options: options); | 60 _createMessages(errors: errors, options: options); |
| 61 | 61 |
| 62 var file = new SourceFile.text(null, source); | 62 var file = new SourceFile(source); |
| 63 | 63 |
| 64 var tree = new _Parser(file, source).parse(); | 64 var tree = new _Parser(file, source).parse(); |
| 65 | 65 |
| 66 analyze([tree], errors: errors, options: options); | 66 analyze([tree], errors: errors, options: options); |
| 67 | 67 |
| 68 if (polyfill) { | 68 if (polyfill) { |
| 69 var processCss = new PolyFill(messages, true); | 69 var processCss = new PolyFill(messages, true); |
| 70 processCss.process(tree, includes: includes); | 70 processCss.process(tree, includes: includes); |
| 71 } | 71 } |
| 72 | 72 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 84 /** | 84 /** |
| 85 * Parse the [input] CSS stylesheet into a tree. The [input] can be a [String], | 85 * Parse the [input] CSS stylesheet into a tree. The [input] can be a [String], |
| 86 * or [List<int>] of bytes and returns a [StyleSheet] AST. The optional | 86 * or [List<int>] of bytes and returns a [StyleSheet] AST. The optional |
| 87 * [errors] list will contain each error/warning as a [Message]. | 87 * [errors] list will contain each error/warning as a [Message]. |
| 88 */ | 88 */ |
| 89 StyleSheet parse(input, {List<Message> errors, List<String> options}) { | 89 StyleSheet parse(input, {List<Message> errors, List<String> options}) { |
| 90 var source = _inputAsString(input); | 90 var source = _inputAsString(input); |
| 91 | 91 |
| 92 _createMessages(errors: errors, options: options); | 92 _createMessages(errors: errors, options: options); |
| 93 | 93 |
| 94 var file = new SourceFile.text(null, source); | 94 var file = new SourceFile(source); |
| 95 return new _Parser(file, source).parse(); | 95 return new _Parser(file, source).parse(); |
| 96 } | 96 } |
| 97 | 97 |
| 98 /** | 98 /** |
| 99 * Parse the [input] CSS selector into a tree. The [input] can be a [String], | 99 * Parse the [input] CSS selector into a tree. The [input] can be a [String], |
| 100 * or [List<int>] of bytes and returns a [StyleSheet] AST. The optional | 100 * or [List<int>] of bytes and returns a [StyleSheet] AST. The optional |
| 101 * [errors] list will contain each error/warning as a [Message]. | 101 * [errors] list will contain each error/warning as a [Message]. |
| 102 */ | 102 */ |
| 103 // TODO(jmesserly): should rename "parseSelector" and return Selector | 103 // TODO(jmesserly): should rename "parseSelector" and return Selector |
| 104 StyleSheet selector(input, {List<Message> errors}) { | 104 StyleSheet selector(input, {List<Message> errors}) { |
| 105 var source = _inputAsString(input); | 105 var source = _inputAsString(input); |
| 106 | 106 |
| 107 _createMessages(errors: errors); | 107 _createMessages(errors: errors); |
| 108 | 108 |
| 109 var file = new SourceFile.text(null, source); | 109 var file = new SourceFile(source); |
| 110 return (new _Parser(file, source) | 110 return (new _Parser(file, source) |
| 111 ..tokenizer.inSelector = true) | 111 ..tokenizer.inSelector = true) |
| 112 .parseSelector(); | 112 .parseSelector(); |
| 113 } | 113 } |
| 114 | 114 |
| 115 SelectorGroup parseSelectorGroup(input, {List<Message> errors}) { | 115 SelectorGroup parseSelectorGroup(input, {List<Message> errors}) { |
| 116 var source = _inputAsString(input); | 116 var source = _inputAsString(input); |
| 117 | 117 |
| 118 _createMessages(errors: errors); | 118 _createMessages(errors: errors); |
| 119 | 119 |
| 120 var file = new SourceFile.text(null, source); | 120 var file = new SourceFile(source); |
| 121 return (new _Parser(file, source) | 121 return (new _Parser(file, source) |
| 122 // TODO(jmesserly): this fix should be applied to the parser. It's tricky | 122 // TODO(jmesserly): this fix should be applied to the parser. It's tricky |
| 123 // because by the time the flag is set one token has already been fetched. | 123 // because by the time the flag is set one token has already been fetched. |
| 124 ..tokenizer.inSelector = true) | 124 ..tokenizer.inSelector = true) |
| 125 .processSelectorGroup(); | 125 .processSelectorGroup(); |
| 126 } | 126 } |
| 127 | 127 |
| 128 String _inputAsString(input) { | 128 String _inputAsString(input) { |
| 129 String source; | 129 String source; |
| 130 | 130 |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 var tok = _next(); | 313 var tok = _next(); |
| 314 var message; | 314 var message; |
| 315 try { | 315 try { |
| 316 message = 'expected $expected, but found $tok'; | 316 message = 'expected $expected, but found $tok'; |
| 317 } catch (e) { | 317 } catch (e) { |
| 318 message = 'parsing error expected $expected'; | 318 message = 'parsing error expected $expected'; |
| 319 } | 319 } |
| 320 _error(message, tok.span); | 320 _error(message, tok.span); |
| 321 } | 321 } |
| 322 | 322 |
| 323 void _error(String message, Span location) { | 323 void _error(String message, SourceSpan location) { |
| 324 if (location == null) { | 324 if (location == null) { |
| 325 location = _peekToken.span; | 325 location = _peekToken.span; |
| 326 } | 326 } |
| 327 messages.error(message, location); | 327 messages.error(message, location); |
| 328 } | 328 } |
| 329 | 329 |
| 330 void _warning(String message, Span location) { | 330 void _warning(String message, SourceSpan location) { |
| 331 if (location == null) { | 331 if (location == null) { |
| 332 location = _peekToken.span; | 332 location = _peekToken.span; |
| 333 } | 333 } |
| 334 messages.warning(message, location); | 334 messages.warning(message, location); |
| 335 } | 335 } |
| 336 | 336 |
| 337 Span _makeSpan(int start) { | 337 SourceSpan _makeSpan(int start) { |
| 338 // TODO(terry): there are places where we are creating spans before we eat | 338 // TODO(terry): there are places where we are creating spans before we eat |
| 339 // the tokens, so using _previousToken.end is not always valid. | 339 // the tokens, so using _previousToken.end is not always valid. |
| 340 var end = _previousToken != null && _previousToken.end >= start | 340 var end = _previousToken != null && _previousToken.end >= start |
| 341 ? _previousToken.end : _peekToken.end; | 341 ? _previousToken.end : _peekToken.end; |
| 342 return file.span(start, end); | 342 return file.span(start, end); |
| 343 } | 343 } |
| 344 | 344 |
| 345 /////////////////////////////////////////////////////////////////// | 345 /////////////////////////////////////////////////////////////////// |
| 346 // Top level productions | 346 // Top level productions |
| 347 /////////////////////////////////////////////////////////////////// | 347 /////////////////////////////////////////////////////////////////// |
| (...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 935 if (_maybeEat(TokenKind.COLON)) { | 935 if (_maybeEat(TokenKind.COLON)) { |
| 936 exprs = processExpr(); | 936 exprs = processExpr(); |
| 937 } | 937 } |
| 938 | 938 |
| 939 return new VarDefinition(definedName, exprs, _makeSpan(start)); | 939 return new VarDefinition(definedName, exprs, _makeSpan(start)); |
| 940 } | 940 } |
| 941 | 941 |
| 942 return tokId; | 942 return tokId; |
| 943 } | 943 } |
| 944 | 944 |
| 945 IncludeDirective processInclude(Span span, {bool eatSemiColon: true}) { | 945 IncludeDirective processInclude(SourceSpan span, {bool eatSemiColon: true}) { |
| 946 /* Stylet grammar: | 946 /* Stylet grammar: |
| 947 * | 947 * |
| 948 * @include IDENT [(args,...)]; | 948 * @include IDENT [(args,...)]; |
| 949 */ | 949 */ |
| 950 _next(); | 950 _next(); |
| 951 | 951 |
| 952 var name; | 952 var name; |
| 953 if (_peekIdentifier()) { | 953 if (_peekIdentifier()) { |
| 954 name = identifier(); | 954 name = identifier(); |
| 955 } | 955 } |
| (...skipping 1320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2276 expr.expressions[0] = varUsage; | 2276 expr.expressions[0] = varUsage; |
| 2277 return expr.expressions; | 2277 return expr.expressions; |
| 2278 } | 2278 } |
| 2279 break; | 2279 break; |
| 2280 } | 2280 } |
| 2281 | 2281 |
| 2282 return processDimension(t, value, _makeSpan(start)); | 2282 return processDimension(t, value, _makeSpan(start)); |
| 2283 } | 2283 } |
| 2284 | 2284 |
| 2285 /** Process all dimension units. */ | 2285 /** Process all dimension units. */ |
| 2286 LiteralTerm processDimension(Token t, var value, Span span) { | 2286 LiteralTerm processDimension(Token t, var value, SourceSpan span) { |
| 2287 LiteralTerm term; | 2287 LiteralTerm term; |
| 2288 var unitType = this._peek(); | 2288 var unitType = this._peek(); |
| 2289 | 2289 |
| 2290 switch (unitType) { | 2290 switch (unitType) { |
| 2291 case TokenKind.UNIT_EM: | 2291 case TokenKind.UNIT_EM: |
| 2292 term = new EmTerm(value, t.text, span); | 2292 term = new EmTerm(value, t.text, span); |
| 2293 _next(); // Skip the unit | 2293 _next(); // Skip the unit |
| 2294 break; | 2294 break; |
| 2295 case TokenKind.UNIT_EX: | 2295 case TokenKind.UNIT_EX: |
| 2296 term = new ExTerm(value, t.text, span); | 2296 term = new ExTerm(value, t.text, span); |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2531 return c - 48; | 2531 return c - 48; |
| 2532 } else if (c >= 97/*a*/ && c <= 102/*f*/) { | 2532 } else if (c >= 97/*a*/ && c <= 102/*f*/) { |
| 2533 return c - 87; | 2533 return c - 87; |
| 2534 } else if (c >= 65/*A*/ && c <= 70/*F*/) { | 2534 } else if (c >= 65/*A*/ && c <= 70/*F*/) { |
| 2535 return c - 55; | 2535 return c - 55; |
| 2536 } else { | 2536 } else { |
| 2537 return -1; | 2537 return -1; |
| 2538 } | 2538 } |
| 2539 } | 2539 } |
| 2540 | 2540 |
| 2541 HexColorTerm _parseHex(String hexText, Span span) { | 2541 HexColorTerm _parseHex(String hexText, SourceSpan span) { |
| 2542 var hexValue = 0; | 2542 var hexValue = 0; |
| 2543 | 2543 |
| 2544 for (var i = 0; i < hexText.length; i++) { | 2544 for (var i = 0; i < hexText.length; i++) { |
| 2545 var digit = _hexDigit(hexText.codeUnitAt(i)); | 2545 var digit = _hexDigit(hexText.codeUnitAt(i)); |
| 2546 if (digit < 0) { | 2546 if (digit < 0) { |
| 2547 _warning('Bad hex number', span); | 2547 _warning('Bad hex number', span); |
| 2548 return new HexColorTerm(new BAD_HEX_VALUE(), hexText, span); | 2548 return new HexColorTerm(new BAD_HEX_VALUE(), hexText, span); |
| 2549 } | 2549 } |
| 2550 hexValue = (hexValue << 4) + digit; | 2550 hexValue = (hexValue << 4) + digit; |
| 2551 } | 2551 } |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2695 | 2695 |
| 2696 if (replace != null && result == null) { | 2696 if (replace != null && result == null) { |
| 2697 result = new StringBuffer(text.substring(0, i)); | 2697 result = new StringBuffer(text.substring(0, i)); |
| 2698 } | 2698 } |
| 2699 | 2699 |
| 2700 if (result != null) result.write(replace != null ? replace : text[i]); | 2700 if (result != null) result.write(replace != null ? replace : text[i]); |
| 2701 } | 2701 } |
| 2702 | 2702 |
| 2703 return result == null ? text : result.toString(); | 2703 return result == null ? text : result.toString(); |
| 2704 } | 2704 } |
| OLD | NEW |