| 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 final int CONSTRUCTOR = 0; | 17 static final int CONSTRUCTOR = 0; |
| 18 static final int EACH = 1; | 18 static final int EACH = 1; |
| 19 static final int WITH = 2; | 19 static final 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 isConstructor() => _blockType == CGBlock.CONSTRUCTOR; | 30 bool get isConstructor() => _blockType == CGBlock.CONSTRUCTOR; |
| 30 bool get isEach() => _blockType == CGBlock.EACH; | 31 bool get isEach() => _blockType == CGBlock.EACH; |
| 31 bool get isWith() => _blockType == CGBlock.WITH; | 32 bool get isWith() => _blockType == CGBlock.WITH; |
| 32 | 33 |
| 33 bool get hasLocalName() => _localName != null; | 34 bool get hasLocalName() => _localName != null; |
| 34 String get localName() => _localName; | 35 String get localName() => _localName; |
| 35 | 36 |
| 36 CGStatement push(var elem, var parentName, [bool exact = false]) { | 37 CGStatement push(var elem, var parentName, [bool exact = false]) { |
| 37 var varName; | 38 var varName; |
| 38 if (elem is TemplateElement && elem.hasVar) { | 39 if (elem is TemplateElement && elem.hasVar) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 54 | 55 |
| 55 void add(String value) { | 56 void add(String value) { |
| 56 if (_stmts.last() != null) { | 57 if (_stmts.last() != null) { |
| 57 _stmts.last().add(value); | 58 _stmts.last().add(value); |
| 58 } | 59 } |
| 59 } | 60 } |
| 60 | 61 |
| 61 CGStatement get last() => _stmts.length > 0 ? _stmts.last() : null; | 62 CGStatement get last() => _stmts.length > 0 ? _stmts.last() : null; |
| 62 | 63 |
| 63 /** | 64 /** |
| 64 * 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 |
| 65 * element is inside of a #each the name exposed is: | 66 * element is inside of a #each the name exposed is: |
| 66 * | 67 * |
| 67 * List varName; | 68 * List varName; |
| 68 * | 69 * |
| 69 * otherwise it's: | 70 * otherwise it's: |
| 70 * | 71 * |
| 71 * var varName; | 72 * var varName; |
| 72 * | 73 * |
| 73 * 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., |
| 74 * | 75 * |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 assert(fileParts.length == 2); | 267 assert(fileParts.length == 2); |
| 267 filename = fileParts[0]; | 268 filename = fileParts[0]; |
| 268 | 269 |
| 269 StringBuffer buff = new StringBuffer(); | 270 StringBuffer buff = new StringBuffer(); |
| 270 int injectId = 0; // Inject function id | 271 int injectId = 0; // Inject function id |
| 271 | 272 |
| 272 buff.add("// Generated Dart class from HTML template.\n"); | 273 buff.add("// Generated Dart class from HTML template.\n"); |
| 273 buff.add("// DO NOT EDIT.\n\n"); | 274 buff.add("// DO NOT EDIT.\n\n"); |
| 274 | 275 |
| 275 String addStylesheetFuncName = "add_${filename}_templatesStyles"; | 276 String addStylesheetFuncName = "add_${filename}_templatesStyles"; |
| 276 | 277 |
| 277 for (final template in templates) { | 278 for (final template in templates) { |
| 278 // Emit the template class. | 279 // Emit the template class. |
| 279 TemplateSignature sig = template.signature; | 280 TemplateSignature sig = template.signature; |
| 280 buff.add(_emitClass(sig.name, sig.params, template.content, | 281 buff.add(_emitClass(sig.name, sig.params, template.content, |
| 281 addStylesheetFuncName)); | 282 addStylesheetFuncName)); |
| 282 } | 283 } |
| 283 | 284 |
| 284 // TODO(terry): Stylesheet aggregator should not be global needs to be | 285 // TODO(terry): Stylesheet aggregator should not be global needs to be |
| 285 // bound to this template file not global to the app. | 286 // bound to this template file not global to the app. |
| 286 | 287 |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 511 List<String> expressions; // List of injection function declarations. | 512 List<String> expressions; // List of injection function declarations. |
| 512 List<String> eachs; // List of each function declarations. | 513 List<String> eachs; // List of each function declarations. |
| 513 List<String> withs; // List of with function declarations. | 514 List<String> withs; // List of with function declarations. |
| 514 | 515 |
| 515 ElemCG() : | 516 ElemCG() : |
| 516 expressions = [], | 517 expressions = [], |
| 517 eachs = [], | 518 eachs = [], |
| 518 withs = [], | 519 withs = [], |
| 519 _cgBlocks = [], | 520 _cgBlocks = [], |
| 520 _globalDecls = new StringBuffer(), | 521 _globalDecls = new StringBuffer(), |
| 521 _globalInits = new StringBuffer(); | 522 _globalInits = new StringBuffer(); |
| 522 | 523 |
| 523 bool get isLastBlockConstructor() { | 524 bool get isLastBlockConstructor() { |
| 524 CGBlock block = _cgBlocks.last(); | 525 CGBlock block = _cgBlocks.last(); |
| 525 return block.isConstructor; | 526 return block.isConstructor; |
| 526 } | 527 } |
| 527 | 528 |
| 528 List<String> activeBlocksLocalNames() { | 529 List<String> activeBlocksLocalNames() { |
| 529 List<String> result = []; | 530 List<String> result = []; |
| 530 | 531 |
| 531 for (final CGBlock block in _cgBlocks) { | 532 for (final CGBlock block in _cgBlocks) { |
| 532 if (block.isEach || block.isWith) { | 533 if (block.isEach || block.isWith) { |
| 533 if (block.hasLocalName) { | 534 if (block.hasLocalName) { |
| 534 result.add(block.localName); | 535 result.add(block.localName); |
| 535 } | 536 } |
| 536 } | 537 } |
| 537 } | 538 } |
| 538 | 539 |
| 539 return result; | 540 return result; |
| 540 } | 541 } |
| 541 | 542 |
| 542 /** | 543 /** |
| 543 * Active block with this localName. | 544 * Active block with this localName. |
| 544 */ | 545 */ |
| 545 bool matchBlocksLocalName(String name) { | 546 bool matchBlocksLocalName(String name) { |
| 546 for (final CGBlock block in _cgBlocks) { | 547 for (final CGBlock block in _cgBlocks) { |
| 547 if (block.isEach || block.isWith) { | 548 if (block.isEach || block.isWith) { |
| 548 if (block.hasLocalName && block.localName == name) { | 549 if (block.hasLocalName && block.localName == name) { |
| 549 return true; | 550 return true; |
| 550 } | 551 } |
| 551 } | 552 } |
| 552 } | 553 } |
| 553 | 554 |
| 554 return false; | 555 return false; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 663 String get globalInitializers() { | 664 String get globalInitializers() { |
| 664 assert(_cgBlocks.length == 1); // Only constructor body should be left. | 665 assert(_cgBlocks.length == 1); // Only constructor body should be left. |
| 665 _globalInits.add(lastBlock.globalInitializers); | 666 _globalInits.add(lastBlock.globalInitializers); |
| 666 return _globalInits.toString(); | 667 return _globalInits.toString(); |
| 667 } | 668 } |
| 668 | 669 |
| 669 String get codeBody() { | 670 String get codeBody() { |
| 670 closeStatement(); | 671 closeStatement(); |
| 671 return _cgBlocks.last().codeBody; | 672 return _cgBlocks.last().codeBody; |
| 672 } | 673 } |
| 673 | 674 |
| 674 /* scopeName for expression | 675 /* scopeName for expression |
| 675 * 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 |
| 676 * name (specified by the var attribute) for this element. | 677 * name (specified by the var attribute) for this element. |
| 677 * | 678 * |
| 678 */ | 679 */ |
| 679 emitElement(var elem, | 680 emitElement(var elem, |
| 680 [String scopeName = "", | 681 [String scopeName = "", |
| 681 var parentVarOrIdx = 0, | 682 var parentVarOrIdx = 0, |
| 682 bool immediateNestedEach = false]) { | 683 bool immediateNestedEach = false]) { |
| 683 if (elem is TemplateElement) { | 684 if (elem is TemplateElement) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 713 } | 714 } |
| 714 | 715 |
| 715 // TODO(terry): Need to interpolate following: | 716 // TODO(terry): Need to interpolate following: |
| 716 // {sp} → space | 717 // {sp} → space |
| 717 // {nil} → empty string | 718 // {nil} → empty string |
| 718 // {\r} → carriage return | 719 // {\r} → carriage return |
| 719 // {\n} → new line (line feed) | 720 // {\n} → new line (line feed) |
| 720 // {\t} → tab | 721 // {\t} → tab |
| 721 // {lb} → left brace | 722 // {lb} → left brace |
| 722 // {rb} → right brace | 723 // {rb} → right brace |
| 723 | 724 |
| 724 add("${outputValue}"); // remove leading/trailing whitespace. | 725 add("${outputValue}"); // remove leading/trailing whitespace. |
| 725 | 726 |
| 726 if (emitTextNode) { | 727 if (emitTextNode) { |
| 727 closeStatement(); | 728 closeStatement(); |
| 728 } | 729 } |
| 729 } | 730 } |
| 730 } else if (elem is TemplateExpression) { | 731 } else if (elem is TemplateExpression) { |
| 731 emitExpressions(elem, scopeName); | 732 emitExpressions(elem, scopeName); |
| 732 } else if (elem is TemplateEachCommand) { | 733 } else if (elem is TemplateEachCommand) { |
| 733 // Signal to caller new block coming in, returns "each_" prefix | 734 // Signal to caller new block coming in, returns "each_" prefix |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 815 | 816 |
| 816 emitExpressions(TemplateExpression elem, String scopeName) { | 817 emitExpressions(TemplateExpression elem, String scopeName) { |
| 817 StringBuffer func = new StringBuffer(); | 818 StringBuffer func = new StringBuffer(); |
| 818 | 819 |
| 819 String newExpr = elem.expression; | 820 String newExpr = elem.expression; |
| 820 bool anyNesting = isNestedNamedBlock(); | 821 bool anyNesting = isNestedNamedBlock(); |
| 821 if (scopeName.length > 0 && !anyNesting) { | 822 if (scopeName.length > 0 && !anyNesting) { |
| 822 // In a block #command need the scope passed in. | 823 // In a block #command need the scope passed in. |
| 823 add("\$\{inject_${expressions.length}(_item)\}"); | 824 add("\$\{inject_${expressions.length}(_item)\}"); |
| 824 func.add("\n String inject_${expressions.length}(var _item) {\n"); | 825 func.add("\n String inject_${expressions.length}(var _item) {\n"); |
| 825 // Escape all single-quotes, this expression is embedded as a string | 826 // Escape all single-quotes, this expression is embedded as a string |
| 826 // parameter for the call to safeHTML. | 827 // parameter for the call to safeHTML. |
| 827 newExpr = _resolveNames(newExpr.replaceAll("'", "\\'"), "_item"); | 828 newExpr = _resolveNames(newExpr.replaceAll("'", "\\'"), "_item"); |
| 828 } else { | 829 } else { |
| 829 // Not in a block #command item isn't passed in. | 830 // Not in a block #command item isn't passed in. |
| 830 add("\$\{inject_${expressions.length}()\}"); | 831 add("\$\{inject_${expressions.length}()\}"); |
| 831 func.add("\n String inject_${expressions.length}() {\n"); | 832 func.add("\n String inject_${expressions.length}() {\n"); |
| 832 | 833 |
| 833 if (anyNesting) { | 834 if (anyNesting) { |
| 834 func.add(defineScopes()); | 835 func.add(defineScopes()); |
| 835 } | 836 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 938 addScope(4, funcBuff, itemName); | 939 addScope(4, funcBuff, itemName); |
| 939 funcBuff.add(codeBody); | 940 funcBuff.add(codeBody); |
| 940 removeScope(4, funcBuff, itemName); | 941 removeScope(4, funcBuff, itemName); |
| 941 | 942 |
| 942 popBlock(); | 943 popBlock(); |
| 943 | 944 |
| 944 funcBuff.add(" }\n"); | 945 funcBuff.add(" }\n"); |
| 945 | 946 |
| 946 withs[withIndex] = funcBuff.toString(); | 947 withs[withIndex] = funcBuff.toString(); |
| 947 | 948 |
| 948 // Compute parent node variable before pushing with statement. | 949 // Compute parent node variable before pushing with statement. |
| 949 String parentVarName = lastBlockVarName; | 950 String parentVarName = lastBlockVarName; |
| 950 | 951 |
| 951 pushExactStatement(elem, parentVarIndex); | 952 pushExactStatement(elem, parentVarIndex); |
| 952 | 953 |
| 953 // 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 |
| 954 // in later when we known the parent variable. | 955 // in later when we known the parent variable. |
| 955 add("${funcName}(${withName}, ${parentVarName})"); | 956 add("${funcName}(${withName}, ${parentVarName})"); |
| 956 } | 957 } |
| 957 | 958 |
| 958 String get lastBlockVarName() { | 959 String get lastBlockVarName() { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1003 for (String name in names) { | 1004 for (String name in names) { |
| 1004 buff.add(" var ${name} = _scopes[\"${name}\"];\n"); | 1005 buff.add(" var ${name} = _scopes[\"${name}\"];\n"); |
| 1005 } | 1006 } |
| 1006 buff.add("\n"); | 1007 buff.add("\n"); |
| 1007 } | 1008 } |
| 1008 | 1009 |
| 1009 return buff.toString(); | 1010 return buff.toString(); |
| 1010 } | 1011 } |
| 1011 | 1012 |
| 1012 } | 1013 } |
| OLD | NEW |