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

Side by Side Diff: pkg/compiler/lib/src/native/enqueue.dart

Issue 1859343004: dartfmt pkg/compiler (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 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
« no previous file with comments | « pkg/compiler/lib/src/native/behavior.dart ('k') | pkg/compiler/lib/src/native/js.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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 import 'dart:collection' show Queue; 5 import 'dart:collection' show Queue;
6 6
7 import '../common.dart'; 7 import '../common.dart';
8 import '../common/backend_api.dart' show 8 import '../common/backend_api.dart' show ForeignResolver;
9 ForeignResolver; 9 import '../common/registry.dart' show Registry;
10 import '../common/registry.dart' show 10 import '../common/resolution.dart' show Parsing, Resolution;
11 Registry; 11 import '../compiler.dart' show Compiler;
12 import '../common/resolution.dart' show
13 Parsing,
14 Resolution;
15 import '../compiler.dart' show
16 Compiler;
17 import '../constants/values.dart'; 12 import '../constants/values.dart';
18 import '../core_types.dart' show 13 import '../core_types.dart' show CoreTypes;
19 CoreTypes;
20 import '../dart_types.dart'; 14 import '../dart_types.dart';
21 import '../enqueue.dart' show 15 import '../enqueue.dart' show Enqueuer, ResolutionEnqueuer;
22 Enqueuer,
23 ResolutionEnqueuer;
24 import '../elements/elements.dart'; 16 import '../elements/elements.dart';
25 import '../elements/modelx.dart' show 17 import '../elements/modelx.dart'
26 BaseClassElementX, 18 show BaseClassElementX, ElementX, FunctionElementX, LibraryElementX;
27 ElementX, 19 import '../js_backend/backend_helpers.dart' show BackendHelpers;
28 FunctionElementX,
29 LibraryElementX;
30 import '../js_backend/backend_helpers.dart' show
31 BackendHelpers;
32 import '../js_backend/js_backend.dart'; 20 import '../js_backend/js_backend.dart';
33 import '../js_emitter/js_emitter.dart' show 21 import '../js_emitter/js_emitter.dart' show CodeEmitterTask, NativeEmitter;
34 CodeEmitterTask, 22 import '../tokens/token.dart' show BeginGroupToken, Token;
35 NativeEmitter; 23 import '../tokens/token_constants.dart' as Tokens show EOF_TOKEN, STRING_TOKEN;
36 import '../tokens/token.dart' show
37 BeginGroupToken,
38 Token;
39 import '../tokens/token_constants.dart' as Tokens show
40 EOF_TOKEN,
41 STRING_TOKEN;
42 import '../tree/tree.dart'; 24 import '../tree/tree.dart';
43 25
44 import 'behavior.dart'; 26 import 'behavior.dart';
45 27
46 /** 28 /**
47 * This could be an abstract class but we use it as a stub for the dart_backend. 29 * This could be an abstract class but we use it as a stub for the dart_backend.
48 */ 30 */
49 class NativeEnqueuer { 31 class NativeEnqueuer {
50 /// Initial entry point to native enqueuer. 32 /// Initial entry point to native enqueuer.
51 void processNativeClasses(Iterable<LibraryElement> libraries) {} 33 void processNativeClasses(Iterable<LibraryElement> libraries) {}
(...skipping 23 matching lines...) Expand all
75 57
76 /// Emits a summary information using the [log] function. 58 /// Emits a summary information using the [log] function.
77 void logSummary(log(message)) {} 59 void logSummary(log(message)) {}
78 60
79 // Do not use annotations in dart2dart. 61 // Do not use annotations in dart2dart.
80 ClassElement get annotationCreatesClass => null; 62 ClassElement get annotationCreatesClass => null;
81 ClassElement get annotationReturnsClass => null; 63 ClassElement get annotationReturnsClass => null;
82 ClassElement get annotationJsNameClass => null; 64 ClassElement get annotationJsNameClass => null;
83 } 65 }
84 66
85
86 abstract class NativeEnqueuerBase implements NativeEnqueuer { 67 abstract class NativeEnqueuerBase implements NativeEnqueuer {
87 static final RegExp _identifier = new RegExp(r'^[a-zA-Z_$][a-zA-Z0-9_$]*$'); 68 static final RegExp _identifier = new RegExp(r'^[a-zA-Z_$][a-zA-Z0-9_$]*$');
88 69
89 /** 70 /**
90 * The set of all native classes. Each native class is in [nativeClasses] and 71 * The set of all native classes. Each native class is in [nativeClasses] and
91 * exactly one of [unusedClasses], [pendingClasses] and [registeredClasses]. 72 * exactly one of [unusedClasses], [pendingClasses] and [registeredClasses].
92 */ 73 */
93 final Set<ClassElement> nativeClasses = new Set<ClassElement>(); 74 final Set<ClassElement> nativeClasses = new Set<ClassElement>();
94 75
95 final Set<ClassElement> registeredClasses = new Set<ClassElement>(); 76 final Set<ClassElement> registeredClasses = new Set<ClassElement>();
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 // 162 //
182 // String "A" has a potential subclass B. 163 // String "A" has a potential subclass B.
183 164
184 var potentialExtends = new Map<String, Set<ClassElement>>(); 165 var potentialExtends = new Map<String, Set<ClassElement>>();
185 166
186 libraries.forEach((library) { 167 libraries.forEach((library) {
187 library.implementation.forEachLocalMember((element) { 168 library.implementation.forEachLocalMember((element) {
188 if (element.isClass) { 169 if (element.isClass) {
189 String extendsName = findExtendsNameOfClass(element); 170 String extendsName = findExtendsNameOfClass(element);
190 if (extendsName != null) { 171 if (extendsName != null) {
191 Set<ClassElement> potentialSubclasses = 172 Set<ClassElement> potentialSubclasses = potentialExtends
192 potentialExtends.putIfAbsent( 173 .putIfAbsent(extendsName, () => new Set<ClassElement>());
193 extendsName,
194 () => new Set<ClassElement>());
195 potentialSubclasses.add(element); 174 potentialSubclasses.add(element);
196 } 175 }
197 } 176 }
198 }); 177 });
199 }); 178 });
200 179
201 // Resolve all the native classes and any classes that might extend them in 180 // Resolve all the native classes and any classes that might extend them in
202 // [potentialExtends], and then check that the properly resolved class is in 181 // [potentialExtends], and then check that the properly resolved class is in
203 // fact a subclass of a native class. 182 // fact a subclass of a native class.
204 183
205 ClassElement nativeSuperclassOf(ClassElement classElement) { 184 ClassElement nativeSuperclassOf(ClassElement classElement) {
206 if (backend.isNative(classElement)) return classElement; 185 if (backend.isNative(classElement)) return classElement;
207 if (classElement.superclass == null) return null; 186 if (classElement.superclass == null) return null;
208 return nativeSuperclassOf(classElement.superclass); 187 return nativeSuperclassOf(classElement.superclass);
209 } 188 }
210 189
211 void walkPotentialSubclasses(ClassElement element) { 190 void walkPotentialSubclasses(ClassElement element) {
212 if (nativeClassesAndSubclasses.contains(element)) return; 191 if (nativeClassesAndSubclasses.contains(element)) return;
213 element.ensureResolved(resolution); 192 element.ensureResolved(resolution);
214 ClassElement nativeSuperclass = nativeSuperclassOf(element); 193 ClassElement nativeSuperclass = nativeSuperclassOf(element);
215 if (nativeSuperclass != null) { 194 if (nativeSuperclass != null) {
216 nativeClassesAndSubclasses.add(element); 195 nativeClassesAndSubclasses.add(element);
217 if (!backend.isNative(element)) { 196 if (!backend.isNative(element)) {
218 nonNativeSubclasses.putIfAbsent(nativeSuperclass, 197 nonNativeSubclasses
219 () => new Set<ClassElement>()) 198 .putIfAbsent(nativeSuperclass, () => new Set<ClassElement>())
220 .add(element); 199 .add(element);
221 } 200 }
222 Set<ClassElement> potentialSubclasses = potentialExtends[element.name]; 201 Set<ClassElement> potentialSubclasses = potentialExtends[element.name];
223 if (potentialSubclasses != null) { 202 if (potentialSubclasses != null) {
224 potentialSubclasses.forEach(walkPotentialSubclasses); 203 potentialSubclasses.forEach(walkPotentialSubclasses);
225 } 204 }
226 } 205 }
227 } 206 }
228 207
229 nativeClasses.forEach(walkPotentialSubclasses); 208 nativeClasses.forEach(walkPotentialSubclasses);
230 209
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 annotation.ensureResolved(resolution); 320 annotation.ensureResolved(resolution);
342 ConstantValue value = 321 ConstantValue value =
343 compiler.constants.getConstantValue(annotation.constant); 322 compiler.constants.getConstantValue(annotation.constant);
344 if (!value.isConstructedObject) continue; 323 if (!value.isConstructedObject) continue;
345 ConstructedConstantValue constructedObject = value; 324 ConstructedConstantValue constructedObject = value;
346 if (constructedObject.type.element != annotationClass) continue; 325 if (constructedObject.type.element != annotationClass) continue;
347 326
348 Iterable<ConstantValue> fields = constructedObject.fields.values; 327 Iterable<ConstantValue> fields = constructedObject.fields.values;
349 // TODO(sra): Better validation of the constant. 328 // TODO(sra): Better validation of the constant.
350 if (fields.length != 1 || fields.single is! StringConstantValue) { 329 if (fields.length != 1 || fields.single is! StringConstantValue) {
351 reporter.internalError(annotation, 330 reporter.internalError(
352 'Annotations needs one string: ${annotation.node}'); 331 annotation, 'Annotations needs one string: ${annotation.node}');
353 } 332 }
354 StringConstantValue specStringConstant = fields.single; 333 StringConstantValue specStringConstant = fields.single;
355 String specString = specStringConstant.toDartString().slowToString(); 334 String specString = specStringConstant.toDartString().slowToString();
356 if (name == null) { 335 if (name == null) {
357 name = specString; 336 name = specString;
358 } else { 337 } else {
359 reporter.internalError(annotation, 338 reporter.internalError(
360 'Too many JSName annotations: ${annotation.node}'); 339 annotation, 'Too many JSName annotations: ${annotation.node}');
361 } 340 }
362 } 341 }
363 return name; 342 return name;
364 } 343 }
365 344
366 enqueueClass(ClassElement classElement, cause) { 345 enqueueClass(ClassElement classElement, cause) {
367 assert(unusedClasses.contains(classElement)); 346 assert(unusedClasses.contains(classElement));
368 unusedClasses.remove(classElement); 347 unusedClasses.remove(classElement);
369 pendingClasses.add(classElement); 348 pendingClasses.add(classElement);
370 queue.add(() { processClass(classElement, cause); }); 349 queue.add(() {
350 processClass(classElement, cause);
351 });
371 } 352 }
372 353
373 void flushQueue() { 354 void flushQueue() {
374 if (flushing) return; 355 if (flushing) return;
375 flushing = true; 356 flushing = true;
376 while (!queue.isEmpty) { 357 while (!queue.isEmpty) {
377 (queue.removeFirst())(); 358 (queue.removeFirst())();
378 } 359 }
379 flushing = false; 360 flushing = false;
380 } 361 }
381 362
382 processClass(ClassElement classElement, cause) { 363 processClass(ClassElement classElement, cause) {
383 // TODO(ahe): Fix this assertion to work in incremental compilation. 364 // TODO(ahe): Fix this assertion to work in incremental compilation.
384 assert(compiler.options.hasIncrementalSupport || 365 assert(compiler.options.hasIncrementalSupport ||
385 !registeredClasses.contains(classElement)); 366 !registeredClasses.contains(classElement));
386 367
387 bool firstTime = registeredClasses.isEmpty; 368 bool firstTime = registeredClasses.isEmpty;
388 pendingClasses.remove(classElement); 369 pendingClasses.remove(classElement);
389 registeredClasses.add(classElement); 370 registeredClasses.add(classElement);
390 371
391 // TODO(ahe): Is this really a global dependency? 372 // TODO(ahe): Is this really a global dependency?
392 classElement.ensureResolved(resolution); 373 classElement.ensureResolved(resolution);
393 compiler.backend.registerInstantiatedType( 374 compiler.backend.registerInstantiatedType(
394 classElement.rawType, world, compiler.globalDependencies); 375 classElement.rawType, world, compiler.globalDependencies);
395 376
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 /// use the declared @JSName as the expression 443 /// use the declared @JSName as the expression
463 /// 3. If [element] does not have a @JSName annotation, qualify the name of 444 /// 3. If [element] does not have a @JSName annotation, qualify the name of
464 /// the method with the @Native name of the enclosing class. 445 /// the method with the @Native name of the enclosing class.
465 void _setNativeNameForStaticMethod(MethodElement element) { 446 void _setNativeNameForStaticMethod(MethodElement element) {
466 String name = findJsNameFromAnnotation(element); 447 String name = findJsNameFromAnnotation(element);
467 if (name == null) name = element.name; 448 if (name == null) name = element.name;
468 if (isIdentifier(name)) { 449 if (isIdentifier(name)) {
469 List<String> nativeNames = 450 List<String> nativeNames =
470 backend.nativeData.getNativeTagsOfClassRaw(element.enclosingClass); 451 backend.nativeData.getNativeTagsOfClassRaw(element.enclosingClass);
471 if (nativeNames.length != 1) { 452 if (nativeNames.length != 1) {
472 reporter.internalError(element, 453 reporter.internalError(
454 element,
473 'Unable to determine a native name for the enclosing class, ' 455 'Unable to determine a native name for the enclosing class, '
474 'options: $nativeNames'); 456 'options: $nativeNames');
475 } 457 }
476 backend.nativeData.setNativeMemberName( 458 backend.nativeData
477 element, '${nativeNames[0]}.$name'); 459 .setNativeMemberName(element, '${nativeNames[0]}.$name');
478 } else { 460 } else {
479 backend.nativeData.setNativeMemberName(element, name); 461 backend.nativeData.setNativeMemberName(element, name);
480 } 462 }
481 } 463 }
482 464
483 bool isIdentifier(String s) => _identifier.hasMatch(s); 465 bool isIdentifier(String s) => _identifier.hasMatch(s);
484 466
485 bool isNativeMethod(FunctionElementX element) { 467 bool isNativeMethod(FunctionElementX element) {
486 if (!backend.canLibraryUseNative(element.library)) return false; 468 if (!backend.canLibraryUseNative(element.library)) return false;
487 // Native method? 469 // Native method?
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 continue; 512 continue;
531 } 513 }
532 if (type is InterfaceType) { 514 if (type is InterfaceType) {
533 if (type == coreTypes.intType) { 515 if (type == coreTypes.intType) {
534 backend.registerInstantiatedType(type, world, registry); 516 backend.registerInstantiatedType(type, world, registry);
535 } else if (type == coreTypes.doubleType) { 517 } else if (type == coreTypes.doubleType) {
536 backend.registerInstantiatedType(type, world, registry); 518 backend.registerInstantiatedType(type, world, registry);
537 } else if (type == coreTypes.numType) { 519 } else if (type == coreTypes.numType) {
538 backend.registerInstantiatedType( 520 backend.registerInstantiatedType(
539 coreTypes.doubleType, world, registry); 521 coreTypes.doubleType, world, registry);
540 backend.registerInstantiatedType( 522 backend.registerInstantiatedType(coreTypes.intType, world, registry);
541 coreTypes.intType, world, registry);
542 } else if (type == coreTypes.stringType) { 523 } else if (type == coreTypes.stringType) {
543 backend.registerInstantiatedType(type, world, registry); 524 backend.registerInstantiatedType(type, world, registry);
544 } else if (type == coreTypes.nullType) { 525 } else if (type == coreTypes.nullType) {
545 backend.registerInstantiatedType(type, world, registry); 526 backend.registerInstantiatedType(type, world, registry);
546 } else if (type == coreTypes.boolType) { 527 } else if (type == coreTypes.boolType) {
547 backend.registerInstantiatedType(type, world, registry); 528 backend.registerInstantiatedType(type, world, registry);
548 } else if (compiler.types.isSubtype( 529 } else if (compiler.types
549 type, backend.listImplementation.rawType)) { 530 .isSubtype(type, backend.listImplementation.rawType)) {
550 backend.registerInstantiatedType(type, world, registry); 531 backend.registerInstantiatedType(type, world, registry);
551 } 532 }
552 } 533 }
553 assert(type is DartType); 534 assert(type is DartType);
554 enqueueUnusedClassesMatching( 535 enqueueUnusedClassesMatching(
555 (nativeClass) => compiler.types.isSubtype(nativeClass.thisType, type), 536 (nativeClass) => compiler.types.isSubtype(nativeClass.thisType, type),
556 cause, 537 cause,
557 'subtypeof($type)'); 538 'subtypeof($type)');
558 } 539 }
559 540
560 // Give an info so that library developers can compile with -v to find why 541 // Give an info so that library developers can compile with -v to find why
561 // all the native classes are included. 542 // all the native classes are included.
562 if (unusedClasses.isEmpty && !allUsedBefore) { 543 if (unusedClasses.isEmpty && !allUsedBefore) {
563 reporter.log('All native types marked as used due to $cause.'); 544 reporter.log('All native types marked as used due to $cause.');
564 } 545 }
565 } 546 }
566 547
567 enqueueUnusedClassesMatching(bool predicate(classElement), 548 enqueueUnusedClassesMatching(bool predicate(classElement), cause,
568 cause, 549 [String reason]) {
569 [String reason]) {
570 Iterable matches = unusedClasses.where(predicate); 550 Iterable matches = unusedClasses.where(predicate);
571 matches.toList().forEach((c) => enqueueClass(c, cause)); 551 matches.toList().forEach((c) => enqueueClass(c, cause));
572 } 552 }
573 553
574 onFirstNativeClass() { 554 onFirstNativeClass() {
575 staticUse(name) { 555 staticUse(name) {
576 backend.enqueue( 556 backend.enqueue(
577 world, helpers.findHelper(name), compiler.globalDependencies); 557 world, helpers.findHelper(name), compiler.globalDependencies);
578 } 558 }
579 559
580 staticUse('defineProperty'); 560 staticUse('defineProperty');
581 staticUse('toStringForNativeObject'); 561 staticUse('toStringForNativeObject');
582 staticUse('hashCodeForNativeObject'); 562 staticUse('hashCodeForNativeObject');
583 staticUse('convertDartClosureToJS'); 563 staticUse('convertDartClosureToJS');
584 addNativeExceptions(); 564 addNativeExceptions();
585 } 565 }
586 566
587 addNativeExceptions() { 567 addNativeExceptions() {
588 enqueueUnusedClassesMatching((classElement) { 568 enqueueUnusedClassesMatching((classElement) {
589 // TODO(sra): Annotate exception classes in dart:html. 569 // TODO(sra): Annotate exception classes in dart:html.
590 String name = classElement.name; 570 String name = classElement.name;
591 if (name.contains('Exception')) return true; 571 if (name.contains('Exception')) return true;
592 if (name.contains('Error')) return true; 572 if (name.contains('Error')) return true;
593 return false; 573 return false;
594 }, 574 }, 'native exception');
595 'native exception');
596 } 575 }
597 } 576 }
598 577
599
600 class NativeResolutionEnqueuer extends NativeEnqueuerBase { 578 class NativeResolutionEnqueuer extends NativeEnqueuerBase {
601
602 Map<String, ClassElement> tagOwner = new Map<String, ClassElement>(); 579 Map<String, ClassElement> tagOwner = new Map<String, ClassElement>();
603 580
604 NativeResolutionEnqueuer(Enqueuer world, Compiler compiler) 581 NativeResolutionEnqueuer(Enqueuer world, Compiler compiler)
605 : super(world, compiler, compiler.options.enableNativeLiveTypeAnalysis); 582 : super(world, compiler, compiler.options.enableNativeLiveTypeAnalysis);
606 583
607 void processNativeClass(ClassElement classElement) { 584 void processNativeClass(ClassElement classElement) {
608 super.processNativeClass(classElement); 585 super.processNativeClass(classElement);
609 586
610 // Js Interop interfaces do not have tags. 587 // Js Interop interfaces do not have tags.
611 if (backend.isJsInterop(classElement)) return; 588 if (backend.isJsInterop(classElement)) return;
612 // Since we map from dispatch tags to classes, a dispatch tag must be used 589 // Since we map from dispatch tags to classes, a dispatch tag must be used
613 // on only one native class. 590 // on only one native class.
614 for (String tag in backend.nativeData.getNativeTagsOfClass(classElement)) { 591 for (String tag in backend.nativeData.getNativeTagsOfClass(classElement)) {
615 ClassElement owner = tagOwner[tag]; 592 ClassElement owner = tagOwner[tag];
(...skipping 22 matching lines...) Expand all
638 * JS('_DOMWindowImpl', 'window') 615 * JS('_DOMWindowImpl', 'window')
639 * 616 *
640 */ 617 */
641 void registerJsCall(Send node, ForeignResolver resolver) { 618 void registerJsCall(Send node, ForeignResolver resolver) {
642 NativeBehavior behavior = NativeBehavior.ofJsCall( 619 NativeBehavior behavior = NativeBehavior.ofJsCall(
643 node, reporter, compiler.parsing, compiler.coreTypes, resolver); 620 node, reporter, compiler.parsing, compiler.coreTypes, resolver);
644 registerNativeBehavior(behavior, node); 621 registerNativeBehavior(behavior, node);
645 nativeBehaviors[node] = behavior; 622 nativeBehaviors[node] = behavior;
646 } 623 }
647 624
648
649 /** 625 /**
650 * Handles JS-embedded global calls, which can be an instantiation point for 626 * Handles JS-embedded global calls, which can be an instantiation point for
651 * types. 627 * types.
652 * 628 *
653 * For example, the following code instantiates and returns a String class 629 * For example, the following code instantiates and returns a String class
654 * 630 *
655 * JS_EMBEDDED_GLOBAL('String', 'foo') 631 * JS_EMBEDDED_GLOBAL('String', 'foo')
656 * 632 *
657 */ 633 */
658 void registerJsEmbeddedGlobalCall(Send node, ForeignResolver resolver) { 634 void registerJsEmbeddedGlobalCall(Send node, ForeignResolver resolver) {
659 NativeBehavior behavior = NativeBehavior.ofJsEmbeddedGlobalCall( 635 NativeBehavior behavior = NativeBehavior.ofJsEmbeddedGlobalCall(
660 node, reporter, compiler.parsing, compiler.coreTypes, resolver); 636 node, reporter, compiler.parsing, compiler.coreTypes, resolver);
661 registerNativeBehavior(behavior, node); 637 registerNativeBehavior(behavior, node);
662 nativeBehaviors[node] = behavior; 638 nativeBehaviors[node] = behavior;
663 } 639 }
664 640
665
666 /** 641 /**
667 * Handles JS-compiler builtin calls, which can be an instantiation point for 642 * Handles JS-compiler builtin calls, which can be an instantiation point for
668 * types. 643 * types.
669 * 644 *
670 * For example, the following code instantiates and returns a String class 645 * For example, the following code instantiates and returns a String class
671 * 646 *
672 * JS_BUILTIN('String', 'int2string', 0) 647 * JS_BUILTIN('String', 'int2string', 0)
673 * 648 *
674 */ 649 */
675 void registerJsBuiltinCall(Send node, ForeignResolver resolver) { 650 void registerJsBuiltinCall(Send node, ForeignResolver resolver) {
676 NativeBehavior behavior = NativeBehavior.ofJsBuiltinCall( 651 NativeBehavior behavior = NativeBehavior.ofJsBuiltinCall(
677 node, reporter, compiler.parsing, compiler.coreTypes, resolver); 652 node, reporter, compiler.parsing, compiler.coreTypes, resolver);
678 registerNativeBehavior(behavior, node); 653 registerNativeBehavior(behavior, node);
679 nativeBehaviors[node] = behavior; 654 nativeBehaviors[node] = behavior;
680 } 655 }
681 } 656 }
682 657
683
684 class NativeCodegenEnqueuer extends NativeEnqueuerBase { 658 class NativeCodegenEnqueuer extends NativeEnqueuerBase {
685
686 final CodeEmitterTask emitter; 659 final CodeEmitterTask emitter;
687 660
688 final Set<ClassElement> doneAddSubtypes = new Set<ClassElement>(); 661 final Set<ClassElement> doneAddSubtypes = new Set<ClassElement>();
689 662
690 NativeCodegenEnqueuer(Enqueuer world, Compiler compiler, this.emitter) 663 NativeCodegenEnqueuer(Enqueuer world, Compiler compiler, this.emitter)
691 : super(world, compiler, compiler.options.enableNativeLiveTypeAnalysis); 664 : super(world, compiler, compiler.options.enableNativeLiveTypeAnalysis);
692 665
693 void processNativeClasses(Iterable<LibraryElement> libraries) { 666 void processNativeClasses(Iterable<LibraryElement> libraries) {
694 super.processNativeClasses(libraries); 667 super.processNativeClasses(libraries);
695 668
696 // HACK HACK - add all the resolved classes. 669 // HACK HACK - add all the resolved classes.
697 NativeEnqueuerBase enqueuer = compiler.enqueuer.resolution.nativeEnqueuer; 670 NativeEnqueuerBase enqueuer = compiler.enqueuer.resolution.nativeEnqueuer;
698 for (final classElement in enqueuer.registeredClasses) { 671 for (final classElement in enqueuer.registeredClasses) {
699 if (unusedClasses.contains(classElement)) { 672 if (unusedClasses.contains(classElement)) {
700 enqueueClass(classElement, 'was resolved'); 673 enqueueClass(classElement, 'was resolved');
701 } 674 }
(...skipping 11 matching lines...) Expand all
713 void addSubtypes(ClassElement cls, NativeEmitter emitter) { 686 void addSubtypes(ClassElement cls, NativeEmitter emitter) {
714 if (!backend.isNative(cls)) return; 687 if (!backend.isNative(cls)) return;
715 if (doneAddSubtypes.contains(cls)) return; 688 if (doneAddSubtypes.contains(cls)) return;
716 doneAddSubtypes.add(cls); 689 doneAddSubtypes.add(cls);
717 690
718 // Walk the superclass chain since classes on the superclass chain might not 691 // Walk the superclass chain since classes on the superclass chain might not
719 // be instantiated (abstract or simply unused). 692 // be instantiated (abstract or simply unused).
720 addSubtypes(cls.superclass, emitter); 693 addSubtypes(cls.superclass, emitter);
721 694
722 for (DartType type in cls.allSupertypes) { 695 for (DartType type in cls.allSupertypes) {
723 List<Element> subtypes = emitter.subtypes.putIfAbsent( 696 List<Element> subtypes =
724 type.element, 697 emitter.subtypes.putIfAbsent(type.element, () => <ClassElement>[]);
725 () => <ClassElement>[]);
726 subtypes.add(cls); 698 subtypes.add(cls);
727 } 699 }
728 700
729 // Skip through all the mixin applications in the super class 701 // Skip through all the mixin applications in the super class
730 // chain. That way, the direct subtypes set only contain the 702 // chain. That way, the direct subtypes set only contain the
731 // natives classes. 703 // natives classes.
732 ClassElement superclass = cls.superclass; 704 ClassElement superclass = cls.superclass;
733 while (superclass != null && superclass.isMixinApplication) { 705 while (superclass != null && superclass.isMixinApplication) {
734 assert(!backend.isNative(superclass)); 706 assert(!backend.isNative(superclass));
735 superclass = superclass.superclass; 707 superclass = superclass.superclass;
736 } 708 }
737 709
738 List<Element> directSubtypes = emitter.directSubtypes.putIfAbsent( 710 List<Element> directSubtypes =
739 superclass, 711 emitter.directSubtypes.putIfAbsent(superclass, () => <ClassElement>[]);
740 () => <ClassElement>[]);
741 directSubtypes.add(cls); 712 directSubtypes.add(cls);
742 } 713 }
743 714
744 void logSummary(log(message)) { 715 void logSummary(log(message)) {
745 log('Compiled ${registeredClasses.length} native classes, ' 716 log('Compiled ${registeredClasses.length} native classes, '
746 '${unusedClasses.length} native classes omitted.'); 717 '${unusedClasses.length} native classes omitted.');
747 } 718 }
748 } 719 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/native/behavior.dart ('k') | pkg/compiler/lib/src/native/js.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698