Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/js_backend/namer.dart

Issue 12049036: Cleanup the namer, and add a test with fields that used to clash with internal names used by the co… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 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 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 part of js_backend; 5 part of js_backend;
6 6
7 /** 7 /**
8 * Assigns JavaScript identifiers to Dart variables, class-names and members. 8 * Assigns JavaScript identifiers to Dart variables, class-names and members.
9 */ 9 */
10 class Namer implements ClosureNamer { 10 class Namer implements ClosureNamer {
11
12 static const javaScriptKeywords = const <String>[
13 // These are current keywords
kasperl 2013/01/23 14:05:36 Terminate comment with .
ngeoffray 2013/01/23 14:42:04 Done.
14 "break", "delete", "function", "return", "typeof", "case", "do", "if",
15 "switch", "var", "catch", "else", "in", "this", "void", "continue",
16 "false", "instanceof", "throw", "while", "debugger", "finally", "new",
17 "true", "with", "default", "for", "null", "try",
18
19 // These are future keywords
kasperl 2013/01/23 14:05:36 Ditto.
ngeoffray 2013/01/23 14:42:04 Done.
20 "abstract", "double", "goto", "native", "static", "boolean", "enum",
21 "implements", "package", "super", "byte", "export", "import", "private",
22 "synchronized", "char", "extends", "int", "protected", "throws",
23 "class", "final", "interface", "public", "transient", "const", "float",
24 "long", "short", "volatile"
25 ];
26
27 static const reservedPropertySymbols =
28 const <String>["__PROTO__", "prototype", "constructor"];
29
11 static Set<String> _jsReserved = null; 30 static Set<String> _jsReserved = null;
12 Set<String> get jsReserved { 31 Set<String> get jsReserved {
13 if (_jsReserved == null) { 32 if (_jsReserved == null) {
14 _jsReserved = new Set<String>(); 33 _jsReserved = new Set<String>();
15 _jsReserved.addAll(JsNames.javaScriptKeywords); 34 _jsReserved.addAll(javaScriptKeywords);
16 _jsReserved.addAll(JsNames.reservedPropertySymbols); 35 _jsReserved.addAll(reservedPropertySymbols);
17 } 36 }
18 return _jsReserved; 37 return _jsReserved;
19 } 38 }
20 39
21 final String CURRENT_ISOLATE = r'$'; 40 final String CURRENT_ISOLATE = r'$';
22 41
23 /** 42 /**
24 * Map from top-level or static elements to their unique identifiers provided 43 * Map from top-level or static elements to their unique identifiers provided
25 * by [getName]. 44 * by [getName].
26 * 45 *
27 * Invariant: Keys must be declaration elements. 46 * Invariant: Keys must be declaration elements.
28 */ 47 */
29 final Compiler compiler; 48 final Compiler compiler;
30 final Map<Element, String> globals; 49 final Map<Element, String> globals;
31 final Map<String, LibraryElement> shortPrivateNameOwners; 50 final Map<String, LibraryElement> shortPrivateNameOwners;
32 final Set<String> usedGlobalNames; 51 final Set<String> usedGlobalNames;
33 final Set<String> usedInstanceNames; 52 final Set<String> usedInstanceNames;
34 final Map<String, String> globalNameMap; 53 final Map<String, String> globalNameMap;
35 final Map<String, String> instanceNameMap; 54 final Map<String, String> instanceNameMap;
55 final Map<String, String> operatorNameMap;
36 final Map<String, int> popularNameCounters; 56 final Map<String, int> popularNameCounters;
37 57
38 /** 58 /**
39 * A cache of names used for bailout methods. We make sure two 59 * A cache of names used for bailout methods. We make sure two
40 * bailout methods cannot have the same name because if the two 60 * bailout methods cannot have the same name because if the two
41 * bailout methods are in a class and a subclass, we would 61 * bailout methods are in a class and a subclass, we would
42 * call the wrong bailout method at runtime. To make it 62 * call the wrong bailout method at runtime. To make it
43 * simple, we don't keep track of inheritance and always avoid 63 * simple, we don't keep track of inheritance and always avoid
44 * similar names. 64 * similar names.
45 */ 65 */
46 final Set<String> usedBailoutInstanceNames; 66 final Set<String> usedBailoutInstanceNames;
47 final Map<Element, String> bailoutNames; 67 final Map<Element, String> bailoutNames;
48 68
49 final Map<Constant, String> constantNames; 69 final Map<Constant, String> constantNames;
50 70
51 Namer(this.compiler) 71 Namer(this.compiler)
52 : globals = new Map<Element, String>(), 72 : globals = new Map<Element, String>(),
53 shortPrivateNameOwners = new Map<String, LibraryElement>(), 73 shortPrivateNameOwners = new Map<String, LibraryElement>(),
54 bailoutNames = new Map<Element, String>(), 74 bailoutNames = new Map<Element, String>(),
55 usedBailoutInstanceNames = new Set<String>(), 75 usedBailoutInstanceNames = new Set<String>(),
56 usedGlobalNames = new Set<String>(), 76 usedGlobalNames = new Set<String>(),
57 usedInstanceNames = new Set<String>(), 77 usedInstanceNames = new Set<String>(),
58 instanceNameMap = new Map<String, String>(), 78 instanceNameMap = new Map<String, String>(),
79 operatorNameMap = new Map<String, String>(),
59 globalNameMap = new Map<String, String>(), 80 globalNameMap = new Map<String, String>(),
60 constantNames = new Map<Constant, String>(), 81 constantNames = new Map<Constant, String>(),
61 popularNameCounters = new Map<String, int>(); 82 popularNameCounters = new Map<String, int>();
62 83
63 String get isolateName => 'Isolate'; 84 String get isolateName => 'Isolate';
64 String get isolatePropertiesName => r'$isolateProperties'; 85 String get isolatePropertiesName => r'$isolateProperties';
65 /** 86 /**
66 * Some closures must contain their name. The name is stored in 87 * Some closures must contain their name. The name is stored in
67 * [STATIC_CLOSURE_NAME_NAME]. 88 * [STATIC_CLOSURE_NAME_NAME].
68 */ 89 */
(...skipping 17 matching lines...) Expand all
86 // The minifier always constructs a new name, using the argument as 107 // The minifier always constructs a new name, using the argument as
87 // input to its hashing algorithm. The given name does not need to be 108 // input to its hashing algorithm. The given name does not need to be
88 // valid. 109 // valid.
89 longName = stringConstant.value.slowToString(); 110 longName = stringConstant.value.slowToString();
90 } else { 111 } else {
91 longName = "C"; 112 longName = "C";
92 } 113 }
93 } else { 114 } else {
94 longName = "CONSTANT"; 115 longName = "CONSTANT";
95 } 116 }
96 result = getFreshName(longName, usedGlobalNames); 117 result = getFreshName(longName, usedGlobalNames, true);
97 constantNames[constant] = result; 118 constantNames[constant] = result;
98 } 119 }
99 return result; 120 return result;
100 } 121 }
101 122
102 String breakLabelName(LabelElement label) { 123 String breakLabelName(LabelElement label) {
103 return '\$${label.labelName}\$${label.target.nestingLevel}'; 124 return '\$${label.labelName}\$${label.target.nestingLevel}';
104 } 125 }
105 126
106 String implicitBreakLabelName(TargetElement target) { 127 String implicitBreakLabelName(TargetElement target) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 163
143 // If a library name does not start with the [LIBRARY_PREFIX] then our 164 // If a library name does not start with the [LIBRARY_PREFIX] then our
144 // assumptions about clashing with mangled private members do not hold. 165 // assumptions about clashing with mangled private members do not hold.
145 String libraryName = getName(library); 166 String libraryName = getName(library);
146 assert(shouldMinify || libraryName.startsWith(LIBRARY_PREFIX)); 167 assert(shouldMinify || libraryName.startsWith(LIBRARY_PREFIX));
147 // TODO(erikcorry): Fix this with other manglings to avoid clashes. 168 // TODO(erikcorry): Fix this with other manglings to avoid clashes.
148 return '_lib$libraryName\$$nameString'; 169 return '_lib$libraryName\$$nameString';
149 } 170 }
150 171
151 String instanceMethodName(FunctionElement element) { 172 String instanceMethodName(FunctionElement element) {
152 SourceString name = Elements.operatorNameToIdentifier(element.name); 173 SourceString name = operatorNameToIdentifier(element.name);
kasperl 2013/01/23 14:05:36 This pattern where you check if the operatorNameTo
ngeoffray 2013/01/23 14:42:04 Done.
153 LibraryElement library = element.getLibrary(); 174 if (name == element.name) {
154 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY) { 175 LibraryElement library = element.getLibrary();
155 ConstructorBodyElement bodyElement = element; 176 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY) {
156 name = bodyElement.constructor.name; 177 ConstructorBodyElement bodyElement = element;
178 name = bodyElement.constructor.name;
179 }
180 FunctionSignature signature = element.computeSignature(compiler);
181 String methodName =
182 '${privateName(library, name)}\$${signature.parameterCount}';
183 if (signature.optionalParametersAreNamed &&
184 !signature.optionalParameters.isEmpty) {
185 StringBuffer buffer = new StringBuffer();
186 signature.orderedOptionalParameters.forEach((Element element) {
187 buffer.add('\$${safeName(element.name.slowToString())}');
188 });
189 methodName = '$methodName$buffer';
190 }
191 if (name == closureInvocationSelectorName) return methodName;
192 return getMappedInstanceName(methodName);
193 } else {
194 return getMappedOperatorName(name.slowToString());
157 } 195 }
158 FunctionSignature signature = element.computeSignature(compiler);
159 String methodName =
160 '${privateName(library, name)}\$${signature.parameterCount}';
161 if (signature.optionalParametersAreNamed &&
162 !signature.optionalParameters.isEmpty) {
163 StringBuffer buffer = new StringBuffer();
164 signature.orderedOptionalParameters.forEach((Element element) {
165 buffer.add('\$${JsNames.getValid(element.name.slowToString())}');
166 });
167 methodName = '$methodName$buffer';
168 }
169 if (name == closureInvocationSelectorName) return methodName;
170 return getMappedInstanceName(methodName);
171 } 196 }
172 197
173 String publicInstanceMethodNameByArity(SourceString name, int arity) { 198 String publicInstanceMethodNameByArity(SourceString name, int arity) {
174 name = Elements.operatorNameToIdentifier(name); 199 SourceString newName = operatorNameToIdentifier(name);
175 assert(!name.isPrivate()); 200 if (newName == name) {
176 var base = name.slowToString(); 201 assert(!name.isPrivate());
177 // We don't mangle the closure invoking function name because it 202 var base = name.slowToString();
178 // is generated by string concatenation in applyFunction from 203 // We don't mangle the closure invoking function name because it
179 // js_helper.dart. 204 // is generated by string concatenation in applyFunction from
180 var proposedName = '$base\$$arity'; 205 // js_helper.dart.
181 if (name == closureInvocationSelectorName) return proposedName; 206 var proposedName = '$base\$$arity';
182 return getMappedInstanceName(proposedName); 207 if (name == closureInvocationSelectorName) return proposedName;
208 return getMappedInstanceName(proposedName);
209 } else {
210 return getMappedOperatorName(newName.slowToString());
211 }
183 } 212 }
184 213
185 String invocationName(Selector selector) { 214 String invocationName(Selector selector) {
186 if (selector.isGetter()) { 215 if (selector.isGetter()) {
187 String proposedName = privateName(selector.library, selector.name); 216 String proposedName = privateName(selector.library, selector.name);
188 return 'get\$${getMappedInstanceName(proposedName)}'; 217 return 'get\$${getMappedInstanceName(proposedName)}';
189 } else if (selector.isSetter()) { 218 } else if (selector.isSetter()) {
190 String proposedName = privateName(selector.library, selector.name); 219 String proposedName = privateName(selector.library, selector.name);
191 return 'set\$${getMappedInstanceName(proposedName)}'; 220 return 'set\$${getMappedInstanceName(proposedName)}';
192 } else { 221 } else {
193 SourceString name = Elements.operatorNameToIdentifier(selector.name); 222 SourceString name = operatorNameToIdentifier(selector.name);
194 StringBuffer buffer = new StringBuffer(); 223 if (name == selector.name) {
195 for (SourceString argumentName in selector.getOrderedNamedArguments()) { 224 StringBuffer buffer = new StringBuffer();
196 buffer.add(r'$'); 225 for (SourceString argumentName in selector.getOrderedNamedArguments()) {
197 argumentName.printOn(buffer); 226 buffer.add(r'$');
227 argumentName.printOn(buffer);
228 }
229 String suffix = '\$${selector.argumentCount}$buffer';
230 // We don't mangle the closure invoking function name because it
231 // is generated by string concatenation in applyFunction from
232 // js_helper.dart.
233 if (selector.isCall() && name == closureInvocationSelectorName) {
kasperl 2013/01/23 13:58:29 Could this be selector.isClosureCall() now that yo
ngeoffray 2013/01/23 14:00:16 Yes it can. Done.
234 return "${name.slowToString()}$suffix";
235 } else {
236 String proposedName = privateName(selector.library, name);
237 return getMappedInstanceName('$proposedName$suffix');
238 }
239 } else {
240 return getMappedOperatorName(name.slowToString());
198 } 241 }
199 String suffix = '\$${selector.argumentCount}$buffer';
200 // We don't mangle the closure invoking function name because it
201 // is generated by string concatenation in applyFunction from
202 // js_helper.dart.
203 if (selector.isCall() && name == closureInvocationSelectorName) {
204 return "${name.slowToString()}$suffix";
205 }
206 String proposedName = privateName(selector.library, name);
207 return getMappedInstanceName('$proposedName$suffix');
208 } 242 }
209 } 243 }
210 244
211 /** 245 /**
212 * Returns the internal name used for an invocation mirror of this selector. 246 * Returns the internal name used for an invocation mirror of this selector.
213 */ 247 */
214 String invocationMirrorInternalName(Selector selector) 248 String invocationMirrorInternalName(Selector selector)
215 => invocationName(selector); 249 => invocationName(selector);
216 250
217 String instanceFieldName(Element element) { 251 String instanceFieldName(Element element) {
218 String proposedName = privateName(element.getLibrary(), element.name); 252 String proposedName = privateName(element.getLibrary(), element.name);
219 return getMappedInstanceName(proposedName); 253 return getMappedInstanceName(proposedName);
220 } 254 }
221 255
222 // Construct a new name for the element based on the library and class it is 256 // Construct a new name for the element based on the library and class it is
223 // in. The name here is not important, we just need to make sure it is 257 // in. The name here is not important, we just need to make sure it is
224 // unique. If we are minifying, we actually construct the name from the 258 // unique. If we are minifying, we actually construct the name from the
225 // minified versions of the class and instance names, but the result is 259 // minified versions of the class and instance names, but the result is
226 // minified once again, so that is not visible in the end result. 260 // minified once again, so that is not visible in the end result.
227 String shadowedFieldName(Element fieldElement) { 261 String shadowedFieldName(Element fieldElement) {
228 // Check for following situation: Native field ${fieldElement.name} has 262 // Check for following situation: Native field ${fieldElement.name} has
229 // fixed JSName ${fieldElement.nativeName()}, but a subclass shadows this 263 // fixed JSName ${fieldElement.nativeName()}, but a subclass shadows this
230 // name. We normally handle that by renaming the superclass field, but we 264 // name. We normally handle that by renaming the superclass field, but we
231 // can't do that because native fields have fixed JsNames. In practice 265 // can't do that because native fields have fixed JavaScript names.
232 // this can't happen because we can't inherit from native classes. 266 // In practice this can't happen because we can't inherit from native
267 // classes.
233 assert (!fieldElement.hasFixedBackendName()); 268 assert (!fieldElement.hasFixedBackendName());
234 269
235 String libraryName = getName(fieldElement.getLibrary()); 270 String libraryName = getName(fieldElement.getLibrary());
236 String className = getName(fieldElement.getEnclosingClass()); 271 String className = getName(fieldElement.getEnclosingClass());
237 String instanceName = instanceFieldName(fieldElement); 272 String instanceName = instanceFieldName(fieldElement);
238 return getMappedInstanceName('$libraryName\$$className\$$instanceName'); 273 return getMappedInstanceName('$libraryName\$$className\$$instanceName');
239 } 274 }
240 275
241 String setterName(Element element) { 276 String setterName(Element element) {
242 // We dynamically create setters from the field-name. The setter name must 277 // We dynamically create setters from the field-name. The setter name must
(...skipping 26 matching lines...) Expand all
269 // We dynamically create getters from the field-name. The getter name must 304 // We dynamically create getters from the field-name. The getter name must
270 // therefore be derived from the instance field-name. 305 // therefore be derived from the instance field-name.
271 LibraryElement library = element.getLibrary(); 306 LibraryElement library = element.getLibrary();
272 String name = getMappedInstanceName(privateName(library, element.name)); 307 String name = getMappedInstanceName(privateName(library, element.name));
273 return 'get\$$name'; 308 return 'get\$$name';
274 } 309 }
275 310
276 String getMappedGlobalName(String proposedName) { 311 String getMappedGlobalName(String proposedName) {
277 var newName = globalNameMap[proposedName]; 312 var newName = globalNameMap[proposedName];
278 if (newName == null) { 313 if (newName == null) {
279 newName = getFreshName(proposedName, usedGlobalNames); 314 newName = getFreshName(proposedName, usedGlobalNames, true);
280 globalNameMap[proposedName] = newName; 315 globalNameMap[proposedName] = newName;
281 } 316 }
282 return newName; 317 return newName;
283 } 318 }
284 319
285 String getMappedInstanceName(String proposedName) { 320 String getMappedInstanceName(String proposedName) {
286 var newName = instanceNameMap[proposedName]; 321 var newName = instanceNameMap[proposedName];
287 if (newName == null) { 322 if (newName == null) {
288 newName = getFreshName(proposedName, usedInstanceNames); 323 newName = getFreshName(proposedName, usedInstanceNames, true);
289 instanceNameMap[proposedName] = newName; 324 instanceNameMap[proposedName] = newName;
290 } 325 }
291 return newName; 326 return newName;
292 } 327 }
293 328
294 String getFreshName(String proposedName, Set<String> usedNames) { 329 String getMappedOperatorName(String proposedName) {
330 var newName = operatorNameMap[proposedName];
331 if (newName == null) {
332 newName = getFreshName(proposedName, usedInstanceNames, false);
333 operatorNameMap[proposedName] = newName;
334 }
335 return newName;
336 }
337
338 String getFreshName(String proposedName,
339 Set<String> usedNames,
340 bool ensureSafe) {
295 var candidate; 341 var candidate;
296 proposedName = safeName(proposedName); 342 if (ensureSafe) {
343 proposedName = safeName(proposedName);
344 }
297 if (!usedNames.contains(proposedName)) { 345 if (!usedNames.contains(proposedName)) {
298 candidate = proposedName; 346 candidate = proposedName;
299 } else { 347 } else {
300 var counter = popularNameCounters[proposedName]; 348 var counter = popularNameCounters[proposedName];
301 var i = counter == null ? 0 : counter; 349 var i = counter == null ? 0 : counter;
302 while (usedNames.contains("$proposedName$i")) { 350 while (usedNames.contains("$proposedName$i")) {
303 i++; 351 i++;
304 } 352 }
305 popularNameCounters[proposedName] = i + 1; 353 popularNameCounters[proposedName] = i + 1;
306 candidate = "$proposedName$i"; 354 candidate = "$proposedName$i";
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 kind == ElementKind.LIBRARY || 474 kind == ElementKind.LIBRARY ||
427 kind == ElementKind.MALFORMED_TYPE) { 475 kind == ElementKind.MALFORMED_TYPE) {
428 bool fixedName = false; 476 bool fixedName = false;
429 if (kind == ElementKind.CLASS) { 477 if (kind == ElementKind.CLASS) {
430 ClassElement classElement = element; 478 ClassElement classElement = element;
431 } 479 }
432 if (Elements.isInstanceField(element)) { 480 if (Elements.isInstanceField(element)) {
433 fixedName = element.hasFixedBackendName(); 481 fixedName = element.hasFixedBackendName();
434 } 482 }
435 String result = 483 String result =
436 fixedName ? guess : getFreshName(guess, usedGlobalNames); 484 fixedName ? guess : getFreshName(guess, usedGlobalNames, true);
437 globals[element] = result; 485 globals[element] = result;
438 return result; 486 return result;
439 } 487 }
440 compiler.internalError('getName for unknown kind: ${element.kind}', 488 compiler.internalError('getName for unknown kind: ${element.kind}',
441 node: element.parseNode(compiler)); 489 node: element.parseNode(compiler));
442 } 490 }
443 } 491 }
444 492
445 String getLazyInitializerName(Element element) { 493 String getLazyInitializerName(Element element) {
446 assert(Elements.isStaticOrTopLevelField(element)); 494 assert(Elements.isStaticOrTopLevelField(element));
(...skipping 10 matching lines...) Expand all
457 505
458 String isolateBailoutAccess(Element element) { 506 String isolateBailoutAccess(Element element) {
459 String newName = getMappedGlobalName('${getName(element)}\$bailout'); 507 String newName = getMappedGlobalName('${getName(element)}\$bailout');
460 return '$CURRENT_ISOLATE.$newName'; 508 return '$CURRENT_ISOLATE.$newName';
461 } 509 }
462 510
463 String isolateLazyInitializerAccess(Element element) { 511 String isolateLazyInitializerAccess(Element element) {
464 return "$CURRENT_ISOLATE.${getLazyInitializerName(element)}"; 512 return "$CURRENT_ISOLATE.${getLazyInitializerName(element)}";
465 } 513 }
466 514
515 String operatorIsPrefix() => r'$is';
516
467 String operatorIs(Element element) { 517 String operatorIs(Element element) {
468 // TODO(erikcorry): Reduce from is$x to ix when we are minifying. 518 // TODO(erikcorry): Reduce from $isx to ix when we are minifying.
469 return 'is\$${getName(element)}'; 519 return '${operatorIsPrefix()}${getName(element)}';
470 } 520 }
471 521
522 /*
523 * Returns a name that does not clash with reserved JS keywords,
524 * and also ensures it won't clash with other identifiers.
525 */
472 String safeName(String name) { 526 String safeName(String name) {
473 if (jsReserved.contains(name) || name.startsWith('\$')) { 527 if (jsReserved.contains(name) || name.startsWith(r'$')) {
474 name = "\$$name"; 528 name = '\$$name';
475 assert(!jsReserved.contains(name));
476 } 529 }
530 assert(!jsReserved.contains(name));
477 return name; 531 return name;
478 } 532 }
533
534 SourceString operatorNameToIdentifier(SourceString name) {
535 if (name == null) return null;
536 String value = name.stringValue;
537 if (value == null) {
538 return name;
539 } else if (identical(value, '==')) {
540 return const SourceString(r'$eq');
541 } else if (identical(value, '~')) {
542 return const SourceString(r'$not');
543 } else if (identical(value, '[]')) {
544 return const SourceString(r'$index');
545 } else if (identical(value, '[]=')) {
546 return const SourceString(r'$indexSet');
547 } else if (identical(value, '*')) {
548 return const SourceString(r'$mul');
549 } else if (identical(value, '/')) {
550 return const SourceString(r'$div');
551 } else if (identical(value, '%')) {
552 return const SourceString(r'$mod');
553 } else if (identical(value, '~/')) {
554 return const SourceString(r'$tdiv');
555 } else if (identical(value, '+')) {
556 return const SourceString(r'$add');
557 } else if (identical(value, '<<')) {
558 return const SourceString(r'$shl');
559 } else if (identical(value, '>>')) {
560 return const SourceString(r'$shr');
561 } else if (identical(value, '>=')) {
562 return const SourceString(r'$ge');
563 } else if (identical(value, '>')) {
564 return const SourceString(r'$gt');
565 } else if (identical(value, '<=')) {
566 return const SourceString(r'$le');
567 } else if (identical(value, '<')) {
568 return const SourceString(r'$lt');
569 } else if (identical(value, '&')) {
570 return const SourceString(r'$and');
571 } else if (identical(value, '^')) {
572 return const SourceString(r'$xor');
573 } else if (identical(value, '|')) {
574 return const SourceString(r'$or');
575 } else if (identical(value, '-')) {
576 return const SourceString(r'$sub');
577 } else if (identical(value, 'unary-')) {
578 return const SourceString(r'$negate');
579 } else {
580 return name;
581 }
582 }
479 } 583 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698