OLD | NEW |
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 class CGBlock { | 5 class CGBlock { |
6 int _blockType; // Code type of this block | 6 int _blockType; // Code type of this block |
7 int _indent; // Number of spaces to prefix for each statement | 7 int _indent; // Number of spaces to prefix for each statement |
8 bool _inEach; // This block or any currently active blocks is a | 8 bool _inEach; // This block or any currently active blocks is a |
9 // #each. If so then any element marked with a | 9 // #each. If so then any element marked with a |
10 // var attribute is repeated therefore the var | 10 // var attribute is repeated therefore the var |
11 // is a List type instead of an Element type. | 11 // is a List type instead of an Element type. |
12 String _localName; // optional local name for #each or #with | 12 String _localName; // optional local name for #each or #with |
13 List<CGStatement> _stmts; | 13 List<CGStatement> _stmts; |
14 int localIndex; // Local variable index (e.g., e0, e1, etc.) | 14 int localIndex; // Local variable index (e.g., e0, e1, etc.) |
15 | 15 |
16 // Block Types: | 16 // Block Types: |
17 static const int CONSTRUCTOR = 0; | 17 static const int CONSTRUCTOR = 0; |
18 static const int EACH = 1; | 18 static const int EACH = 1; |
19 static const int WITH = 2; | 19 static const int WITH = 2; |
20 | 20 |
21 CGBlock([this._indent = 4, | 21 CGBlock([this._indent = 4, |
22 this._blockType = CGBlock.CONSTRUCTOR, | 22 this._blockType = CGBlock.CONSTRUCTOR, |
23 this._inEach = false, | 23 this._inEach = false, |
24 this._localName = null]) : | 24 this._localName = null]) : |
25 _stmts = new List<CGStatement>(), localIndex = 0 { | 25 _stmts = new List<CGStatement>(), localIndex = 0 { |
26 assert(_blockType >= CGBlock.CONSTRUCTOR && _blockType <= CGBlock.WITH); | 26 assert(_blockType >= CGBlock.CONSTRUCTOR && _blockType <= CGBlock.WITH); |
27 } | 27 } |
28 | 28 |
29 bool get anyStatements() => !_stmts.isEmpty(); | 29 bool get anyStatements => !_stmts.isEmpty(); |
30 bool get isConstructor() => _blockType == CGBlock.CONSTRUCTOR; | 30 bool get isConstructor => _blockType == CGBlock.CONSTRUCTOR; |
31 bool get isEach() => _blockType == CGBlock.EACH; | 31 bool get isEach => _blockType == CGBlock.EACH; |
32 bool get isWith() => _blockType == CGBlock.WITH; | 32 bool get isWith => _blockType == CGBlock.WITH; |
33 | 33 |
34 bool get hasLocalName() => _localName != null; | 34 bool get hasLocalName => _localName != null; |
35 String get localName() => _localName; | 35 String get localName => _localName; |
36 | 36 |
37 CGStatement push(var elem, var parentName, [bool exact = false]) { | 37 CGStatement push(var elem, var parentName, [bool exact = false]) { |
38 var varName; | 38 var varName; |
39 if (elem is TemplateElement && elem.hasVar) { | 39 if (elem is TemplateElement && elem.hasVar) { |
40 varName = elem.varName; | 40 varName = elem.varName; |
41 } else { | 41 } else { |
42 varName = localIndex++; | 42 varName = localIndex++; |
43 } | 43 } |
44 | 44 |
45 CGStatement stmt = new CGStatement(elem, _indent, parentName, varName, | 45 CGStatement stmt = new CGStatement(elem, _indent, parentName, varName, |
46 exact, _inEach); | 46 exact, _inEach); |
47 _stmts.add(stmt); | 47 _stmts.add(stmt); |
48 | 48 |
49 return stmt; | 49 return stmt; |
50 } | 50 } |
51 | 51 |
52 void pop() { | 52 void pop() { |
53 _stmts.removeLast(); | 53 _stmts.removeLast(); |
54 } | 54 } |
55 | 55 |
56 void add(String value) { | 56 void add(String value) { |
57 if (_stmts.last() != null) { | 57 if (_stmts.last() != null) { |
58 _stmts.last().add(value); | 58 _stmts.last().add(value); |
59 } | 59 } |
60 } | 60 } |
61 | 61 |
62 CGStatement get last() => _stmts.length > 0 ? _stmts.last() : null; | 62 CGStatement get last => _stmts.length > 0 ? _stmts.last() : null; |
63 | 63 |
64 /** | 64 /** |
65 * Returns mixed list of elements marked with the var attribute. If the | 65 * Returns mixed list of elements marked with the var attribute. If the |
66 * element is inside of a #each the name exposed is: | 66 * element is inside of a #each the name exposed is: |
67 * | 67 * |
68 * List varName; | 68 * List varName; |
69 * | 69 * |
70 * otherwise it's: | 70 * otherwise it's: |
71 * | 71 * |
72 * var varName; | 72 * var varName; |
73 * | 73 * |
74 * TODO(terry): For scalars var varName should be Element tag type e.g., | 74 * TODO(terry): For scalars var varName should be Element tag type e.g., |
75 * | 75 * |
76 * DivElement varName; | 76 * DivElement varName; |
77 */ | 77 */ |
78 String get globalDeclarations() { | 78 String get globalDeclarations { |
79 StringBuffer buff = new StringBuffer(); | 79 StringBuffer buff = new StringBuffer(); |
80 for (final CGStatement stmt in _stmts) { | 80 for (final CGStatement stmt in _stmts) { |
81 buff.add(stmt.globalDeclaration()); | 81 buff.add(stmt.globalDeclaration()); |
82 } | 82 } |
83 | 83 |
84 return buff.toString(); | 84 return buff.toString(); |
85 } | 85 } |
86 | 86 |
87 /** | 87 /** |
88 * List of statement constructors for each var inside a #each. | 88 * List of statement constructors for each var inside a #each. |
89 * | 89 * |
90 * ${#each products} | 90 * ${#each products} |
91 * <div var=myVar>...</div> | 91 * <div var=myVar>...</div> |
92 * ${/each} | 92 * ${/each} |
93 * | 93 * |
94 * returns: | 94 * returns: |
95 * | 95 * |
96 * myVar = []; | 96 * myVar = []; |
97 */ | 97 */ |
98 String get globalInitializers() { | 98 String get globalInitializers { |
99 StringBuffer buff = new StringBuffer(); | 99 StringBuffer buff = new StringBuffer(); |
100 for (final CGStatement stmt in _stmts) { | 100 for (final CGStatement stmt in _stmts) { |
101 buff.add(stmt.globalInitializers()); | 101 buff.add(stmt.globalInitializers()); |
102 } | 102 } |
103 | 103 |
104 return buff.toString(); | 104 return buff.toString(); |
105 } | 105 } |
106 | 106 |
107 String get codeBody() { | 107 String get codeBody { |
108 StringBuffer buff = new StringBuffer(); | 108 StringBuffer buff = new StringBuffer(); |
109 | 109 |
110 for (final CGStatement stmt in _stmts) { | 110 for (final CGStatement stmt in _stmts) { |
111 buff.add(stmt.emitDartStatement()); | 111 buff.add(stmt.emitDartStatement()); |
112 } | 112 } |
113 | 113 |
114 return buff.toString(); | 114 return buff.toString(); |
115 } | 115 } |
116 } | 116 } |
117 | 117 |
(...skipping 16 matching lines...) Expand all Loading... |
134 // We have the global variable name | 134 // We have the global variable name |
135 varName = varNameOrIndex; | 135 varName = varNameOrIndex; |
136 _globalVariable = true; | 136 _globalVariable = true; |
137 } else { | 137 } else { |
138 // local index generate local variable name. | 138 // local index generate local variable name. |
139 varName = "e${varNameOrIndex}"; | 139 varName = "e${varNameOrIndex}"; |
140 _globalVariable = false; | 140 _globalVariable = false; |
141 } | 141 } |
142 } | 142 } |
143 | 143 |
144 bool get hasGlobalVariable() => _globalVariable; | 144 bool get hasGlobalVariable => _globalVariable; |
145 String get variableName() => varName; | 145 String get variableName => varName; |
146 | 146 |
147 String globalDeclaration() { | 147 String globalDeclaration() { |
148 if (hasGlobalVariable) { | 148 if (hasGlobalVariable) { |
149 String spaces = Codegen.spaces(_indent); | 149 String spaces = Codegen.spaces(_indent); |
150 return (_repeating) ? | 150 return (_repeating) ? |
151 " List ${varName}; // Repeated elements.\n" : " var ${varName};\n"; | 151 " List ${varName}; // Repeated elements.\n" : " var ${varName};\n"; |
152 } | 152 } |
153 | 153 |
154 return ""; | 154 return ""; |
155 } | 155 } |
156 | 156 |
157 String globalInitializers() { | 157 String globalInitializers() { |
158 if (hasGlobalVariable && _repeating) { | 158 if (hasGlobalVariable && _repeating) { |
159 return " ${varName} = [];\n"; | 159 return " ${varName} = [];\n"; |
160 } | 160 } |
161 | 161 |
162 return ""; | 162 return ""; |
163 } | 163 } |
164 | 164 |
165 void add(String value) { | 165 void add(String value) { |
166 _buff.add(value); | 166 _buff.add(value); |
167 } | 167 } |
168 | 168 |
169 bool get isClosed() => _closed; | 169 bool get isClosed => _closed; |
170 | 170 |
171 void close() { | 171 void close() { |
172 if (_elem is TemplateElement && _elem.scoped) { | 172 if (_elem is TemplateElement && _elem.scoped) { |
173 add("</${_elem.tagName}>"); | 173 add("</${_elem.tagName}>"); |
174 } | 174 } |
175 _closed = true; | 175 _closed = true; |
176 } | 176 } |
177 | 177 |
178 String emitDartStatement() { | 178 String emitDartStatement() { |
179 StringBuffer statement = new StringBuffer(); | 179 StringBuffer statement = new StringBuffer(); |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 buff.add(" ${addStylesheetFuncName}();\n\n"); | 429 buff.add(" ${addStylesheetFuncName}();\n\n"); |
430 | 430 |
431 buff.add(" _fragment = new DocumentFragment();\n"); | 431 buff.add(" _fragment = new DocumentFragment();\n"); |
432 | 432 |
433 buff.add(ecg.codeBody); // HTML for constructor to build. | 433 buff.add(ecg.codeBody); // HTML for constructor to build. |
434 | 434 |
435 buff.add(" }\n\n"); // End constructor | 435 buff.add(" }\n\n"); // End constructor |
436 | 436 |
437 buff.add(emitGetters(content.getters)); | 437 buff.add(emitGetters(content.getters)); |
438 | 438 |
439 buff.add(" Element get root() => _fragment;\n"); | 439 buff.add(" Element get root => _fragment;\n"); |
440 | 440 |
441 // Emit all CSS class selectors: | 441 // Emit all CSS class selectors: |
442 buff.add(_emitCSSSelectors(content.css)); | 442 buff.add(_emitCSSSelectors(content.css)); |
443 | 443 |
444 // Emit the injection functions. | 444 // Emit the injection functions. |
445 buff.add("\n // Injection functions:"); | 445 buff.add("\n // Injection functions:"); |
446 for (final expr in ecg.expressions) { | 446 for (final expr in ecg.expressions) { |
447 buff.add("${expr}"); | 447 buff.add("${expr}"); |
448 } | 448 } |
449 | 449 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
514 List<String> withs; // List of with function declarations. | 514 List<String> withs; // List of with function declarations. |
515 | 515 |
516 ElemCG() : | 516 ElemCG() : |
517 expressions = [], | 517 expressions = [], |
518 eachs = [], | 518 eachs = [], |
519 withs = [], | 519 withs = [], |
520 _cgBlocks = [], | 520 _cgBlocks = [], |
521 _globalDecls = new StringBuffer(), | 521 _globalDecls = new StringBuffer(), |
522 _globalInits = new StringBuffer(); | 522 _globalInits = new StringBuffer(); |
523 | 523 |
524 bool get isLastBlockConstructor() { | 524 bool get isLastBlockConstructor { |
525 CGBlock block = _cgBlocks.last(); | 525 CGBlock block = _cgBlocks.last(); |
526 return block.isConstructor; | 526 return block.isConstructor; |
527 } | 527 } |
528 | 528 |
529 List<String> activeBlocksLocalNames() { | 529 List<String> activeBlocksLocalNames() { |
530 List<String> result = []; | 530 List<String> result = []; |
531 | 531 |
532 for (final CGBlock block in _cgBlocks) { | 532 for (final CGBlock block in _cgBlocks) { |
533 if (block.isEach || block.isWith) { | 533 if (block.isEach || block.isWith) { |
534 if (block.hasLocalName) { | 534 if (block.hasLocalName) { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
618 } | 618 } |
619 | 619 |
620 CGStatement pushStatement(var elem, var parentName) { | 620 CGStatement pushStatement(var elem, var parentName) { |
621 return lastBlock.push(elem, parentName, false); | 621 return lastBlock.push(elem, parentName, false); |
622 } | 622 } |
623 | 623 |
624 CGStatement pushExactStatement(var elem, var parentName) { | 624 CGStatement pushExactStatement(var elem, var parentName) { |
625 return lastBlock.push(elem, parentName, true); | 625 return lastBlock.push(elem, parentName, true); |
626 } | 626 } |
627 | 627 |
628 bool get isClosedStatement() { | 628 bool get isClosedStatement { |
629 return (lastBlock != null && lastBlock.last != null) ? | 629 return (lastBlock != null && lastBlock.last != null) ? |
630 lastBlock.last.isClosed : false; | 630 lastBlock.last.isClosed : false; |
631 } | 631 } |
632 | 632 |
633 void closeStatement() { | 633 void closeStatement() { |
634 if (lastBlock != null && lastBlock.last != null && | 634 if (lastBlock != null && lastBlock.last != null && |
635 !lastBlock.last.isClosed) { | 635 !lastBlock.last.isClosed) { |
636 lastBlock.last.close(); | 636 lastBlock.last.close(); |
637 } | 637 } |
638 } | 638 } |
639 | 639 |
640 String get lastVariableName() { | 640 String get lastVariableName { |
641 if (lastBlock != null && lastBlock.last != null) { | 641 if (lastBlock != null && lastBlock.last != null) { |
642 return lastBlock.last.variableName; | 642 return lastBlock.last.variableName; |
643 } | 643 } |
644 } | 644 } |
645 | 645 |
646 String get lastParentName() { | 646 String get lastParentName { |
647 if (lastBlock != null && lastBlock.last != null) { | 647 if (lastBlock != null && lastBlock.last != null) { |
648 return lastBlock.last.parentName; | 648 return lastBlock.last.parentName; |
649 } | 649 } |
650 } | 650 } |
651 | 651 |
652 CGBlock get lastBlock() => _cgBlocks.length > 0 ? _cgBlocks.last() : null; | 652 CGBlock get lastBlock => _cgBlocks.length > 0 ? _cgBlocks.last() : null; |
653 | 653 |
654 void add(String str) { | 654 void add(String str) { |
655 _cgBlocks.last().add(str); | 655 _cgBlocks.last().add(str); |
656 } | 656 } |
657 | 657 |
658 String get globalDeclarations() { | 658 String get globalDeclarations { |
659 assert(_cgBlocks.length == 1); // Only constructor body should be left. | 659 assert(_cgBlocks.length == 1); // Only constructor body should be left. |
660 _globalDecls.add(lastBlock.globalDeclarations); | 660 _globalDecls.add(lastBlock.globalDeclarations); |
661 return _globalDecls.toString(); | 661 return _globalDecls.toString(); |
662 } | 662 } |
663 | 663 |
664 String get globalInitializers() { | 664 String get globalInitializers { |
665 assert(_cgBlocks.length == 1); // Only constructor body should be left. | 665 assert(_cgBlocks.length == 1); // Only constructor body should be left. |
666 _globalInits.add(lastBlock.globalInitializers); | 666 _globalInits.add(lastBlock.globalInitializers); |
667 return _globalInits.toString(); | 667 return _globalInits.toString(); |
668 } | 668 } |
669 | 669 |
670 String get codeBody() { | 670 String get codeBody { |
671 closeStatement(); | 671 closeStatement(); |
672 return _cgBlocks.last().codeBody; | 672 return _cgBlocks.last().codeBody; |
673 } | 673 } |
674 | 674 |
675 /* scopeName for expression | 675 /* scopeName for expression |
676 * parentVarOrIndex if # it's a local variable if string it's an exposed | 676 * parentVarOrIndex if # it's a local variable if string it's an exposed |
677 * name (specified by the var attribute) for this element. | 677 * name (specified by the var attribute) for this element. |
678 * | 678 * |
679 */ | 679 */ |
680 emitElement(var elem, | 680 emitElement(var elem, |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
949 // Compute parent node variable before pushing with statement. | 949 // Compute parent node variable before pushing with statement. |
950 String parentVarName = lastBlockVarName; | 950 String parentVarName = lastBlockVarName; |
951 | 951 |
952 pushExactStatement(elem, parentVarIndex); | 952 pushExactStatement(elem, parentVarIndex); |
953 | 953 |
954 // Setup call to each func as "each_n(xxxxx, " the parent param is filled | 954 // Setup call to each func as "each_n(xxxxx, " the parent param is filled |
955 // in later when we known the parent variable. | 955 // in later when we known the parent variable. |
956 add("${funcName}(${withName}, ${parentVarName})"); | 956 add("${funcName}(${withName}, ${parentVarName})"); |
957 } | 957 } |
958 | 958 |
959 String get lastBlockVarName() { | 959 String get lastBlockVarName { |
960 var varName; | 960 var varName; |
961 if (lastBlock != null && lastBlock.anyStatements) { | 961 if (lastBlock != null && lastBlock.anyStatements) { |
962 varName = lastBlock.last.variableName; | 962 varName = lastBlock.last.variableName; |
963 } else { | 963 } else { |
964 varName = "_fragment"; | 964 varName = "_fragment"; |
965 } | 965 } |
966 | 966 |
967 return varName; | 967 return varName; |
968 } | 968 } |
969 | 969 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1004 for (String name in names) { | 1004 for (String name in names) { |
1005 buff.add(" var ${name} = _scopes[\"${name}\"];\n"); | 1005 buff.add(" var ${name} = _scopes[\"${name}\"];\n"); |
1006 } | 1006 } |
1007 buff.add("\n"); | 1007 buff.add("\n"); |
1008 } | 1008 } |
1009 | 1009 |
1010 return buff.toString(); | 1010 return buff.toString(); |
1011 } | 1011 } |
1012 | 1012 |
1013 } | 1013 } |
OLD | NEW |