| 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 |