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

Side by Side Diff: lib/compiler/implementation/elements/elements.dart

Issue 10824275: Revert "Refactor Library/CompilationUnit and how we define local Scope." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 4 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
« no previous file with comments | « lib/compiler/implementation/compiler.dart ('k') | lib/compiler/implementation/enqueue.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 #library('elements'); 5 #library('elements');
6 6
7 #import('dart:uri');
8
9 #import('../tree/tree.dart'); 7 #import('../tree/tree.dart');
10 #import('../scanner/scannerlib.dart'); 8 #import('../scanner/scannerlib.dart');
11 #import('../leg.dart'); // TODO(karlklose): we only need type. 9 #import('../leg.dart'); // TODO(karlklose): we only need type.
12 #import('../util/util.dart'); 10 #import('../util/util.dart');
13 11
14 class ElementCategory { 12 class ElementCategory {
15 /** 13 /**
16 * Represents things that we don't expect to find when looking in a 14 * Represents things that we don't expect to find when looking in a
17 * scope. 15 * scope.
18 */ 16 */
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 } 248 }
251 249
252 bool _isNative = false; 250 bool _isNative = false;
253 void setNative() { _isNative = true; } 251 void setNative() { _isNative = true; }
254 bool isNative() => _isNative; 252 bool isNative() => _isNative;
255 253
256 FunctionElement asFunctionElement() => null; 254 FunctionElement asFunctionElement() => null;
257 } 255 }
258 256
259 class ContainerElement extends Element { 257 class ContainerElement extends Element {
260 Link<Element> localMembers = const EmptyLink<Element>(); 258 ContainerElement(name, kind, enclosingElement) :
259 super(name, kind, enclosingElement);
261 260
262 ContainerElement(name, kind, enclosingElement) 261 abstract void addMember(Element element, DiagnosticListener listener);
263 : super(name, kind, enclosingElement);
264
265 void addMember(Element element, DiagnosticListener listener) {
266 localMembers = localMembers.prepend(element);
267 }
268 }
269
270 class ScopeContainerElement extends ContainerElement {
271 final Map<SourceString, Element> localScope;
272
273 ScopeContainerElement(name, kind, enclosingElement)
274 : super(name, kind, enclosingElement),
275 localScope = new Map<SourceString, Element>();
276
277 void addMember(Element element, DiagnosticListener listener) {
278 super.addMember(element, listener);
279 addToScope(element, listener);
280 }
281
282 void addToScope(Element element, DiagnosticListener listener) {
283 if (element.isAccessor()) {
284 addGetterOrSetter(element, localScope[element.name], listener);
285 } else {
286 Element existing = localScope.putIfAbsent(element.name, () => element);
287 if (existing !== element) {
288 listener.cancel('duplicate definition', token: element.position());
289 listener.cancel('existing definition', token: existing.position());
290 }
291 }
292 }
293
294 Element localLookup(SourceString elementName) {
295 return localScope[elementName];
296 }
297 262
298 void addGetterOrSetter(Element element, 263 void addGetterOrSetter(Element element,
299 Element existing, 264 Element existing,
300 DiagnosticListener listener) { 265 DiagnosticListener listener) {
301 void reportError(Element other) { 266 void reportError(Element other) {
302 listener.cancel('duplicate definition of ${element.name.slowToString()}', 267 listener.cancel('duplicate definition of ${element.name.slowToString()}',
303 element: element); 268 element: element);
304 listener.cancel('existing definition', element: other); 269 listener.cancel('existing definition', element: other);
305 } 270 }
306 271
(...skipping 19 matching lines...) Expand all
326 if (element.kind == ElementKind.GETTER) { 291 if (element.kind == ElementKind.GETTER) {
327 field.getter = element; 292 field.getter = element;
328 } else { 293 } else {
329 field.setter = element; 294 field.setter = element;
330 } 295 }
331 addMember(field, listener); 296 addMember(field, listener);
332 } 297 }
333 } 298 }
334 } 299 }
335 300
336
337
338 class CompilationUnitElement extends ContainerElement { 301 class CompilationUnitElement extends ContainerElement {
339 final Script script; 302 final Script script;
303 Link<Element> topLevelElements = const EmptyLink<Element>();
340 304
341 CompilationUnitElement(Script script, Element enclosing) 305 CompilationUnitElement(Script script, Element enclosing)
342 : this.script = script, 306 : this.script = script,
343 super(new SourceString(script.name), 307 super(new SourceString(script.name),
344 ElementKind.COMPILATION_UNIT, 308 ElementKind.COMPILATION_UNIT,
345 enclosing); 309 enclosing);
346 310
311 CompilationUnitElement.library(Script script)
312 : this.script = script,
313 super(new SourceString(script.name), ElementKind.LIBRARY, null);
314
347 void addMember(Element element, DiagnosticListener listener) { 315 void addMember(Element element, DiagnosticListener listener) {
348 // Keep a list of top level members. 316 LibraryElement library = enclosingElement;
349 super.addMember(element, listener); 317 library.addMember(element, listener);
350 // Provide the member to the library to build scope. 318 topLevelElements = topLevelElements.prepend(element);
351 getLibrary().addMember(element, listener); 319 }
320
321 void define(Element element, DiagnosticListener listener) {
322 LibraryElement library = enclosingElement;
323 library.define(element, listener);
324 }
325
326 void addTag(ScriptTag tag, DiagnosticListener listener) {
327 listener.cancel("script tags not allowed here", node: tag);
352 } 328 }
353 } 329 }
354 330
355 class LibraryElement extends ScopeContainerElement { 331 class LibraryElement extends CompilationUnitElement {
356 CompilationUnitElement entryCompilationUnit; 332 // TODO(ahe): Library element should not be a subclass of
333 // CompilationUnitElement.
334
357 Link<CompilationUnitElement> compilationUnits = 335 Link<CompilationUnitElement> compilationUnits =
358 const EmptyLink<CompilationUnitElement>(); 336 const EmptyLink<CompilationUnitElement>();
359
360 Link<ScriptTag> tags = const EmptyLink<ScriptTag>(); 337 Link<ScriptTag> tags = const EmptyLink<ScriptTag>();
361 ScriptTag libraryTag; 338 ScriptTag libraryTag;
339 Map<SourceString, Element> elements;
362 bool canUseNative = false; 340 bool canUseNative = false;
363 LibraryElement patch = null; 341 LibraryElement patch = null;
364 342
365 LibraryElement(Script script) 343 LibraryElement(Script script)
366 : super(new SourceString(script.name), ElementKind.LIBRARY, null) { 344 : elements = new Map<SourceString, Element>(),
367 entryCompilationUnit = new CompilationUnitElement(script, this); 345 super.library(script);
368 }
369
370 Uri get uri() => entryCompilationUnit.script.uri;
371 346
372 bool get isPatched() => patch !== null; 347 bool get isPatched() => patch !== null;
373 348
374 void addCompilationUnit(CompilationUnitElement element) { 349 void addCompilationUnit(CompilationUnitElement element) {
375 compilationUnits = compilationUnits.prepend(element); 350 compilationUnits = compilationUnits.prepend(element);
376 } 351 }
377 352
378 void addTag(ScriptTag tag, DiagnosticListener listener) { 353 void addTag(ScriptTag tag, DiagnosticListener listener) {
379 tags = tags.prepend(tag); 354 tags = tags.prepend(tag);
380 } 355 }
381 356
357 void addMember(Element element, DiagnosticListener listener) {
358 topLevelElements = topLevelElements.prepend(element);
359 define(element, listener);
360 }
361
362 void define(Element element, DiagnosticListener listener) {
363 if (element.kind == ElementKind.GETTER
364 || element.kind == ElementKind.SETTER) {
365 addGetterOrSetter(element, elements[element.name], listener);
366 } else {
367 Element existing = elements.putIfAbsent(element.name, () => element);
368 if (existing !== element) {
369 listener.cancel('duplicate definition', token: element.position());
370 listener.cancel('existing definition', token: existing.position());
371 }
372 }
373 }
374
382 /** Look up a top-level element in this library. The element could 375 /** Look up a top-level element in this library. The element could
383 * potentially have been imported from another library. Returns 376 * potentially have been imported from another library. Returns
384 * null if no such element exist. */ 377 * null if no such element exist. */
385 Element find(SourceString elementName) { 378 Element find(SourceString elementName) {
386 return localScope[elementName]; 379 return elements[elementName];
387 } 380 }
388 381
389 /** Look up a top-level element in this library, but only look for 382 /** Look up a top-level element in this library, but only look for
390 * non-imported elements. Returns null if no such element exist. */ 383 * non-imported elements. Returns null if no such element exist. */
391 Element findLocal(SourceString elementName) { 384 Element findLocal(SourceString elementName) {
392 Element result = localScope[elementName]; 385 Element result = elements[elementName];
393 if (result === null || result.getLibrary() != this) return null; 386 if (result === null || result.getLibrary() != this) return null;
394 return result; 387 return result;
395 } 388 }
396 389
397 void forEachExport(f(Element element)) { 390 void forEachExport(f(Element element)) {
398 localMembers.forEach((Element e) { 391 elements.forEach((SourceString _, Element e) {
399 if (e.kind !== ElementKind.PREFIX 392 if (this === e.getLibrary()
400 && e.kind !== ElementKind.FOREIGN 393 && e.kind !== ElementKind.PREFIX
401 && !e.name.isPrivate()) { 394 && e.kind !== ElementKind.FOREIGN) {
402 f(e); 395 if (!e.name.isPrivate()) f(e);
403 } 396 }
404 }); 397 });
405 } 398 }
406 399
407 bool hasLibraryName() => libraryTag !== null; 400 bool hasLibraryName() => libraryTag !== null;
408 401
409 /** 402 /**
410 * Returns the library name (as defined by the #library tag) or for script 403 * Returns the library name (as defined by the #library tag) or for script
411 * (which have no #library tag) the script file name. The latter case is used 404 * (which have no #library tag) the script file name. The latter case is used
412 * to private 'library name' for scripts to use for instance in dartdoc. 405 * to private 'library name' for scripts to use for instance in dartdoc.
413 */ 406 */
414 String getLibraryOrScriptName() { 407 String getLibraryOrScriptName() {
415 if (libraryTag !== null) { 408 if (libraryTag !== null) {
416 return libraryTag.argument.dartString.slowToString(); 409 return libraryTag.argument.dartString.slowToString();
417 } else { 410 } else {
418 // Use the file name as script name. 411 // Use the file name as script name.
419 String path = uri.path; 412 var path = script.uri.path;
420 return path.substring(path.lastIndexOf('/') + 1); 413 return path.substring(path.lastIndexOf('/') + 1);
421 } 414 }
422 } 415 }
423 416
424 CompilationUnitElement getCompilationUnit() => entryCompilationUnit;
425
426 Scope buildEnclosingScope() => new TopScope(this); 417 Scope buildEnclosingScope() => new TopScope(this);
427 } 418 }
428 419
429 class PrefixElement extends Element { 420 class PrefixElement extends Element {
430 Map<SourceString, Element> imported; 421 Map<SourceString, Element> imported;
431 Token firstPosition; 422 Token firstPosition;
432 final CompilationUnitElement patchCompilationUnit; 423 final CompilationUnitElement patchSource;
433 424
434 PrefixElement(SourceString prefix, Element enclosing, this.firstPosition, 425 PrefixElement(SourceString prefix, Element enclosing, this.firstPosition,
435 [this.patchCompilationUnit]) 426 [this.patchSource])
436 : imported = new Map<SourceString, Element>(), 427 : imported = new Map<SourceString, Element>(),
437 super(prefix, ElementKind.PREFIX, enclosing); 428 super(prefix, ElementKind.PREFIX, enclosing);
438 429
439 CompilationUnitElement getCompilationUnit() { 430 CompilationUnitElement getCompilationUnit() {
440 if (patchCompilationUnit !== null) return patchCompilationUnit; 431 if (patchSource !== null) return patchSource;
441 return super.getCompilationUnit(); 432 return super.getCompilationUnit();
442 } 433 }
443 434
444 lookupLocalMember(SourceString memberName) => imported[memberName]; 435 lookupLocalMember(SourceString memberName) => imported[memberName];
445 436
446 Type computeType(Compiler compiler) => compiler.types.dynamicType; 437 Type computeType(Compiler compiler) => compiler.types.dynamicType;
447 438
448 Token position() => firstPosition; 439 Token position() => firstPosition;
449 } 440 }
450 441
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
881 TypeVariableElement variableElement = 872 TypeVariableElement variableElement =
882 new TypeVariableElement(variableName, element, node); 873 new TypeVariableElement(variableName, element, node);
883 TypeVariableType variableType = new TypeVariableType(variableElement); 874 TypeVariableType variableType = new TypeVariableType(variableElement);
884 variableElement.type = variableType; 875 variableElement.type = variableType;
885 arguments.addLast(variableType); 876 arguments.addLast(variableType);
886 } 877 }
887 return arguments.toLink(); 878 return arguments.toLink();
888 } 879 }
889 } 880 }
890 881
891 class ClassElement extends ScopeContainerElement 882 class ClassElement extends ContainerElement
892 implements TypeDeclarationElement { 883 implements TypeDeclarationElement {
893 final int id; 884 final int id;
894 InterfaceType type; 885 InterfaceType type;
895 Type supertype; 886 Type supertype;
896 Type defaultClass; 887 Type defaultClass;
888 Link<Element> members = const EmptyLink<Element>();
889 Map<SourceString, Element> localMembers;
890 Map<SourceString, Element> constructors;
897 Link<Type> interfaces = const EmptyLink<Type>(); 891 Link<Type> interfaces = const EmptyLink<Type>();
898 bool isResolved = false; 892 bool isResolved = false;
899 bool isBeingResolved = false; 893 bool isBeingResolved = false;
900 // backendMembers are members that have been added by the backend to simplify 894 // backendMembers are members that have been added by the backend to simplify
901 // compilation. They don't have any user-side counter-part. 895 // compilation. They don't have any user-side counter-part.
902 Link<Element> backendMembers = const EmptyLink<Element>(); 896 Link<Element> backendMembers = const EmptyLink<Element>();
903 897
904 Link<Type> allSupertypes; 898 Link<Type> allSupertypes;
905 ClassElement patch = null; 899 ClassElement patch = null;
906 900
907 ClassElement(SourceString name, CompilationUnitElement enclosing, this.id) 901 ClassElement(SourceString name, CompilationUnitElement enclosing, this.id)
908 : super(name, ElementKind.CLASS, enclosing); 902 : localMembers = new Map<SourceString, Element>(),
903 constructors = new Map<SourceString, Element>(),
904 super(name, ElementKind.CLASS, enclosing);
905
906 void addMember(Element element, DiagnosticListener listener) {
907 members = members.prepend(element);
908 if (element.kind == ElementKind.GENERATIVE_CONSTRUCTOR ||
909 element.modifiers.isFactory()) {
910 constructors[element.name] = element;
911 } else if (element.kind == ElementKind.GETTER
912 || element.kind == ElementKind.SETTER) {
913 addGetterOrSetter(element, localMembers[element.name], listener);
914 } else {
915 localMembers[element.name] = element;
916 }
917 }
909 918
910 InterfaceType computeType(compiler) { 919 InterfaceType computeType(compiler) {
911 if (type == null) { 920 if (type == null) {
912 ClassNode node = parseNode(compiler); 921 ClassNode node = parseNode(compiler);
913 Link<Type> parameters = 922 Link<Type> parameters =
914 TypeDeclarationElement.createTypeVariables(this, node.typeParameters); 923 TypeDeclarationElement.createTypeVariables(this, node.typeParameters);
915 type = new InterfaceType(this, parameters); 924 type = new InterfaceType(this, parameters);
916 } 925 }
917 return type; 926 return type;
918 } 927 }
919 928
920 Link<Type> get typeVariables() => type.arguments; 929 Link<Type> get typeVariables() => type.arguments;
921 930
922 ClassElement ensureResolved(Compiler compiler) { 931 ClassElement ensureResolved(Compiler compiler) {
923 compiler.resolveClass(this); 932 compiler.resolveClass(this);
924 return this; 933 return this;
925 } 934 }
926 935
927 /**
928 * Lookup local members in the class. This will ignore constructors.
929 */
930 Element lookupLocalMember(SourceString memberName) { 936 Element lookupLocalMember(SourceString memberName) {
931 var result = localLookup(memberName); 937 return localMembers[memberName];
932 if (result !== null && result.isConstructor()) return null;
933 return result;
934 } 938 }
935 939
936 /**
937 * Lookup super members for the class. This will ignore constructors.
938 */
939 Element lookupSuperMember(SourceString memberName) { 940 Element lookupSuperMember(SourceString memberName) {
940 bool isPrivate = memberName.isPrivate(); 941 bool isPrivate = memberName.isPrivate();
941 for (ClassElement s = superclass; s != null; s = s.superclass) { 942 for (ClassElement s = superclass; s != null; s = s.superclass) {
942 // Private members from a different library are not visible. 943 // Private members from a different library are not visible.
943 if (isPrivate && getLibrary() !== s.getLibrary()) continue; 944 if (isPrivate && getLibrary() !== s.getLibrary()) continue;
944 Element e = s.lookupLocalMember(memberName); 945 Element e = s.lookupLocalMember(memberName);
945 if (e === null) continue; 946 if (e === null) continue;
946 // Static members are not inherited. 947 // Static members are not inherited.
947 if (e.modifiers.isStatic()) continue; 948 if (e.modifiers.isStatic()) continue;
948 return e; 949 return e;
949 } 950 }
950 return null; 951 return null;
951 } 952 }
952 953
953 /** 954 /**
954 * Find the first member in the class chain with the given 955 * Find the first member in the class chain with the given
955 * [memberName]. This method is NOT to be used for resolving 956 * [memberName]. This method is NOT to be used for resolving
956 * unqualified sends because it does not implement the scoping 957 * unqualified sends because it does not implement the scoping
957 * rules, where library scope comes before superclass scope. 958 * rules, where library scope comes before superclass scope.
958 */ 959 */
959 Element lookupMember(SourceString memberName) { 960 Element lookupMember(SourceString memberName) {
960 Element localMember = lookupLocalMember(memberName); 961 Element localMember = localMembers[memberName];
961 return localMember === null ? lookupSuperMember(memberName) : localMember; 962 return localMember === null ? lookupSuperMember(memberName) : localMember;
962 } 963 }
963 964
964 /** 965 /**
965 * Returns true if the [fieldMember] is shadowed by another field. The given 966 * Returns true if the [fieldMember] is shadowed by another field. The given
966 * [fieldMember] must be a member of this class. 967 * [fieldMember] must be a member of this class.
967 * 968 *
968 * This method also works if the [fieldMember] is private. 969 * This method also works if the [fieldMember] is private.
969 */ 970 */
970 bool isShadowedByField(Element fieldMember) { 971 bool isShadowedByField(Element fieldMember) {
(...skipping 24 matching lines...) Expand all
995 Element noMatch(Element)]) { 996 Element noMatch(Element)]) {
996 // TODO(karlklose): have a map from class names to a map of constructors 997 // TODO(karlklose): have a map from class names to a map of constructors
997 // instead of creating the name here? 998 // instead of creating the name here?
998 SourceString normalizedName; 999 SourceString normalizedName;
999 if (constructorName !== const SourceString('')) { 1000 if (constructorName !== const SourceString('')) {
1000 normalizedName = Elements.constructConstructorName(className, 1001 normalizedName = Elements.constructConstructorName(className,
1001 constructorName); 1002 constructorName);
1002 } else { 1003 } else {
1003 normalizedName = className; 1004 normalizedName = className;
1004 } 1005 }
1005 Element result = localLookup(normalizedName); 1006 Element result = constructors[normalizedName];
1006 if (result === null || !result.isConstructor()) { 1007 if (result === null && noMatch !== null) {
1007 result = noMatch !== null ? noMatch(result) : null; 1008 result = noMatch(lookupLocalMember(constructorName));
1008 } 1009 }
1009 return result; 1010 return result;
1010 } 1011 }
1011 1012
1012 bool get hasConstructor() {
1013 // Search in scope to be sure we search patched constructors.
1014 for (var element in localScope.getValues()) {
1015 if (element.isConstructor()) return true;
1016 }
1017 return false;
1018 }
1019
1020 Collection<Element> get constructors() {
1021 // TODO(ajohnsen): See if we can avoid this method at some point.
1022 List<Element> result = <Element>[];
1023 // Search in scope to be sure we search patched constructors.
1024 localScope.forEach((_, Element value) {
1025 if (value.isConstructor()) result.add(value);
1026 });
1027 return result;
1028 }
1029
1030 /** 1013 /**
1031 * Returns the super class, if any. 1014 * Returns the super class, if any.
1032 * 1015 *
1033 * The returned element may not be resolved yet. 1016 * The returned element may not be resolved yet.
1034 */ 1017 */
1035 ClassElement get superclass() { 1018 ClassElement get superclass() {
1036 assert(isResolved); 1019 assert(isResolved);
1037 return supertype === null ? null : supertype.element; 1020 return supertype === null ? null : supertype.element;
1038 } 1021 }
1039 1022
1040 /** 1023 /**
1041 * Runs through all members of this class. 1024 * Runs through all members of this class.
1042 * 1025 *
1043 * The enclosing class is passed to the callback. This is useful when 1026 * The enclosing class is passed to the callback. This is useful when
1044 * [includeSuperMembers] is [:true:]. 1027 * [includeSuperMembers] is [:true:].
1045 */ 1028 */
1046 void forEachMember([void f(ClassElement enclosingClass, Element member), 1029 void forEachMember([void f(ClassElement enclosingClass, Element member),
1047 includeBackendMembers = false, 1030 includeBackendMembers = false,
1048 includeSuperMembers = false]) { 1031 includeSuperMembers = false]) {
1049 Set<ClassElement> seen = new Set<ClassElement>(); 1032 Set<ClassElement> seen = new Set<ClassElement>();
1050 ClassElement classElement = this; 1033 ClassElement classElement = this;
1051 do { 1034 do {
1052 if (seen.contains(classElement)) return; 1035 if (seen.contains(classElement)) return;
1053 seen.add(classElement); 1036 seen.add(classElement);
1054 for (Element element in classElement.localMembers) { 1037 for (Element element in classElement.members) {
1055 f(classElement, element); 1038 f(classElement, element);
1056 } 1039 }
1057 if (includeBackendMembers) { 1040 if (includeBackendMembers) {
1058 for (Element element in classElement.backendMembers) { 1041 for (Element element in classElement.backendMembers) {
1059 f(classElement, element); 1042 f(classElement, element);
1060 } 1043 }
1061 } 1044 }
1062 classElement = includeSuperMembers ? classElement.superclass : null; 1045 classElement = includeSuperMembers ? classElement.superclass : null;
1063 } while(classElement !== null); 1046 } while(classElement !== null);
1064 } 1047 }
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
1301 TypeVariableElement(name, Element enclosing, this.cachedNode, 1284 TypeVariableElement(name, Element enclosing, this.cachedNode,
1302 [this.type, this.bound]) 1285 [this.type, this.bound])
1303 : super(name, ElementKind.TYPE_VARIABLE, enclosing); 1286 : super(name, ElementKind.TYPE_VARIABLE, enclosing);
1304 1287
1305 TypeVariableType computeType(compiler) => type; 1288 TypeVariableType computeType(compiler) => type;
1306 1289
1307 Node parseNode(compiler) => cachedNode; 1290 Node parseNode(compiler) => cachedNode;
1308 1291
1309 String toString() => "${enclosingElement.toString()}.${name.slowToString()}"; 1292 String toString() => "${enclosingElement.toString()}.${name.slowToString()}";
1310 } 1293 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/compiler.dart ('k') | lib/compiler/implementation/enqueue.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698