Chromium Code Reviews| Index: sdk/lib/internal/symbol.dart |
| diff --git a/sdk/lib/internal/symbol.dart b/sdk/lib/internal/symbol.dart |
| index 7a0369a9a5686a9b4fb926e632cd3eced29a11cf..1eef13714745a4c3baad7dc53836c41c169cc3a2 100644 |
| --- a/sdk/lib/internal/symbol.dart |
| +++ b/sdk/lib/internal/symbol.dart |
| @@ -15,29 +15,45 @@ part of dart._internal; |
| class Symbol implements core.Symbol { |
| final String _name; |
| - static final RegExp validationPattern = |
| - new RegExp(r'^(?:[a-zA-Z$][a-zA-Z$0-9_]*\.)*(?:[a-zA-Z$][a-zA-Z$0-9_]*=?|' |
| - r'-|' |
| - r'unary-|' |
| - r'\[\]=|' |
| - r'~|' |
| - r'==|' |
| - r'\[\]|' |
| - r'\*|' |
| - r'/|' |
| - r'%|' |
| - r'~/|' |
| - r'\+|' |
| - r'<<|' |
| - r'>>|' |
| - r'>=|' |
| - r'>|' |
| - r'<=|' |
| - r'<|' |
| - r'&|' |
| - r'\^|' |
| - r'\|' |
| - r')$'); |
| + // Reserved words are not allowed as identifiers. |
| + static const String reservedWordRE = |
| + r'(?:assert|break|c(?:a(?:se|tch)|lass|on(?:st|tinue))|d(?:efault|o)|' |
| + r'e(?:lse|num|xtends)|f(?:alse|inal(?:ly)?|or)|i[fns]|n(?:ew|ull)|' |
| + r'ret(?:hrow|urn)|s(?:uper|witch)|t(?:h(?:is|row)|r(?:ue|y))|' |
| + r'v(?:ar|oid)|w(?:hile|ith))'; |
| + // Mathces a public identifier (identifier not starting with '_'). |
| + static const String publicIdentifierRE = |
| + r'(?!' '$reservedWordRE' r'\b(?!\$))[a-zA-Z$][\w$]*'; |
| + // Matches the names of declarable operators. |
| + static const String operatorRE = |
| + r'(?:[\-+*/%&|^]|\[\]=?|==|~/?|<[<=]?|>[>=]?|unary-)'; |
| + |
| + |
|
ahe
2014/02/21 12:52:09
Extra line.
|
| + // Grammar: |
| + // symbol ::= qualifiedName | <empty> |
| + // qualifiedName ::= publicIdentifier '.' qualifiedName | name |
| + // name ::= publicIdentifier |
| + // | publicIdentifier '=' |
| + // | operator |
| + // where publicIdentifier is any valid identifier (not a reserved word) |
| + // that isn't private (doesn't start with '_'). |
| + // |
| + // Railroad diagram of the accepted grammar: |
| + // |
| + // /----------------\ |
| + // | | |
| + // | /-[.]-/ /-[=]-\ |
| + // \ / / \ |
| + // -------[id]-------------------------> |
| + // \ / |
| + // \------[operator]---/ |
| + // \ / |
| + // \------------/ |
| + // |
| + |
| + // Validates non-empty symbol (empty symbol is handled before using this). |
| + static final RegExp validationPattern = new RegExp( |
| + '^(?:$operatorRE\$|$publicIdentifierRE(?:=?\$|[.](?!\$)))+?\$'); |
| external const Symbol(String name); |
| @@ -64,14 +80,14 @@ class Symbol implements core.Symbol { |
| static String getName(Symbol symbol) => symbol._name; |
| static String validate(String name) { |
| - if (name.isEmpty) return name; |
| + if (name.isEmpty || validationPattern.hasMatch(name)) return name; |
| if (name.startsWith('_')) { |
| + // There may be other private parts in a qualified name than the first |
| + // one, but this is a common case that deserves a specific error |
| + // message. |
| throw new ArgumentError('"$name" is a private identifier'); |
| } |
| - if (!validationPattern.hasMatch(name)) { |
| - throw new ArgumentError( |
| - '"$name" is not an identifier or an empty String'); |
| - } |
| - return name; |
| + throw new ArgumentError( |
| + '"$name" is not a valid (qualified) symbol name'); |
| } |
| } |