in lib/parser.dart [2225:2398]
dynamic /* Expression | List<Expression> | ... */ processTerm(
[bool ieFilter = false]) {
var start = _peekToken.span;
Token? t; // token for term's value
dynamic value; // value of term (numeric values)
var unary = '';
switch (_peek()) {
case TokenKind.HASH:
_eat(TokenKind.HASH);
if (!_anyWhiteSpaceBeforePeekToken(TokenKind.HASH)) {
String? hexText;
if (_peekKind(TokenKind.INTEGER)) {
var hexText1 = _peekToken.text;
_next();
// Append identifier only if there's no delimiting whitespace.
if (_peekIdentifier() && _previousToken!.end == _peekToken.start) {
hexText = '$hexText1${identifier().name}';
} else {
hexText = hexText1;
}
} else if (_peekIdentifier()) {
hexText = identifier().name;
}
if (hexText != null) {
return _parseHex(hexText, _makeSpan(start));
}
}
if (isChecked) {
_warning('Expected hex number', _makeSpan(start));
}
// Construct the bad hex value with a #<space>number.
return _parseHex(' ${processTerm().text}', _makeSpan(start));
case TokenKind.INTEGER:
t = _next();
value = int.parse('$unary${t.text}');
break;
case TokenKind.DOUBLE:
t = _next();
value = double.parse('$unary${t.text}');
break;
case TokenKind.SINGLE_QUOTE:
value = processQuotedString(false);
value = "'${_escapeString(value as String, single: true)}'";
return LiteralTerm(value, value, _makeSpan(start));
case TokenKind.DOUBLE_QUOTE:
value = processQuotedString(false);
value = '"${_escapeString(value as String)}"';
return LiteralTerm(value, value, _makeSpan(start));
case TokenKind.LPAREN:
_next();
var group = GroupTerm(_makeSpan(start));
dynamic /* Expression | List<Expression> | ... */ term;
do {
term = processTerm();
if (term != null && term is LiteralTerm) {
group.add(term);
}
} while (term != null &&
!_maybeEat(TokenKind.RPAREN) &&
!isPrematureEndOfFile());
return group;
case TokenKind.LBRACK:
_next();
var term = processTerm();
if (!(term is NumberTerm)) {
_error('Expecting a positive number', _makeSpan(start));
}
_eat(TokenKind.RBRACK);
return ItemTerm(term.value, term.text as String, _makeSpan(start));
case TokenKind.IDENTIFIER:
var nameValue = identifier(); // Snarf up the ident we'll remap, maybe.
if (!ieFilter && _maybeEat(TokenKind.LPAREN)) {
var calc = processCalc(nameValue);
if (calc != null) return calc;
// FUNCTION
return processFunction(nameValue);
}
if (ieFilter) {
if (_maybeEat(TokenKind.COLON) &&
nameValue.name.toLowerCase() == 'progid') {
// IE filter:progid:
return processIEFilter(start);
} else {
// Handle filter:<name> where name is any filter e.g., alpha,
// chroma, Wave, blur, etc.
return processIEFilter(start);
}
}
// TODO(terry): Need to have a list of known identifiers today only
// 'from' is special.
if (nameValue.name == 'from') {
return LiteralTerm(nameValue, nameValue.name, _makeSpan(start));
}
// What kind of identifier is it, named color?
var colorEntry = TokenKind.matchColorName(nameValue.name);
if (colorEntry == null) {
if (isChecked) {
var propName = nameValue.name;
var errMsg = TokenKind.isPredefinedName(propName)
? 'Improper use of property value $propName'
: 'Unknown property value $propName';
_warning(errMsg, _makeSpan(start));
}
return LiteralTerm(nameValue, nameValue.name, _makeSpan(start));
}
// Yes, process the color as an RGB value.
var rgbColor =
TokenKind.decimalToHex(TokenKind.colorValue(colorEntry), 6);
return _parseHex(rgbColor, _makeSpan(start));
case TokenKind.UNICODE_RANGE:
String? first;
String? second;
int firstNumber;
int secondNumber;
_eat(TokenKind.UNICODE_RANGE, unicodeRange: true);
if (_maybeEat(TokenKind.HEX_INTEGER, unicodeRange: true)) {
first = _previousToken!.text;
firstNumber = int.parse('0x$first');
if (firstNumber > MAX_UNICODE) {
_error('unicode range must be less than 10FFFF', _makeSpan(start));
}
if (_maybeEat(TokenKind.MINUS, unicodeRange: true)) {
if (_maybeEat(TokenKind.HEX_INTEGER, unicodeRange: true)) {
second = _previousToken!.text;
secondNumber = int.parse('0x$second');
if (secondNumber > MAX_UNICODE) {
_error(
'unicode range must be less than 10FFFF', _makeSpan(start));
}
if (firstNumber > secondNumber) {
_error('unicode first range can not be greater than last',
_makeSpan(start));
}
}
}
} else if (_maybeEat(TokenKind.HEX_RANGE, unicodeRange: true)) {
first = _previousToken!.text;
}
return UnicodeRangeTerm(first, second, _makeSpan(start));
case TokenKind.AT:
if (messages.options.lessSupport) {
_next();
var expr = processExpr();
if (isChecked && expr.expressions.length > 1) {
_error('only @name for Less syntax', _peekToken.span);
}
var param = expr.expressions[0];
var varUsage =
VarUsage((param as LiteralTerm).text, [], _makeSpan(start));
expr.expressions[0] = varUsage;
return expr.expressions;
}
break;
}
return t != null
? processDimension(t, value as Object, _makeSpan(start))
: null;
}