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

Side by Side Diff: lib/src/emitters.dart

Issue 12225039: Support for observable models, fixes #259 (Closed) Base URL: https://github.com/dart-lang/web-ui.git@master
Patch Set: small formatting fixes Created 7 years, 10 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
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 /** Collects several code emitters for the template tool. */ 5 /** Collects several code emitters for the template tool. */
6 library emitters; 6 library emitters;
7 7
8 import 'dart:json' as json; 8 import 'dart:json' as json;
9 9
10 import 'package:csslib/parser.dart' as css; 10 import 'package:csslib/parser.dart' as css;
11 import 'package:csslib/visitor.dart'; 11 import 'package:csslib/visitor.dart';
12 import 'package:html5lib/dom.dart'; 12 import 'package:html5lib/dom.dart';
13 import 'package:html5lib/dom_parsing.dart'; 13 import 'package:html5lib/dom_parsing.dart';
14 import 'package:source_maps/span.dart' show Span, FixedLocation; 14 import 'package:source_maps/span.dart' show Span, FixedLocation;
15 15
16 import 'code_printer.dart'; 16 import 'code_printer.dart';
17 import 'codegen.dart' as codegen; 17 import 'codegen.dart' as codegen;
18 import 'dart_parser.dart' show DartCodeInfo;
18 import 'html5_utils.dart'; 19 import 'html5_utils.dart';
19 import 'html5_setters.g.dart'; 20 import 'html5_setters.g.dart';
20 import 'info.dart'; 21 import 'info.dart';
21 import 'messages.dart'; 22 import 'messages.dart';
22 import 'utils.dart'; 23 import 'utils.dart';
23 24
24 /** 25 /**
25 * Context used by an emitter. Typically representing where to generate code 26 * Context used by an emitter. Typically representing where to generate code
26 * and additional information, such as total number of generated identifiers. 27 * and additional information, such as total number of generated identifiers.
27 */ 28 */
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 } 429 }
429 430
430 visit(elemInfo); 431 visit(elemInfo);
431 432
432 bool hasExtends = info.extendsComponent != null; 433 bool hasExtends = info.extendsComponent != null;
433 var codeInfo = info.userCode; 434 var codeInfo = info.userCode;
434 if (codeInfo == null) { 435 if (codeInfo == null) {
435 var superclass = hasExtends ? info.extendsComponent.constructor 436 var superclass = hasExtends ? info.extendsComponent.constructor
436 : 'autogenerated.WebComponent'; 437 : 'autogenerated.WebComponent';
437 codeInfo = new DartCodeInfo(null, null, [], 438 codeInfo = new DartCodeInfo(null, null, [],
438 'class ${info.constructor} extends $superclass {\n}'); 439 'class ${info.constructor} extends $superclass {\n}', null);
439 } 440 }
440 441
441 var code = codeInfo.code; 442 var code = codeInfo.code;
442 var match = new RegExp('class ${info.constructor}[^{]*{').firstMatch(code); 443 var match = codeInfo.findClass(info.constructor);
443 if (match != null) { 444 if (match != null) {
444 var printer = new CodePrinter(0); 445 var printer = new CodePrinter(0);
445 var libraryName = (codeInfo.libraryName != null) 446 var libraryName = (codeInfo.libraryName != null)
446 ? codeInfo.libraryName 447 ? codeInfo.libraryName
447 : info.tagName.replaceAll(new RegExp('[-./]'), '_'); 448 : info.tagName.replaceAll(new RegExp('[-./]'), '_');
448 var declaringPath = info.declaringFile.path; 449 var declaringPath = info.declaringFile.path;
449 printer.addLine(codegen.header(declaringPath, libraryName)); 450 printer.addLine(codegen.header(declaringPath, libraryName));
450 451
451 // Add exisitng import, export, and part directives. 452 // Add existing import, export, and part directives.
452 for (var directive in codeInfo.directives) { 453 for (var directive in codeInfo.directives) {
453 printer.addLine(codegen.directiveText(directive, info, pathInfo)); 454 // TODO(jmesserly): add span here
455 printer.addLine(directive.toString());
454 } 456 }
455 457
456 // Add imports only for those components used by this component. 458 // Add imports only for those components used by this component.
457 var imports = info.usedComponents.keys.map( 459 var imports = info.usedComponents.keys.map(
458 (c) => pathInfo.relativePath(info, c)); 460 (c) => pathInfo.relativePath(info, c));
459 461
460 if (hasExtends) { 462 if (hasExtends) {
461 // Inject an import to the base component. 463 // Inject an import to the base component.
462 printer.addLine(codegen.importList( 464 printer.addLine(codegen.importList(
463 [pathInfo.relativePath(info, info.extendsComponent)])); 465 [pathInfo.relativePath(info, info.extendsComponent)]));
464 } 466 }
465 467
466 var cssClasses = json.stringify( 468 var cssClasses = json.stringify(
467 computeCssClasses(info, scopedStyles: cssPolyfill)); 469 computeCssClasses(info, scopedStyles: cssPolyfill));
468 return printer 470 return printer
469 ..add(codegen.importList(imports), 471 ..add(codegen.importList(imports),
470 location: new FixedLocation(0, declaringPath.toString(), 0, 0)) 472 location: new FixedLocation(0, declaringPath.toString(), 0, 0))
471 ..addLine('') 473 ..addLine('')
472 ..add(code.substring(0, match.end)) 474 // TODO(jmesserly): add span here
475 ..add(code.substring(codeInfo.directivesEnd, match.leftBracket.end))
473 ..add('\n') 476 ..add('\n')
474 ..indent += 1 477 ..indent += 1
475 ..addLine('/** Autogenerated from the template. */') 478 ..addLine('/** Autogenerated from the template. */')
476 ..addLine('') 479 ..addLine('')
477 ..addLine('/** CSS class constants. */') 480 ..addLine('/** CSS class constants. */')
478 ..addLine('static Map<String, String> _css = $cssClasses;') 481 ..addLine('static Map<String, String> _css = $cssClasses;')
479 ..addLine('') 482 ..addLine('')
480 ..addLine('/**') 483 ..addLine('/**')
481 ..addLine(" * Shadow root for this component. We use 'var' to allow" 484 ..addLine(" * Shadow root for this component. We use 'var' to allow"
482 " simulating shadow DOM") 485 " simulating shadow DOM")
(...skipping 25 matching lines...) Expand all
508 ..addLine(_clearFields(_context.declarations)) 511 ..addLine(_clearFields(_context.declarations))
509 ..addLine('}') 512 ..addLine('}')
510 ..addLine('') 513 ..addLine('')
511 ..addLine('void composeChildren() {') 514 ..addLine('void composeChildren() {')
512 ..addLine(' super.composeChildren();') 515 ..addLine(' super.composeChildren();')
513 ..addLine(' if (_root is! autogenerated.ShadowRoot) _root = this;') 516 ..addLine(' if (_root is! autogenerated.ShadowRoot) _root = this;')
514 ..addLine('}') 517 ..addLine('}')
515 ..addLine('') 518 ..addLine('')
516 ..addLine('/** Original code from the component. */') 519 ..addLine('/** Original code from the component. */')
517 ..indent -= 1 520 ..indent -= 1
518 ..add(code.substring(match.end)); 521 // TODO(jmesserly): add span here
522 ..add(code.substring(match.leftBracket.end));
523
519 } else { 524 } else {
520 messages.error('please provide a class definition ' 525 messages.error('please provide a class definition '
521 'for ${info.constructor}:\n $code', info.element.sourceSpan, 526 'for ${info.constructor}:\n $code', info.element.sourceSpan,
522 file: info.inputPath); 527 file: info.inputPath);
523 return null; 528 return null;
524 } 529 }
525 } 530 }
526 } 531 }
527 532
528 /** Generates the class corresponding to the main html page. */ 533 /** Generates the class corresponding to the main html page. */
529 class MainPageEmitter extends RecursiveEmitter { 534 class MainPageEmitter extends RecursiveEmitter {
530 MainPageEmitter(FileInfo fileInfo) : super(fileInfo, new Context(indent: 1)); 535 MainPageEmitter(FileInfo fileInfo) : super(fileInfo, new Context(indent: 1));
531 536
532 CodePrinter run(Document document, PathInfo pathInfo) { 537 CodePrinter run(Document document, PathInfo pathInfo) {
533 visit(_fileInfo.bodyInfo); 538 visit(_fileInfo.bodyInfo);
534 539
535 // fix up the URLs to content that is not modified by the compiler 540 // fix up the URLs to content that is not modified by the compiler
536 document.queryAll('script').forEach((tag) { 541 document.queryAll('script').forEach((tag) {
537 var src = tag.attributes["src"]; 542 var src = tag.attributes["src"];
538 if (tag.attributes['type'] == 'application/dart') { 543 if (tag.attributes['type'] == 'application/dart') {
539 tag.remove(); 544 tag.remove();
540 } else if (src != null) { 545 } else if (src != null) {
541 tag.attributes["src"] = pathInfo.transformUrl(_fileInfo.path, src); 546 tag.attributes["src"] = pathInfo.transformUrl(_fileInfo.path, src);
542 } 547 }
543 }); 548 });
544 document.queryAll('link').forEach((tag) { 549 document.queryAll('link').forEach((tag) {
545 var href = tag.attributes['href']; 550 var href = tag.attributes['href'];
546 if (tag.attributes['rel'] == 'components') { 551 if (tag.attributes['rel'] == 'components') {
547 tag.remove(); 552 tag.remove();
548 } else if (href != null) { 553 } else if (href != null) {
549 tag.attributes['href'] = pathInfo.transformUrl(_fileInfo.path, href); 554 tag.attributes['href'] = pathInfo.transformUrl(_fileInfo.path, href);
550 } 555 }
551 }); 556 });
552 557
553 var printer = new CodePrinter(0); 558 var printer = new CodePrinter(0);
554 559
555 // Inject library name if not pressent. 560 // Inject library name if not pressent.
556 var codeInfo = _fileInfo.userCode; 561 var codeInfo = _fileInfo.userCode;
557 if (codeInfo == null) { 562 if (codeInfo == null) {
558 codeInfo = new DartCodeInfo(null, null, [], 'main(){\n}'); 563 codeInfo = new DartCodeInfo(null, null, [], 'main(){\n}');
559 } 564 }
560 var libraryName = codeInfo.libraryName != null 565 var libraryName = codeInfo.libraryName != null
561 ? codeInfo.libraryName : _fileInfo.libraryName; 566 ? codeInfo.libraryName : _fileInfo.libraryName;
562 printer.add(codegen.header(_fileInfo.path, libraryName)); 567 printer.add(codegen.header(_fileInfo.path, libraryName));
563 568
564 // Add exisitng import, export, and part directives. 569 // Add existing import, export, and part directives.
565 for (var directive in codeInfo.directives) { 570 for (var directive in codeInfo.directives) {
566 printer.addLine(codegen.directiveText(directive, _fileInfo, pathInfo)); 571 // TODO(jmesserly): add span here
572 printer.addLine(directive.toString());
567 } 573 }
568 574
569 // Import only those components used by the page. 575 // Import only those components used by the page.
570 var imports = _fileInfo.usedComponents.keys.map( 576 var imports = _fileInfo.usedComponents.keys.map(
571 (c) => pathInfo.relativePath(_fileInfo, c)); 577 (c) => pathInfo.relativePath(_fileInfo, c));
572 return printer..add(codegen.importList(imports)) 578 return printer..add(codegen.importList(imports))
573 ..addLine('') 579 ..addLine('')
574 ..addLine('') 580 ..addLine('')
575 ..addLine('// Original code') 581 ..addLine('// Original code')
576 ..add(codeInfo.code) 582 // TODO(jmesserly): add span here
577 ..addLine('') 583 ..add(codeInfo.codeAfterDirectives())
578 ..addLine('// Additional generated code') 584 ..addLine('')
579 ..addLine('void init_autogenerated() {') 585 ..addLine('// Additional generated code')
580 ..indent += 1 586 ..addLine('void init_autogenerated() {')
581 ..addLine('var _root = autogenerated.document.body;') 587 ..indent += 1
582 ..add(_context.declarations) 588 ..addLine('var _root = autogenerated.document.body;')
583 ..addLine('var __t = new autogenerated.Template(_root);') 589 ..add(_context.declarations)
584 ..add(_context.printer) 590 ..addLine('var __t = new autogenerated.Template(_root);')
585 ..addLine('__t.create();') 591 ..add(_context.printer)
586 ..addLine('__t..insert();') 592 ..addLine('__t.create();')
587 ..indent -= 1 593 ..addLine('__t..insert();')
588 ..addLine('}'); 594 ..indent -= 1
595 ..addLine('}');
589 } 596 }
590 } 597 }
591 598
599 /** Emits a .dart file using the [DartCodeInfo]. */
600 CodePrinter emitDartFile(FileInfo fileInfo, PathInfo pathInfo) {
601 var printer = new CodePrinter(0);
602
603 // Inject library name if not pressent.
604 var codeInfo = fileInfo.userCode;
605 var libraryName = codeInfo.libraryName;
Siggi Cherem (dart-lang) 2013/02/13 01:43:24 unused variable
Jennifer Messerly 2013/02/13 05:43:15 Done. Also fixed "pressent" typo I had copied
606 printer.add(codegen.header(fileInfo.path, codeInfo.libraryName));
607
608 // Add existing import, export, and part directives.
609 // TODO(jmesserly): add spans here
610 for (var directive in codeInfo.directives) {
611 printer.addLine(directive.toString());
612 }
613 printer.add(codeInfo.codeAfterDirectives());
614 return printer;
615 }
616
592 /** Clears all fields in [declarations]. */ 617 /** Clears all fields in [declarations]. */
593 String _clearFields(Declarations declarations) { 618 String _clearFields(Declarations declarations) {
594 if (declarations.declarations.isEmpty) return ''; 619 if (declarations.declarations.isEmpty) return '';
595 var buff = new StringBuffer(); 620 var buff = new StringBuffer();
596 for (var d in declarations.declarations) { 621 for (var d in declarations.declarations) {
597 buff.add('${d.name} = '); 622 buff.add('${d.name} = ');
598 } 623 }
599 buff.add('null;'); 624 buff.add('null;');
600 return buff.toString(); 625 return buff.toString();
601 } 626 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 } 680 }
656 typeName = htmlElementExtends[typeName]; 681 typeName = htmlElementExtends[typeName];
657 } 682 }
658 // If we didn't find a DOM setter, and this is a component, set a property on 683 // If we didn't find a DOM setter, and this is a component, set a property on
659 // the component. 684 // the component.
660 if (info.component != null && !name.startsWith('data-')) { 685 if (info.component != null && !name.startsWith('data-')) {
661 return 'xtag.${toCamelCase(name)}'; 686 return 'xtag.${toCamelCase(name)}';
662 } 687 }
663 return "attributes['$name']"; 688 return "attributes['$name']";
664 } 689 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698