Merge branch 'master' into dart-doc-comments
diff --git a/lib/css.dart b/lib/css.dart
index 98c9b2a..f47b4f1 100644
--- a/lib/css.dart
+++ b/lib/css.dart
@@ -59,7 +59,7 @@
   }
 }
 
-_time(String message, callback(), bool printTime) {
+T _time<T>(String message, T Function() callback, bool printTime) {
   if (!printTime) return callback();
   final watch = new Stopwatch();
   watch.start();
diff --git a/lib/parser.dart b/lib/parser.dart
index bd750d9..511f204 100644
--- a/lib/parser.dart
+++ b/lib/parser.dart
@@ -264,7 +264,7 @@
     return _peekToken.kind;
   }
 
-  Token _next({unicodeRange: false}) {
+  Token _next({bool unicodeRange: false}) {
     _previousToken = _peekToken;
     _peekToken = tokenizer.next(unicodeRange: unicodeRange);
     return _previousToken;
@@ -290,7 +290,7 @@
     _previousToken = markedData.previousToken;
   }
 
-  bool _maybeEat(int kind, {unicodeRange: false}) {
+  bool _maybeEat(int kind, {bool unicodeRange: false}) {
     if (_peekToken.kind == kind) {
       _previousToken = _peekToken;
       _peekToken = tokenizer.next(unicodeRange: unicodeRange);
@@ -300,7 +300,7 @@
     }
   }
 
-  void _eat(int kind, {unicodeRange: false}) {
+  void _eat(int kind, {bool unicodeRange: false}) {
     if (!_maybeEat(kind, unicodeRange: unicodeRange)) {
       _errorExpected(TokenKind.kindToString(kind));
     }
@@ -308,7 +308,7 @@
 
   void _errorExpected(String expected) {
     var tok = _next();
-    var message;
+    String message;
     try {
       message = 'expected $expected, but found $tok';
     } catch (e) {
@@ -396,7 +396,7 @@
       start = _peekToken.span;
     }
 
-    var type;
+    Identifier type;
     // Get the media type.
     if (_peekIdentifier()) type = identifier();
 
@@ -472,7 +472,7 @@
   ///                           declarations
   ///                         '}'
   ///     supports:           '@supports' supports_condition group_rule_body
-  processDirective() {
+  Directive processDirective() {
     var start = _peekToken.span;
 
     var tokId = processVariableOrDirective();
@@ -567,7 +567,7 @@
         }
 
         // Any pseudo page?
-        var pseudoPage;
+        Identifier pseudoPage;
         if (_maybeEat(TokenKind.COLON)) {
           if (_peekIdentifier()) {
             pseudoPage = identifier();
@@ -640,7 +640,7 @@
         //       ['from'|'to'|PERCENTAGE] [',' ['from'|'to'|PERCENTAGE] ]* ;
         _next();
 
-        var name;
+        Identifier name;
         if (_peekIdentifier()) {
           name = identifier();
         }
@@ -707,7 +707,7 @@
         // namespace_prefix : IDENT
         _next();
 
-        var prefix;
+        Identifier prefix;
         if (_peekIdentifier()) {
           prefix = identifier();
         }
@@ -792,8 +792,8 @@
 
     _eat(TokenKind.LBRACE);
 
-    List<TreeNode> productions = [];
-    var mixinDirective;
+    var productions = <TreeNode>[];
+    MixinDefinition mixinDirective;
 
     var start = _peekToken.span;
     while (!_maybeEat(TokenKind.END_OF_FILE)) {
@@ -862,7 +862,8 @@
 
   /// Returns a VarDefinitionDirective or VarDefinition if a varaible otherwise
   /// return the token id of a directive or -1 if neither.
-  processVariableOrDirective({bool mixinParameter: false}) {
+  dynamic // VarDefinitionDirective | VarDefinition | int
+      processVariableOrDirective({bool mixinParameter: false}) {
     var start = _peekToken.span;
 
     var tokId = _peek();
@@ -887,7 +888,7 @@
           // Less compatibility:
           //    @name: value;      =>    var-name: value;       (VarDefinition)
           //    property: @name;   =>    property: var(name);   (VarUsage)
-          var name;
+          Identifier name;
           if (_peekIdentifier()) {
             name = identifier();
           }
@@ -1033,7 +1034,7 @@
     while (true) {
       conditions.add(processSupportsConditionInParens());
 
-      var type;
+      ClauseType type;
       var text = _peekToken.text.toLowerCase();
 
       if (text == 'and') {
@@ -1178,7 +1179,8 @@
     if (checkBrace) _eat(TokenKind.LBRACE);
 
     var decls = <TreeNode>[];
-    var dartStyles = []; // List of latest styles exposed to Dart.
+    var dartStyles =
+        <DartStyleExpression>[]; // List of latest styles exposed to Dart.
 
     do {
       var selectorGroup = _nestedSelector();
@@ -1235,8 +1237,9 @@
 
     _eat(TokenKind.LBRACE);
 
-    List<Declaration> decls = [];
-    List dartStyles = []; // List of latest styles exposed to Dart.
+    var decls = <Declaration>[];
+    var dartStyles =
+        <DartStyleExpression>[]; // List of latest styles exposed to Dart.
 
     do {
       switch (_peek()) {
@@ -1367,7 +1370,7 @@
     return selector;
   }
 
-  simpleSelectorSequence(bool forceCombinatorNone) {
+  SimpleSelectorSequence simpleSelectorSequence(bool forceCombinatorNone) {
     var start = _peekToken.span;
     var combinatorType = TokenKind.COMBINATOR_NONE;
     var thisOperator = false;
@@ -1435,6 +1438,7 @@
     if (simpleSel != null) {
       return new SimpleSelectorSequence(simpleSel, span, combinatorType);
     }
+    return null;
   }
 
   /// Simple selector grammar:
@@ -1453,7 +1457,7 @@
   ///        : [ namespace_prefix ]? '*'
   ///     class
   ///        : '.' IDENT
-  simpleSelector() {
+  SimpleSelector simpleSelector() {
     // TODO(terry): Natalie makes a good point parsing of namespace and element
     //              are essentially the same (asterisk or identifier) other
     //              than the error message for element.  Should consolidate the
@@ -1483,7 +1487,7 @@
     }
 
     if (_maybeEat(TokenKind.NAMESPACE)) {
-      var element;
+      TreeNode element;
       switch (_peek()) {
         case TokenKind.ASTERISK:
           // Mark as universal element
@@ -1522,7 +1526,7 @@
   }
 
   /// type_selector | universal | HASH | class | attrib | pseudo
-  simpleSelectorTail() {
+  SimpleSelector simpleSelectorTail() {
     // Check for HASH | class | attrib | pseudo | negation
     var start = _peekToken.span;
     switch (_peek()) {
@@ -1569,9 +1573,10 @@
         _next();
         break;
     }
+    return null;
   }
 
-  processPseudoSelector(FileSpan start) {
+  SimpleSelector processPseudoSelector(FileSpan start) {
     // :pseudo-class ::pseudo-element
     // TODO(terry): '::' should be token.
     _eat(TokenKind.COLON);
@@ -1580,7 +1585,7 @@
     // TODO(terry): If no identifier specified consider optimizing out the
     //              : or :: and making this a normal selector.  For now,
     //              create an empty pseudoName.
-    var pseudoName;
+    Identifier pseudoName;
     if (_peekIdentifier()) {
       pseudoName = identifier();
     } else {
@@ -1625,15 +1630,15 @@
 
         // Used during selector look-a-head if not a SelectorExpression is
         // bad.
-        if (expr is! SelectorExpression) {
+        if (expr is SelectorExpression) {
+          _eat(TokenKind.RPAREN);
+          return (pseudoElement)
+              ? new PseudoElementFunctionSelector(pseudoName, expr, span)
+              : new PseudoClassFunctionSelector(pseudoName, expr, span);
+        } else {
           _errorExpected("CSS expression");
           return null;
         }
-
-        _eat(TokenKind.RPAREN);
-        return (pseudoElement)
-            ? new PseudoElementFunctionSelector(pseudoName, expr, span)
-            : new PseudoClassFunctionSelector(pseudoName, expr, span);
       }
     }
 
@@ -1653,7 +1658,7 @@
   ///     PLUS              '+'
   ///     DIMENSION         {num}{ident}
   ///     NUMBER            {num}
-  processSelectorExpression() {
+  TreeNode /* SelectorExpression | LiteralTerm */ processSelectorExpression() {
     var start = _peekToken.span;
 
     var expressions = <Expression>[];
@@ -1698,7 +1703,7 @@
       }
 
       if (keepParsing && value != null) {
-        var unitTerm;
+        LiteralTerm unitTerm;
         // Don't process the dimension if MINUS or PLUS is next.
         if (_peek() != TokenKind.MINUS && _peek() != TokenKind.PLUS) {
           unitTerm = processDimension(termToken, value, _makeSpan(start));
@@ -1786,7 +1791,7 @@
   //   property: expr prio? \9; - IE8 and below property, /9 before semi-colon
   //   *IDENT                   - IE7 or below
   //   _IDENT                   - IE6 property (automatically a valid ident)
-  Declaration processDeclaration(List dartStyles) {
+  Declaration processDeclaration(List<DartStyleExpression> dartStyles) {
     Declaration decl;
 
     var start = _peekToken.span;
@@ -1817,7 +1822,7 @@
           important: importantPriority, ie7: ie7);
     } else if (_peekToken.kind == TokenKind.VAR_DEFINITION) {
       _next();
-      var definedName;
+      Identifier definedName;
       if (_peekIdentifier()) definedName = identifier();
 
       _eat(TokenKind.COLON);
@@ -1926,8 +1931,8 @@
 
   static int _findStyle(String styleName) => _stylesToDart[styleName];
 
-  DartStyleExpression _styleForDart(
-      Identifier property, Expressions exprs, List dartStyles) {
+  DartStyleExpression _styleForDart(Identifier property, Expressions exprs,
+      List<DartStyleExpression> dartStyles) {
     var styleType = _findStyle(property.name.toLowerCase());
     if (styleType != null) {
       return buildDartStyleNode(styleType, exprs, dartStyles);
@@ -1935,7 +1940,8 @@
     return null;
   }
 
-  FontExpression _mergeFontStyles(FontExpression fontExpr, List dartStyles) {
+  FontExpression _mergeFontStyles(
+      FontExpression fontExpr, List<DartStyleExpression> dartStyles) {
     // Merge all font styles for this class selector.
     for (var dartStyle in dartStyles) {
       if (dartStyle.isFont) {
@@ -1947,7 +1953,7 @@
   }
 
   DartStyleExpression buildDartStyleNode(
-      int styleType, Expressions exprs, List dartStyles) {
+      int styleType, Expressions exprs, List<DartStyleExpression> dartStyles) {
     switch (styleType) {
       // Properties in order:
       //
@@ -2173,10 +2179,13 @@
   }
 
   // TODO(terry): Need to handle auto.
-  marginValue(var exprTerm) {
-    if (exprTerm is UnitTerm || exprTerm is NumberTerm) {
-      return exprTerm.value;
+  num marginValue(Expression exprTerm) {
+    if (exprTerm is UnitTerm) {
+      return exprTerm.value as num;
+    } else if (exprTerm is NumberTerm) {
+      return exprTerm.value as num;
     }
+    return null;
   }
 
   //  Expression grammar:
@@ -2192,7 +2201,7 @@
     var keepGoing = true;
     var expr;
     while (keepGoing && (expr = processTerm(ieFilter)) != null) {
-      var op;
+      Expression op;
 
       var opStart = _peekToken.span;
 
@@ -2223,10 +2232,10 @@
       }
 
       if (expr != null) {
-        if (expr is List) {
-          expr.forEach((exprItem) {
+        if (expr is List<Expression>) {
+          for (var exprItem in expr) {
             expressions.add(exprItem);
-          });
+          }
         } else {
           expressions.add(expr);
         }
@@ -2270,7 +2279,8 @@
   //     FREQ:         {num}['hz' | 'khz']
   //     function:     IDENT '(' expr ')'
   //
-  processTerm([bool ieFilter = false]) {
+  dynamic /* Expression | List<Expression> | ... */ processTerm(
+      [bool ieFilter = false]) {
     var start = _peekToken.span;
     Token t; // token for term's value
     var value; // value of term (numeric values)
@@ -2324,7 +2334,7 @@
 
         GroupTerm group = new GroupTerm(_makeSpan(start));
 
-        var term;
+        dynamic /* Expression | List<Expression> | ... */ term;
         do {
           term = processTerm();
           if (term != null && term is LiteralTerm) {
@@ -2391,10 +2401,10 @@
             TokenKind.decimalToHex(TokenKind.colorValue(colorEntry), 6);
         return _parseHex(rgbColor, _makeSpan(start));
       case TokenKind.UNICODE_RANGE:
-        var first;
-        var second;
-        var firstNumber;
-        var secondNumber;
+        String first;
+        String second;
+        int firstNumber;
+        int secondNumber;
         _eat(TokenKind.UNICODE_RANGE, unicodeRange: true);
         if (_maybeEat(TokenKind.HEX_INTEGER, unicodeRange: true)) {
           first = _previousToken.text;
@@ -2673,7 +2683,7 @@
   //
   //  function:     IDENT '(' expr ')'
   //
-  processFunction(Identifier func) {
+  TreeNode /* LiteralTerm | Expression */ processFunction(Identifier func) {
     var start = _peekToken.span;
     var name = func.name;
 
diff --git a/lib/src/css_printer.dart b/lib/src/css_printer.dart
index 7fec014..a8d5b4a 100644
--- a/lib/src/css_printer.dart
+++ b/lib/src/css_printer.dart
@@ -417,7 +417,7 @@
   }
 
   void visitHexColorTerm(HexColorTerm node) {
-    var mappedName;
+    String mappedName;
     if (_isTesting && (node.value is! BAD_HEX_VALUE)) {
       mappedName = TokenKind.hexToColorName(node.value);
     }
diff --git a/lib/src/tokenizer.dart b/lib/src/tokenizer.dart
index f5f4fbd..a4ca215 100644
--- a/lib/src/tokenizer.dart
+++ b/lib/src/tokenizer.dart
@@ -13,12 +13,12 @@
   final QUESTION_MARK = '?'.codeUnitAt(0);
 
   /// CDATA keyword.
-  final List CDATA_NAME = 'CDATA'.codeUnits;
+  final List<int> CDATA_NAME = 'CDATA'.codeUnits;
 
   Tokenizer(SourceFile file, String text, bool skipWhitespace, [int index = 0])
       : super(file, text, skipWhitespace, index);
 
-  Token next({unicodeRange: false}) {
+  Token next({bool unicodeRange: false}) {
     // keep track of our starting position
     _startIndex = _index;
 
diff --git a/lib/src/tree.dart b/lib/src/tree.dart
index 11d15a9..41ea62b 100644
--- a/lib/src/tree.dart
+++ b/lib/src/tree.dart
@@ -511,7 +511,7 @@
   SupportsConjunction(this.conditions, SourceSpan span) : super(span);
 
   SupportsConjunction clone() {
-    var clonedConditions = <SupportsCondition>[];
+    var clonedConditions = <SupportsConditionInParens>[];
     for (var condition in conditions) {
       clonedConditions.add(condition.clone());
     }
@@ -527,7 +527,7 @@
   SupportsDisjunction(this.conditions, SourceSpan span) : super(span);
 
   SupportsDisjunction clone() {
-    var clonedConditions = <SupportsCondition>[];
+    var clonedConditions = <SupportsConditionInParens>[];
     for (var condition in conditions) {
       clonedConditions.add(condition.clone());
     }
@@ -900,9 +900,10 @@
 class Declaration extends TreeNode {
   final Identifier _property;
   final Expression _expression;
+<<<<<<< HEAD
 
   /// Style exposed to Dart.
-  dynamic dartStyle;
+  DartStyleExpression dartStyle;
   final bool important;
 
   /// IE CSS hacks that can only be read by a particular IE version.
@@ -915,7 +916,7 @@
   final bool isIE7;
 
   Declaration(this._property, this._expression, this.dartStyle, SourceSpan span,
-      {important: false, ie7: false})
+      {bool important: false, bool ie7: false})
       : this.important = important,
         this.isIE7 = ie7,
         super(span);
@@ -1275,7 +1276,7 @@
 }
 
 class ItemTerm extends NumberTerm {
-  ItemTerm(var value, String t, SourceSpan span) : super(value, t, span);
+  ItemTerm(dynamic value, String t, SourceSpan span) : super(value, t, span);
 
   ItemTerm clone() => new ItemTerm(value, text, span);
   visit(VisitorBase visitor) => visitor.visitItemTerm(this);
@@ -1363,14 +1364,14 @@
   // TODO(terry): Only px/pt for now need to handle all possible units to
   //              support calc expressions on units.
   FontExpression(SourceSpan span,
-      {dynamic size,
+      {Object /* LengthTerm | num */ size,
       List<String> family,
       int weight,
       String style,
       String variant,
       LineHeight lineHeight})
       : font = new Font(
-            size: size is LengthTerm ? size.value : size,
+            size: size is LengthTerm ? size.value : size as num,
             family: family,
             weight: weight,
             style: style,