| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | |
| 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. | |
| 4 | |
| 5 /** | |
| 6 * A keyword in the Dart programming language. | |
| 7 */ | |
| 8 class Keyword implements SourceString { | |
| 9 static final Keyword BREAK = const Keyword("break"); | |
| 10 static final Keyword CASE = const Keyword("case"); | |
| 11 static final Keyword CATCH = const Keyword("catch"); | |
| 12 static final Keyword CLASS = const Keyword("class"); | |
| 13 static final Keyword CONST = const Keyword("const"); | |
| 14 static final Keyword CONTINUE = const Keyword("continue"); | |
| 15 static final Keyword DEFAULT = const Keyword("default"); | |
| 16 static final Keyword DO = const Keyword("do"); | |
| 17 static final Keyword ELSE = const Keyword("else"); | |
| 18 static final Keyword EXTENDS = const Keyword("extends"); | |
| 19 static final Keyword FALSE = const Keyword("false"); | |
| 20 static final Keyword FINAL = const Keyword("final"); | |
| 21 static final Keyword FINALLY = const Keyword("finally"); | |
| 22 static final Keyword FOR = const Keyword("for"); | |
| 23 static final Keyword IF = const Keyword("if"); | |
| 24 static final Keyword IN = const Keyword("in"); | |
| 25 static final Keyword IS = const Keyword("is", info: IS_INFO); | |
| 26 static final Keyword NEW = const Keyword("new"); | |
| 27 static final Keyword NULL = const Keyword("null"); | |
| 28 static final Keyword RETURN = const Keyword("return"); | |
| 29 static final Keyword SUPER = const Keyword("super"); | |
| 30 static final Keyword SWITCH = const Keyword("switch"); | |
| 31 static final Keyword THIS = const Keyword("this"); | |
| 32 static final Keyword THROW = const Keyword("throw"); | |
| 33 static final Keyword TRUE = const Keyword("true"); | |
| 34 static final Keyword TRY = const Keyword("try"); | |
| 35 static final Keyword VAR = const Keyword("var"); | |
| 36 static final Keyword VOID = const Keyword("void"); | |
| 37 static final Keyword WHILE = const Keyword("while"); | |
| 38 | |
| 39 // Pseudo keywords: | |
| 40 static final Keyword ABSTRACT = const Keyword("abstract", isPseudo: true); | |
| 41 static final Keyword ASSERT = const Keyword("assert", isPseudo: true); | |
| 42 static final Keyword FACTORY = const Keyword("factory", isPseudo: true); | |
| 43 static final Keyword GET = const Keyword("get", isPseudo: true); | |
| 44 static final Keyword IMPLEMENTS = const Keyword("implements", isPseudo: true); | |
| 45 static final Keyword IMPORT = const Keyword("import", isPseudo: true); | |
| 46 static final Keyword INTERFACE = const Keyword("interface", isPseudo: true); | |
| 47 static final Keyword LIBRARY = const Keyword("library", isPseudo: true); | |
| 48 static final Keyword NATIVE = const Keyword("native", isPseudo: true); | |
| 49 static final Keyword NEGATE = const Keyword("negate", isPseudo: true); | |
| 50 static final Keyword OPERATOR = const Keyword("operator", isPseudo: true); | |
| 51 static final Keyword SET = const Keyword("set", isPseudo: true); | |
| 52 static final Keyword SOURCE = const Keyword("source", isPseudo: true); | |
| 53 static final Keyword STATIC = const Keyword("static", isPseudo: true); | |
| 54 static final Keyword TYPEDEF = const Keyword("typedef", isPseudo: true); | |
| 55 | |
| 56 static final List<Keyword> values = const <Keyword> [ | |
| 57 BREAK, | |
| 58 CASE, | |
| 59 CATCH, | |
| 60 CONST, | |
| 61 CONTINUE, | |
| 62 DEFAULT, | |
| 63 DO, | |
| 64 ELSE, | |
| 65 FALSE, | |
| 66 FINAL, | |
| 67 FINALLY, | |
| 68 FOR, | |
| 69 IF, | |
| 70 IN, | |
| 71 IS, | |
| 72 NEW, | |
| 73 NULL, | |
| 74 RETURN, | |
| 75 SUPER, | |
| 76 SWITCH, | |
| 77 THIS, | |
| 78 THROW, | |
| 79 TRUE, | |
| 80 TRY, | |
| 81 VAR, | |
| 82 VOID, | |
| 83 WHILE, | |
| 84 ABSTRACT, | |
| 85 ASSERT, | |
| 86 CLASS, | |
| 87 EXTENDS, | |
| 88 FACTORY, | |
| 89 GET, | |
| 90 IMPLEMENTS, | |
| 91 IMPORT, | |
| 92 INTERFACE, | |
| 93 LIBRARY, | |
| 94 NATIVE, | |
| 95 NEGATE, | |
| 96 OPERATOR, | |
| 97 SET, | |
| 98 SOURCE, | |
| 99 STATIC, | |
| 100 TYPEDEF ]; | |
| 101 | |
| 102 final String syntax; | |
| 103 final bool isPseudo; | |
| 104 final PrecedenceInfo info; | |
| 105 | |
| 106 static Map<String, Keyword> _keywords; | |
| 107 static Map<String, Keyword> get keywords() { | |
| 108 if (_keywords === null) { | |
| 109 _keywords = computeKeywordMap(); | |
| 110 } | |
| 111 return _keywords; | |
| 112 } | |
| 113 | |
| 114 const Keyword(String this.syntax, | |
| 115 [bool this.isPseudo = false, | |
| 116 PrecedenceInfo this.info = KEYWORD_INFO]); | |
| 117 | |
| 118 static Map<String, Keyword> computeKeywordMap() { | |
| 119 Map<String, Keyword> result = new LinkedHashMap<String, Keyword>(); | |
| 120 for (Keyword keyword in values) { | |
| 121 result[keyword.syntax] = keyword; | |
| 122 } | |
| 123 return result; | |
| 124 } | |
| 125 | |
| 126 int hashCode() => syntax.hashCode(); | |
| 127 | |
| 128 bool operator ==(other) { | |
| 129 return other is SourceString && toString() == other.slowToString(); | |
| 130 } | |
| 131 | |
| 132 Iterator<int> iterator() => new StringCodeIterator(syntax); | |
| 133 | |
| 134 void printOn(StringBuffer sb) { | |
| 135 sb.add(syntax); | |
| 136 } | |
| 137 | |
| 138 String toString() => syntax; | |
| 139 String slowToString() => syntax; | |
| 140 String get stringValue() => syntax; | |
| 141 | |
| 142 bool isEmpty() => false; | |
| 143 bool isPrivate() => false; | |
| 144 } | |
| 145 | |
| 146 /** | |
| 147 * Abstract state in a state machine for scanning keywords. | |
| 148 */ | |
| 149 class KeywordState { | |
| 150 abstract bool isLeaf(); | |
| 151 abstract KeywordState next(int c); | |
| 152 abstract Keyword get keyword(); | |
| 153 | |
| 154 static KeywordState _KEYWORD_STATE; | |
| 155 static KeywordState get KEYWORD_STATE() { | |
| 156 if (_KEYWORD_STATE === null) { | |
| 157 List<String> strings = new List<String>(Keyword.values.length); | |
| 158 for (int i = 0; i < Keyword.values.length; i++) { | |
| 159 strings[i] = Keyword.values[i].syntax; | |
| 160 } | |
| 161 strings.sort((a,b) => a.compareTo(b)); | |
| 162 _KEYWORD_STATE = computeKeywordStateTable(0, strings, 0, strings.length); | |
| 163 } | |
| 164 return _KEYWORD_STATE; | |
| 165 } | |
| 166 | |
| 167 static KeywordState computeKeywordStateTable(int start, List<String> strings, | |
| 168 int offset, int length) { | |
| 169 List<KeywordState> result = new List<KeywordState>(26); | |
| 170 assert(length != 0); | |
| 171 int chunk = 0; | |
| 172 int chunkStart = -1; | |
| 173 bool isLeaf = false; | |
| 174 for (int i = offset; i < offset + length; i++) { | |
| 175 if (strings[i].length == start) { | |
| 176 isLeaf = true; | |
| 177 } | |
| 178 if (strings[i].length > start) { | |
| 179 int c = strings[i].charCodeAt(start); | |
| 180 if (chunk != c) { | |
| 181 if (chunkStart != -1) { | |
| 182 assert(result[chunk - $a] === null); | |
| 183 result[chunk - $a] = computeKeywordStateTable(start + 1, strings, | |
| 184 chunkStart, | |
| 185 i - chunkStart); | |
| 186 } | |
| 187 chunkStart = i; | |
| 188 chunk = c; | |
| 189 } | |
| 190 } | |
| 191 } | |
| 192 if (chunkStart != -1) { | |
| 193 assert(result[chunk - $a] === null); | |
| 194 result[chunk - $a] = | |
| 195 computeKeywordStateTable(start + 1, strings, chunkStart, | |
| 196 offset + length - chunkStart); | |
| 197 } else { | |
| 198 assert(length == 1); | |
| 199 return new LeafKeywordState(strings[offset]); | |
| 200 } | |
| 201 if (isLeaf) { | |
| 202 return new ArrayKeywordState(result, strings[offset]); | |
| 203 } else { | |
| 204 return new ArrayKeywordState(result, null); | |
| 205 } | |
| 206 } | |
| 207 } | |
| 208 | |
| 209 /** | |
| 210 * A state with multiple outgoing transitions. | |
| 211 */ | |
| 212 class ArrayKeywordState extends KeywordState { | |
| 213 final List<KeywordState> table; | |
| 214 final Keyword keyword; | |
| 215 | |
| 216 ArrayKeywordState(List<KeywordState> this.table, String syntax) | |
| 217 : keyword = (syntax === null) ? null : Keyword.keywords[syntax]; | |
| 218 | |
| 219 bool isLeaf() => false; | |
| 220 | |
| 221 KeywordState next(int c) => table[c - $a]; | |
| 222 | |
| 223 String toString() { | |
| 224 StringBuffer sb = new StringBuffer(); | |
| 225 sb.add("["); | |
| 226 if (keyword !== null) { | |
| 227 sb.add("*"); | |
| 228 sb.add(keyword); | |
| 229 sb.add(" "); | |
| 230 } | |
| 231 List<KeywordState> foo = table; | |
| 232 for (int i = 0; i < foo.length; i++) { | |
| 233 if (foo[i] != null) { | |
| 234 sb.add("${new String.fromCharCodes([i + $a])}: ${foo[i]}; "); | |
| 235 } | |
| 236 } | |
| 237 sb.add("]"); | |
| 238 return sb.toString(); | |
| 239 } | |
| 240 } | |
| 241 | |
| 242 /** | |
| 243 * A state that has no outgoing transitions. | |
| 244 */ | |
| 245 class LeafKeywordState extends KeywordState { | |
| 246 final Keyword keyword; | |
| 247 | |
| 248 LeafKeywordState(String syntax) : keyword = Keyword.keywords[syntax]; | |
| 249 | |
| 250 bool isLeaf() => true; | |
| 251 | |
| 252 KeywordState next(int c) => null; | |
| 253 | |
| 254 String toString() => keyword.syntax; | |
| 255 } | |
| OLD | NEW |