@herb-tools/node 0.9.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/binding.gyp +1 -0
  2. package/dist/herb-node.cjs +1 -1
  3. package/dist/herb-node.esm.js +1 -1
  4. package/extension/error_helpers.cpp +204 -1
  5. package/extension/error_helpers.h +8 -1
  6. package/extension/extension_helpers.cpp +3 -1
  7. package/extension/herb.cpp +11 -0
  8. package/extension/libherb/analyze/action_view/attribute_extraction_helpers.c +14 -1
  9. package/extension/libherb/analyze/action_view/content_tag.c +19 -11
  10. package/extension/libherb/analyze/action_view/link_to.c +25 -1
  11. package/extension/libherb/analyze/action_view/registry.c +23 -0
  12. package/extension/libherb/analyze/action_view/tag.c +14 -8
  13. package/extension/libherb/analyze/action_view/tag_helper_handler.h +2 -0
  14. package/extension/libherb/analyze/action_view/tag_helpers.c +78 -11
  15. package/extension/libherb/analyze/analyze.c +3 -0
  16. package/extension/libherb/analyze/missing_end.c +1 -1
  17. package/extension/libherb/analyze/prism_annotate.c +4 -2
  18. package/extension/libherb/analyze/render_nodes.c +761 -0
  19. package/extension/libherb/analyze/render_nodes.h +11 -0
  20. package/extension/libherb/analyze/transform.c +8 -1
  21. package/extension/libherb/ast_nodes.c +98 -1
  22. package/extension/libherb/ast_nodes.h +38 -1
  23. package/extension/libherb/ast_pretty_print.c +75 -1
  24. package/extension/libherb/ast_pretty_print.h +1 -1
  25. package/extension/libherb/errors.c +380 -1
  26. package/extension/libherb/errors.h +59 -1
  27. package/extension/libherb/include/analyze/action_view/tag_helper_handler.h +2 -0
  28. package/extension/libherb/include/analyze/render_nodes.h +11 -0
  29. package/extension/libherb/include/ast_nodes.h +38 -1
  30. package/extension/libherb/include/ast_pretty_print.h +1 -1
  31. package/extension/libherb/include/errors.h +59 -1
  32. package/extension/libherb/include/parser.h +1 -0
  33. package/extension/libherb/include/util/hb_foreach.h +1 -1
  34. package/extension/libherb/include/version.h +1 -1
  35. package/extension/libherb/parser.c +1 -0
  36. package/extension/libherb/parser.h +1 -0
  37. package/extension/libherb/parser_match_tags.c +21 -1
  38. package/extension/libherb/util/hb_foreach.h +1 -1
  39. package/extension/libherb/version.h +1 -1
  40. package/extension/libherb/visitor.c +21 -1
  41. package/extension/nodes.cpp +143 -1
  42. package/extension/nodes.h +3 -1
  43. package/package.json +2 -2
  44. package/CHANGELOG.md +0 -19
@@ -1,5 +1,5 @@
1
1
  // NOTE: This file is generated by the templates/template.rb script and should not
2
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.0/templates/src/errors.c.erb
2
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.1/templates/src/errors.c.erb
3
3
 
4
4
  #include "include/errors.h"
5
5
  #include "include/location.h"
@@ -820,6 +820,215 @@ void append_nested_erb_tag_error(token_T* opening_tag, size_t nested_tag_line, s
820
820
  hb_array_append(errors, nested_erb_tag_error_init(opening_tag, nested_tag_line, nested_tag_column, start, end, allocator));
821
821
  }
822
822
 
823
+ RENDER_AMBIGUOUS_LOCALS_ERROR_T* render_ambiguous_locals_error_init(hb_string_T partial, position_T start, position_T end, hb_allocator_T* allocator) {
824
+ RENDER_AMBIGUOUS_LOCALS_ERROR_T* render_ambiguous_locals_error = hb_allocator_alloc(allocator, sizeof(RENDER_AMBIGUOUS_LOCALS_ERROR_T));
825
+
826
+ if (!render_ambiguous_locals_error) { return NULL; }
827
+
828
+ error_init(&render_ambiguous_locals_error->base, RENDER_AMBIGUOUS_LOCALS_ERROR, start, end);
829
+
830
+ const char* message_template = "Did you mean `render partial: '%s', locals: { ... }`? Using `render '%s', locals: { ... }` passes a local variable named `locals` to the partial instead of setting the `locals:` option.";
831
+
832
+ hb_string_T truncated_argument_0 = hb_string_truncate(partial, ERROR_MESSAGES_TRUNCATED_LENGTH);
833
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
834
+
835
+ hb_string_T truncated_argument_1 = hb_string_truncate(partial, ERROR_MESSAGES_TRUNCATED_LENGTH);
836
+ char* truncated_c_string_1 = hb_string_to_c_string_using_malloc(truncated_argument_1);
837
+
838
+ char message[442];
839
+ snprintf(
840
+ message,
841
+ sizeof(message),
842
+ message_template,
843
+ truncated_c_string_0 ? truncated_c_string_0 : "",
844
+ truncated_c_string_1 ? truncated_c_string_1 : ""
845
+ );
846
+
847
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
848
+ if (truncated_c_string_1) { free(truncated_c_string_1); }
849
+ render_ambiguous_locals_error->base.message = hb_string_copy(hb_string(message), allocator);
850
+
851
+ render_ambiguous_locals_error->partial = hb_string_copy(partial, allocator);
852
+ return render_ambiguous_locals_error;
853
+ }
854
+
855
+ void append_render_ambiguous_locals_error(hb_string_T partial, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
856
+ hb_array_append(errors, render_ambiguous_locals_error_init(partial, start, end, allocator));
857
+ }
858
+
859
+ RENDER_MISSING_LOCALS_ERROR_T* render_missing_locals_error_init(hb_string_T partial, hb_string_T keywords, position_T start, position_T end, hb_allocator_T* allocator) {
860
+ RENDER_MISSING_LOCALS_ERROR_T* render_missing_locals_error = hb_allocator_alloc(allocator, sizeof(RENDER_MISSING_LOCALS_ERROR_T));
861
+
862
+ if (!render_missing_locals_error) { return NULL; }
863
+
864
+ error_init(&render_missing_locals_error->base, RENDER_MISSING_LOCALS_ERROR, start, end);
865
+
866
+ const char* message_template = "Wrap `%s` in `locals: { ... }` when using `partial:`. Use `render partial: '%s', locals: { %s }` instead. Without `locals:`, these keyword arguments are ignored.";
867
+
868
+ hb_string_T truncated_argument_0 = hb_string_truncate(keywords, ERROR_MESSAGES_TRUNCATED_LENGTH);
869
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
870
+
871
+ hb_string_T truncated_argument_1 = hb_string_truncate(partial, ERROR_MESSAGES_TRUNCATED_LENGTH);
872
+ char* truncated_c_string_1 = hb_string_to_c_string_using_malloc(truncated_argument_1);
873
+
874
+ hb_string_T truncated_argument_2 = hb_string_truncate(keywords, ERROR_MESSAGES_TRUNCATED_LENGTH);
875
+ char* truncated_c_string_2 = hb_string_to_c_string_using_malloc(truncated_argument_2);
876
+
877
+ char message[546];
878
+ snprintf(
879
+ message,
880
+ sizeof(message),
881
+ message_template,
882
+ truncated_c_string_0 ? truncated_c_string_0 : "",
883
+ truncated_c_string_1 ? truncated_c_string_1 : "",
884
+ truncated_c_string_2 ? truncated_c_string_2 : ""
885
+ );
886
+
887
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
888
+ if (truncated_c_string_1) { free(truncated_c_string_1); }
889
+ if (truncated_c_string_2) { free(truncated_c_string_2); }
890
+ render_missing_locals_error->base.message = hb_string_copy(hb_string(message), allocator);
891
+
892
+ render_missing_locals_error->partial = hb_string_copy(partial, allocator);
893
+ render_missing_locals_error->keywords = hb_string_copy(keywords, allocator);
894
+ return render_missing_locals_error;
895
+ }
896
+
897
+ void append_render_missing_locals_error(hb_string_T partial, hb_string_T keywords, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
898
+ hb_array_append(errors, render_missing_locals_error_init(partial, keywords, start, end, allocator));
899
+ }
900
+
901
+ RENDER_NO_ARGUMENTS_ERROR_T* render_no_arguments_error_init(position_T start, position_T end, hb_allocator_T* allocator) {
902
+ RENDER_NO_ARGUMENTS_ERROR_T* render_no_arguments_error = hb_allocator_alloc(allocator, sizeof(RENDER_NO_ARGUMENTS_ERROR_T));
903
+
904
+ if (!render_no_arguments_error) { return NULL; }
905
+
906
+ error_init(&render_no_arguments_error->base, RENDER_NO_ARGUMENTS_ERROR, start, end);
907
+
908
+ render_no_arguments_error->base.message = hb_string_copy(hb_string("No arguments passed to `render`. It needs a partial name, a keyword argument like `partial:`, `template:`, or `layout:`, or a renderable object."), allocator);
909
+
910
+ return render_no_arguments_error;
911
+ }
912
+
913
+ void append_render_no_arguments_error(position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
914
+ hb_array_append(errors, render_no_arguments_error_init(start, end, allocator));
915
+ }
916
+
917
+ RENDER_CONFLICTING_PARTIAL_ERROR_T* render_conflicting_partial_error_init(hb_string_T positional_partial, hb_string_T keyword_partial, position_T start, position_T end, hb_allocator_T* allocator) {
918
+ RENDER_CONFLICTING_PARTIAL_ERROR_T* render_conflicting_partial_error = hb_allocator_alloc(allocator, sizeof(RENDER_CONFLICTING_PARTIAL_ERROR_T));
919
+
920
+ if (!render_conflicting_partial_error) { return NULL; }
921
+
922
+ error_init(&render_conflicting_partial_error->base, RENDER_CONFLICTING_PARTIAL_ERROR, start, end);
923
+
924
+ const char* message_template = "Both a positional partial `'%s'` and a keyword `partial: '%s'` were passed to `render`. Use one form or the other, not both.";
925
+
926
+ hb_string_T truncated_argument_0 = hb_string_truncate(positional_partial, ERROR_MESSAGES_TRUNCATED_LENGTH);
927
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
928
+
929
+ hb_string_T truncated_argument_1 = hb_string_truncate(keyword_partial, ERROR_MESSAGES_TRUNCATED_LENGTH);
930
+ char* truncated_c_string_1 = hb_string_to_c_string_using_malloc(truncated_argument_1);
931
+
932
+ char message[381];
933
+ snprintf(
934
+ message,
935
+ sizeof(message),
936
+ message_template,
937
+ truncated_c_string_0 ? truncated_c_string_0 : "",
938
+ truncated_c_string_1 ? truncated_c_string_1 : ""
939
+ );
940
+
941
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
942
+ if (truncated_c_string_1) { free(truncated_c_string_1); }
943
+ render_conflicting_partial_error->base.message = hb_string_copy(hb_string(message), allocator);
944
+
945
+ render_conflicting_partial_error->positional_partial = hb_string_copy(positional_partial, allocator);
946
+ render_conflicting_partial_error->keyword_partial = hb_string_copy(keyword_partial, allocator);
947
+ return render_conflicting_partial_error;
948
+ }
949
+
950
+ void append_render_conflicting_partial_error(hb_string_T positional_partial, hb_string_T keyword_partial, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
951
+ hb_array_append(errors, render_conflicting_partial_error_init(positional_partial, keyword_partial, start, end, allocator));
952
+ }
953
+
954
+ RENDER_INVALID_AS_OPTION_ERROR_T* render_invalid_as_option_error_init(hb_string_T as_value, position_T start, position_T end, hb_allocator_T* allocator) {
955
+ RENDER_INVALID_AS_OPTION_ERROR_T* render_invalid_as_option_error = hb_allocator_alloc(allocator, sizeof(RENDER_INVALID_AS_OPTION_ERROR_T));
956
+
957
+ if (!render_invalid_as_option_error) { return NULL; }
958
+
959
+ error_init(&render_invalid_as_option_error->base, RENDER_INVALID_AS_OPTION_ERROR, start, end);
960
+
961
+ const char* message_template = "The `as:` value `'%s'` is not a valid Ruby identifier. Use a name that starts with a lowercase letter or underscore, like `as: :item`.";
962
+
963
+ hb_string_T truncated_argument_0 = hb_string_truncate(as_value, ERROR_MESSAGES_TRUNCATED_LENGTH);
964
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
965
+
966
+ char message[263];
967
+ snprintf(
968
+ message,
969
+ sizeof(message),
970
+ message_template,
971
+ truncated_c_string_0 ? truncated_c_string_0 : ""
972
+ );
973
+
974
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
975
+ render_invalid_as_option_error->base.message = hb_string_copy(hb_string(message), allocator);
976
+
977
+ render_invalid_as_option_error->as_value = hb_string_copy(as_value, allocator);
978
+ return render_invalid_as_option_error;
979
+ }
980
+
981
+ void append_render_invalid_as_option_error(hb_string_T as_value, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
982
+ hb_array_append(errors, render_invalid_as_option_error_init(as_value, start, end, allocator));
983
+ }
984
+
985
+ RENDER_OBJECT_AND_COLLECTION_ERROR_T* render_object_and_collection_error_init(position_T start, position_T end, hb_allocator_T* allocator) {
986
+ RENDER_OBJECT_AND_COLLECTION_ERROR_T* render_object_and_collection_error = hb_allocator_alloc(allocator, sizeof(RENDER_OBJECT_AND_COLLECTION_ERROR_T));
987
+
988
+ if (!render_object_and_collection_error) { return NULL; }
989
+
990
+ error_init(&render_object_and_collection_error->base, RENDER_OBJECT_AND_COLLECTION_ERROR, start, end);
991
+
992
+ render_object_and_collection_error->base.message = hb_string_copy(hb_string("The `object:` and `collection:` options are mutually exclusive. Use one or the other in your `render` call."), allocator);
993
+
994
+ return render_object_and_collection_error;
995
+ }
996
+
997
+ void append_render_object_and_collection_error(position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
998
+ hb_array_append(errors, render_object_and_collection_error_init(start, end, allocator));
999
+ }
1000
+
1001
+ RENDER_LAYOUT_WITHOUT_BLOCK_ERROR_T* render_layout_without_block_error_init(hb_string_T layout, position_T start, position_T end, hb_allocator_T* allocator) {
1002
+ RENDER_LAYOUT_WITHOUT_BLOCK_ERROR_T* render_layout_without_block_error = hb_allocator_alloc(allocator, sizeof(RENDER_LAYOUT_WITHOUT_BLOCK_ERROR_T));
1003
+
1004
+ if (!render_layout_without_block_error) { return NULL; }
1005
+
1006
+ error_init(&render_layout_without_block_error->base, RENDER_LAYOUT_WITHOUT_BLOCK_ERROR, start, end);
1007
+
1008
+ const char* message_template = "Layout rendering needs a block. Use `render layout: '%s' do ... end` so the layout has content to wrap.";
1009
+
1010
+ hb_string_T truncated_argument_0 = hb_string_truncate(layout, ERROR_MESSAGES_TRUNCATED_LENGTH);
1011
+ char* truncated_c_string_0 = hb_string_to_c_string_using_malloc(truncated_argument_0);
1012
+
1013
+ char message[232];
1014
+ snprintf(
1015
+ message,
1016
+ sizeof(message),
1017
+ message_template,
1018
+ truncated_c_string_0 ? truncated_c_string_0 : ""
1019
+ );
1020
+
1021
+ if (truncated_c_string_0) { free(truncated_c_string_0); }
1022
+ render_layout_without_block_error->base.message = hb_string_copy(hb_string(message), allocator);
1023
+
1024
+ render_layout_without_block_error->layout = hb_string_copy(layout, allocator);
1025
+ return render_layout_without_block_error;
1026
+ }
1027
+
1028
+ void append_render_layout_without_block_error(hb_string_T layout, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors) {
1029
+ hb_array_append(errors, render_layout_without_block_error_init(layout, start, end, allocator));
1030
+ }
1031
+
823
1032
  hb_string_T error_type_to_string(ERROR_T* error) {
824
1033
  switch (error->type) {
825
1034
  case UNEXPECTED_ERROR: return hb_string("UNEXPECTED_ERROR");
@@ -845,6 +1054,13 @@ hb_string_T error_type_to_string(ERROR_T* error) {
845
1054
  case UNCLOSED_ERB_TAG_ERROR: return hb_string("UNCLOSED_ERB_TAG_ERROR");
846
1055
  case STRAY_ERB_CLOSING_TAG_ERROR: return hb_string("STRAY_ERB_CLOSING_TAG_ERROR");
847
1056
  case NESTED_ERB_TAG_ERROR: return hb_string("NESTED_ERB_TAG_ERROR");
1057
+ case RENDER_AMBIGUOUS_LOCALS_ERROR: return hb_string("RENDER_AMBIGUOUS_LOCALS_ERROR");
1058
+ case RENDER_MISSING_LOCALS_ERROR: return hb_string("RENDER_MISSING_LOCALS_ERROR");
1059
+ case RENDER_NO_ARGUMENTS_ERROR: return hb_string("RENDER_NO_ARGUMENTS_ERROR");
1060
+ case RENDER_CONFLICTING_PARTIAL_ERROR: return hb_string("RENDER_CONFLICTING_PARTIAL_ERROR");
1061
+ case RENDER_INVALID_AS_OPTION_ERROR: return hb_string("RENDER_INVALID_AS_OPTION_ERROR");
1062
+ case RENDER_OBJECT_AND_COLLECTION_ERROR: return hb_string("RENDER_OBJECT_AND_COLLECTION_ERROR");
1063
+ case RENDER_LAYOUT_WITHOUT_BLOCK_ERROR: return hb_string("RENDER_LAYOUT_WITHOUT_BLOCK_ERROR");
848
1064
  }
849
1065
 
850
1066
  return hb_string("Unknown error_type_T");
@@ -875,6 +1091,13 @@ hb_string_T error_human_type(ERROR_T* error) {
875
1091
  case UNCLOSED_ERB_TAG_ERROR: return hb_string("UnclosedERBTagError");
876
1092
  case STRAY_ERB_CLOSING_TAG_ERROR: return hb_string("StrayERBClosingTagError");
877
1093
  case NESTED_ERB_TAG_ERROR: return hb_string("NestedERBTagError");
1094
+ case RENDER_AMBIGUOUS_LOCALS_ERROR: return hb_string("RenderAmbiguousLocalsError");
1095
+ case RENDER_MISSING_LOCALS_ERROR: return hb_string("RenderMissingLocalsError");
1096
+ case RENDER_NO_ARGUMENTS_ERROR: return hb_string("RenderNoArgumentsError");
1097
+ case RENDER_CONFLICTING_PARTIAL_ERROR: return hb_string("RenderConflictingPartialError");
1098
+ case RENDER_INVALID_AS_OPTION_ERROR: return hb_string("RenderInvalidAsOptionError");
1099
+ case RENDER_OBJECT_AND_COLLECTION_ERROR: return hb_string("RenderObjectAndCollectionError");
1100
+ case RENDER_LAYOUT_WITHOUT_BLOCK_ERROR: return hb_string("RenderLayoutWithoutBlockError");
878
1101
  }
879
1102
 
880
1103
  return hb_string("Unknown error_type_T");
@@ -1044,6 +1267,50 @@ static void error_free_nested_erb_tag_error(NESTED_ERB_TAG_ERROR_T* nested_erb_t
1044
1267
  error_free_base_error(&nested_erb_tag_error->base, allocator);
1045
1268
  }
1046
1269
 
1270
+ static void error_free_render_ambiguous_locals_error(RENDER_AMBIGUOUS_LOCALS_ERROR_T* render_ambiguous_locals_error, hb_allocator_T* allocator) {
1271
+ if (render_ambiguous_locals_error->partial.data != NULL) { hb_allocator_dealloc(allocator, render_ambiguous_locals_error->partial.data); }
1272
+
1273
+ error_free_base_error(&render_ambiguous_locals_error->base, allocator);
1274
+ }
1275
+
1276
+ static void error_free_render_missing_locals_error(RENDER_MISSING_LOCALS_ERROR_T* render_missing_locals_error, hb_allocator_T* allocator) {
1277
+ if (render_missing_locals_error->partial.data != NULL) { hb_allocator_dealloc(allocator, render_missing_locals_error->partial.data); }
1278
+ if (render_missing_locals_error->keywords.data != NULL) { hb_allocator_dealloc(allocator, render_missing_locals_error->keywords.data); }
1279
+
1280
+ error_free_base_error(&render_missing_locals_error->base, allocator);
1281
+ }
1282
+
1283
+ static void error_free_render_no_arguments_error(RENDER_NO_ARGUMENTS_ERROR_T* render_no_arguments_error, hb_allocator_T* allocator) {
1284
+ /* no RENDER_NO_ARGUMENTS_ERROR_T specific fields to free up */
1285
+
1286
+ error_free_base_error(&render_no_arguments_error->base, allocator);
1287
+ }
1288
+
1289
+ static void error_free_render_conflicting_partial_error(RENDER_CONFLICTING_PARTIAL_ERROR_T* render_conflicting_partial_error, hb_allocator_T* allocator) {
1290
+ if (render_conflicting_partial_error->positional_partial.data != NULL) { hb_allocator_dealloc(allocator, render_conflicting_partial_error->positional_partial.data); }
1291
+ if (render_conflicting_partial_error->keyword_partial.data != NULL) { hb_allocator_dealloc(allocator, render_conflicting_partial_error->keyword_partial.data); }
1292
+
1293
+ error_free_base_error(&render_conflicting_partial_error->base, allocator);
1294
+ }
1295
+
1296
+ static void error_free_render_invalid_as_option_error(RENDER_INVALID_AS_OPTION_ERROR_T* render_invalid_as_option_error, hb_allocator_T* allocator) {
1297
+ if (render_invalid_as_option_error->as_value.data != NULL) { hb_allocator_dealloc(allocator, render_invalid_as_option_error->as_value.data); }
1298
+
1299
+ error_free_base_error(&render_invalid_as_option_error->base, allocator);
1300
+ }
1301
+
1302
+ static void error_free_render_object_and_collection_error(RENDER_OBJECT_AND_COLLECTION_ERROR_T* render_object_and_collection_error, hb_allocator_T* allocator) {
1303
+ /* no RENDER_OBJECT_AND_COLLECTION_ERROR_T specific fields to free up */
1304
+
1305
+ error_free_base_error(&render_object_and_collection_error->base, allocator);
1306
+ }
1307
+
1308
+ static void error_free_render_layout_without_block_error(RENDER_LAYOUT_WITHOUT_BLOCK_ERROR_T* render_layout_without_block_error, hb_allocator_T* allocator) {
1309
+ if (render_layout_without_block_error->layout.data != NULL) { hb_allocator_dealloc(allocator, render_layout_without_block_error->layout.data); }
1310
+
1311
+ error_free_base_error(&render_layout_without_block_error->base, allocator);
1312
+ }
1313
+
1047
1314
  void error_free(ERROR_T* error, hb_allocator_T* allocator) {
1048
1315
  if (!error) { return; }
1049
1316
 
@@ -1071,6 +1338,13 @@ void error_free(ERROR_T* error, hb_allocator_T* allocator) {
1071
1338
  case UNCLOSED_ERB_TAG_ERROR: error_free_unclosed_erb_tag_error((UNCLOSED_ERB_TAG_ERROR_T*) error, allocator); break;
1072
1339
  case STRAY_ERB_CLOSING_TAG_ERROR: error_free_stray_erb_closing_tag_error((STRAY_ERB_CLOSING_TAG_ERROR_T*) error, allocator); break;
1073
1340
  case NESTED_ERB_TAG_ERROR: error_free_nested_erb_tag_error((NESTED_ERB_TAG_ERROR_T*) error, allocator); break;
1341
+ case RENDER_AMBIGUOUS_LOCALS_ERROR: error_free_render_ambiguous_locals_error((RENDER_AMBIGUOUS_LOCALS_ERROR_T*) error, allocator); break;
1342
+ case RENDER_MISSING_LOCALS_ERROR: error_free_render_missing_locals_error((RENDER_MISSING_LOCALS_ERROR_T*) error, allocator); break;
1343
+ case RENDER_NO_ARGUMENTS_ERROR: error_free_render_no_arguments_error((RENDER_NO_ARGUMENTS_ERROR_T*) error, allocator); break;
1344
+ case RENDER_CONFLICTING_PARTIAL_ERROR: error_free_render_conflicting_partial_error((RENDER_CONFLICTING_PARTIAL_ERROR_T*) error, allocator); break;
1345
+ case RENDER_INVALID_AS_OPTION_ERROR: error_free_render_invalid_as_option_error((RENDER_INVALID_AS_OPTION_ERROR_T*) error, allocator); break;
1346
+ case RENDER_OBJECT_AND_COLLECTION_ERROR: error_free_render_object_and_collection_error((RENDER_OBJECT_AND_COLLECTION_ERROR_T*) error, allocator); break;
1347
+ case RENDER_LAYOUT_WITHOUT_BLOCK_ERROR: error_free_render_layout_without_block_error((RENDER_LAYOUT_WITHOUT_BLOCK_ERROR_T*) error, allocator); break;
1074
1348
  }
1075
1349
  }
1076
1350
 
@@ -1457,6 +1731,104 @@ static void error_pretty_print_nested_erb_tag_error(NESTED_ERB_TAG_ERROR_T* erro
1457
1731
  pretty_print_size_t_property(error->nested_tag_column, hb_string("nested_tag_column"), indent, relative_indent, true, buffer);
1458
1732
  }
1459
1733
 
1734
+ static void error_pretty_print_render_ambiguous_locals_error(RENDER_AMBIGUOUS_LOCALS_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1735
+ if (!error) { return; }
1736
+
1737
+ hb_buffer_append(buffer, "@ ");
1738
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
1739
+ hb_buffer_append(buffer, " ");
1740
+
1741
+ pretty_print_location(error->base.location, buffer);
1742
+ hb_buffer_append(buffer, "\n");
1743
+
1744
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
1745
+ pretty_print_quoted_property(hb_string("partial"), error->partial, indent, relative_indent, true, buffer);
1746
+ }
1747
+
1748
+ static void error_pretty_print_render_missing_locals_error(RENDER_MISSING_LOCALS_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1749
+ if (!error) { return; }
1750
+
1751
+ hb_buffer_append(buffer, "@ ");
1752
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
1753
+ hb_buffer_append(buffer, " ");
1754
+
1755
+ pretty_print_location(error->base.location, buffer);
1756
+ hb_buffer_append(buffer, "\n");
1757
+
1758
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
1759
+ pretty_print_quoted_property(hb_string("partial"), error->partial, indent, relative_indent, false, buffer);
1760
+ pretty_print_quoted_property(hb_string("keywords"), error->keywords, indent, relative_indent, true, buffer);
1761
+ }
1762
+
1763
+ static void error_pretty_print_render_no_arguments_error(RENDER_NO_ARGUMENTS_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1764
+ if (!error) { return; }
1765
+
1766
+ hb_buffer_append(buffer, "@ ");
1767
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
1768
+ hb_buffer_append(buffer, " ");
1769
+
1770
+ pretty_print_location(error->base.location, buffer);
1771
+ hb_buffer_append(buffer, "\n");
1772
+
1773
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, true, buffer);
1774
+ }
1775
+
1776
+ static void error_pretty_print_render_conflicting_partial_error(RENDER_CONFLICTING_PARTIAL_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1777
+ if (!error) { return; }
1778
+
1779
+ hb_buffer_append(buffer, "@ ");
1780
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
1781
+ hb_buffer_append(buffer, " ");
1782
+
1783
+ pretty_print_location(error->base.location, buffer);
1784
+ hb_buffer_append(buffer, "\n");
1785
+
1786
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
1787
+ pretty_print_quoted_property(hb_string("positional_partial"), error->positional_partial, indent, relative_indent, false, buffer);
1788
+ pretty_print_quoted_property(hb_string("keyword_partial"), error->keyword_partial, indent, relative_indent, true, buffer);
1789
+ }
1790
+
1791
+ static void error_pretty_print_render_invalid_as_option_error(RENDER_INVALID_AS_OPTION_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1792
+ if (!error) { return; }
1793
+
1794
+ hb_buffer_append(buffer, "@ ");
1795
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
1796
+ hb_buffer_append(buffer, " ");
1797
+
1798
+ pretty_print_location(error->base.location, buffer);
1799
+ hb_buffer_append(buffer, "\n");
1800
+
1801
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
1802
+ pretty_print_quoted_property(hb_string("as_value"), error->as_value, indent, relative_indent, true, buffer);
1803
+ }
1804
+
1805
+ static void error_pretty_print_render_object_and_collection_error(RENDER_OBJECT_AND_COLLECTION_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1806
+ if (!error) { return; }
1807
+
1808
+ hb_buffer_append(buffer, "@ ");
1809
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
1810
+ hb_buffer_append(buffer, " ");
1811
+
1812
+ pretty_print_location(error->base.location, buffer);
1813
+ hb_buffer_append(buffer, "\n");
1814
+
1815
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, true, buffer);
1816
+ }
1817
+
1818
+ static void error_pretty_print_render_layout_without_block_error(RENDER_LAYOUT_WITHOUT_BLOCK_ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1819
+ if (!error) { return; }
1820
+
1821
+ hb_buffer_append(buffer, "@ ");
1822
+ hb_buffer_append_string(buffer, error_human_type((ERROR_T*) error));
1823
+ hb_buffer_append(buffer, " ");
1824
+
1825
+ pretty_print_location(error->base.location, buffer);
1826
+ hb_buffer_append(buffer, "\n");
1827
+
1828
+ pretty_print_quoted_property(hb_string("message"), error->base.message, indent, relative_indent, false, buffer);
1829
+ pretty_print_quoted_property(hb_string("layout"), error->layout, indent, relative_indent, true, buffer);
1830
+ }
1831
+
1460
1832
  void error_pretty_print(ERROR_T* error, const size_t indent, const size_t relative_indent, hb_buffer_T* buffer) {
1461
1833
  if (!error) { return; }
1462
1834
 
@@ -1484,6 +1856,13 @@ void error_pretty_print(ERROR_T* error, const size_t indent, const size_t relati
1484
1856
  case UNCLOSED_ERB_TAG_ERROR: error_pretty_print_unclosed_erb_tag_error((UNCLOSED_ERB_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
1485
1857
  case STRAY_ERB_CLOSING_TAG_ERROR: error_pretty_print_stray_erb_closing_tag_error((STRAY_ERB_CLOSING_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
1486
1858
  case NESTED_ERB_TAG_ERROR: error_pretty_print_nested_erb_tag_error((NESTED_ERB_TAG_ERROR_T*) error, indent, relative_indent, buffer); break;
1859
+ case RENDER_AMBIGUOUS_LOCALS_ERROR: error_pretty_print_render_ambiguous_locals_error((RENDER_AMBIGUOUS_LOCALS_ERROR_T*) error, indent, relative_indent, buffer); break;
1860
+ case RENDER_MISSING_LOCALS_ERROR: error_pretty_print_render_missing_locals_error((RENDER_MISSING_LOCALS_ERROR_T*) error, indent, relative_indent, buffer); break;
1861
+ case RENDER_NO_ARGUMENTS_ERROR: error_pretty_print_render_no_arguments_error((RENDER_NO_ARGUMENTS_ERROR_T*) error, indent, relative_indent, buffer); break;
1862
+ case RENDER_CONFLICTING_PARTIAL_ERROR: error_pretty_print_render_conflicting_partial_error((RENDER_CONFLICTING_PARTIAL_ERROR_T*) error, indent, relative_indent, buffer); break;
1863
+ case RENDER_INVALID_AS_OPTION_ERROR: error_pretty_print_render_invalid_as_option_error((RENDER_INVALID_AS_OPTION_ERROR_T*) error, indent, relative_indent, buffer); break;
1864
+ case RENDER_OBJECT_AND_COLLECTION_ERROR: error_pretty_print_render_object_and_collection_error((RENDER_OBJECT_AND_COLLECTION_ERROR_T*) error, indent, relative_indent, buffer); break;
1865
+ case RENDER_LAYOUT_WITHOUT_BLOCK_ERROR: error_pretty_print_render_layout_without_block_error((RENDER_LAYOUT_WITHOUT_BLOCK_ERROR_T*) error, indent, relative_indent, buffer); break;
1487
1866
  }
1488
1867
  }
1489
1868
 
@@ -1,5 +1,5 @@
1
1
  // NOTE: This file is generated by the templates/template.rb script and should not
2
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.0/templates/src/include/errors.h.erb
2
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.1/templates/src/include/errors.h.erb
3
3
 
4
4
  #ifndef HERB_ERRORS_H
5
5
  #define HERB_ERRORS_H
@@ -37,6 +37,13 @@ typedef enum {
37
37
  UNCLOSED_ERB_TAG_ERROR,
38
38
  STRAY_ERB_CLOSING_TAG_ERROR,
39
39
  NESTED_ERB_TAG_ERROR,
40
+ RENDER_AMBIGUOUS_LOCALS_ERROR,
41
+ RENDER_MISSING_LOCALS_ERROR,
42
+ RENDER_NO_ARGUMENTS_ERROR,
43
+ RENDER_CONFLICTING_PARTIAL_ERROR,
44
+ RENDER_INVALID_AS_OPTION_ERROR,
45
+ RENDER_OBJECT_AND_COLLECTION_ERROR,
46
+ RENDER_LAYOUT_WITHOUT_BLOCK_ERROR,
40
47
  } error_type_T;
41
48
 
42
49
  typedef struct ERROR_STRUCT {
@@ -179,6 +186,43 @@ typedef struct {
179
186
  size_t nested_tag_column;
180
187
  } NESTED_ERB_TAG_ERROR_T;
181
188
 
189
+ typedef struct {
190
+ ERROR_T base;
191
+ hb_string_T partial;
192
+ } RENDER_AMBIGUOUS_LOCALS_ERROR_T;
193
+
194
+ typedef struct {
195
+ ERROR_T base;
196
+ hb_string_T partial;
197
+ hb_string_T keywords;
198
+ } RENDER_MISSING_LOCALS_ERROR_T;
199
+
200
+ typedef struct {
201
+ ERROR_T base;
202
+ /* no additional fields */
203
+ } RENDER_NO_ARGUMENTS_ERROR_T;
204
+
205
+ typedef struct {
206
+ ERROR_T base;
207
+ hb_string_T positional_partial;
208
+ hb_string_T keyword_partial;
209
+ } RENDER_CONFLICTING_PARTIAL_ERROR_T;
210
+
211
+ typedef struct {
212
+ ERROR_T base;
213
+ hb_string_T as_value;
214
+ } RENDER_INVALID_AS_OPTION_ERROR_T;
215
+
216
+ typedef struct {
217
+ ERROR_T base;
218
+ /* no additional fields */
219
+ } RENDER_OBJECT_AND_COLLECTION_ERROR_T;
220
+
221
+ typedef struct {
222
+ ERROR_T base;
223
+ hb_string_T layout;
224
+ } RENDER_LAYOUT_WITHOUT_BLOCK_ERROR_T;
225
+
182
226
  UNEXPECTED_ERROR_T* unexpected_error_init(hb_string_T description, hb_string_T expected, hb_string_T found, position_T start, position_T end, hb_allocator_T* allocator);
183
227
  void append_unexpected_error(hb_string_T description, hb_string_T expected, hb_string_T found, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
184
228
  UNEXPECTED_TOKEN_ERROR_T* unexpected_token_error_init(token_type_T expected_type, token_T* found, position_T start, position_T end, hb_allocator_T* allocator);
@@ -225,6 +269,20 @@ STRAY_ERB_CLOSING_TAG_ERROR_T* stray_erb_closing_tag_error_init(position_T start
225
269
  void append_stray_erb_closing_tag_error(position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
226
270
  NESTED_ERB_TAG_ERROR_T* nested_erb_tag_error_init(token_T* opening_tag, size_t nested_tag_line, size_t nested_tag_column, position_T start, position_T end, hb_allocator_T* allocator);
227
271
  void append_nested_erb_tag_error(token_T* opening_tag, size_t nested_tag_line, size_t nested_tag_column, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
272
+ RENDER_AMBIGUOUS_LOCALS_ERROR_T* render_ambiguous_locals_error_init(hb_string_T partial, position_T start, position_T end, hb_allocator_T* allocator);
273
+ void append_render_ambiguous_locals_error(hb_string_T partial, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
274
+ RENDER_MISSING_LOCALS_ERROR_T* render_missing_locals_error_init(hb_string_T partial, hb_string_T keywords, position_T start, position_T end, hb_allocator_T* allocator);
275
+ void append_render_missing_locals_error(hb_string_T partial, hb_string_T keywords, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
276
+ RENDER_NO_ARGUMENTS_ERROR_T* render_no_arguments_error_init(position_T start, position_T end, hb_allocator_T* allocator);
277
+ void append_render_no_arguments_error(position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
278
+ RENDER_CONFLICTING_PARTIAL_ERROR_T* render_conflicting_partial_error_init(hb_string_T positional_partial, hb_string_T keyword_partial, position_T start, position_T end, hb_allocator_T* allocator);
279
+ void append_render_conflicting_partial_error(hb_string_T positional_partial, hb_string_T keyword_partial, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
280
+ RENDER_INVALID_AS_OPTION_ERROR_T* render_invalid_as_option_error_init(hb_string_T as_value, position_T start, position_T end, hb_allocator_T* allocator);
281
+ void append_render_invalid_as_option_error(hb_string_T as_value, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
282
+ RENDER_OBJECT_AND_COLLECTION_ERROR_T* render_object_and_collection_error_init(position_T start, position_T end, hb_allocator_T* allocator);
283
+ void append_render_object_and_collection_error(position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
284
+ RENDER_LAYOUT_WITHOUT_BLOCK_ERROR_T* render_layout_without_block_error_init(hb_string_T layout, position_T start, position_T end, hb_allocator_T* allocator);
285
+ void append_render_layout_without_block_error(hb_string_T layout, position_T start, position_T end, hb_allocator_T* allocator, hb_array_T* errors);
228
286
 
229
287
  void error_init(ERROR_T* error, error_type_T type, position_T start, position_T end);
230
288
 
@@ -38,4 +38,6 @@ void tag_helper_info_free(tag_helper_info_T** info);
38
38
  tag_helper_handler_T* get_tag_helper_handlers(void);
39
39
  size_t get_tag_helper_handlers_count(void);
40
40
 
41
+ char* extract_inline_block_content(pm_call_node_t* call_node, hb_allocator_T* allocator);
42
+
41
43
  #endif
@@ -0,0 +1,11 @@
1
+ #ifndef HERB_ANALYZE_RENDER_NODES_H
2
+ #define HERB_ANALYZE_RENDER_NODES_H
3
+
4
+ #include "../ast_nodes.h"
5
+ #include "analyze.h"
6
+
7
+ #include <stdbool.h>
8
+
9
+ bool transform_render_nodes(const AST_NODE_T* node, void* data);
10
+
11
+ #endif
@@ -1,5 +1,5 @@
1
1
  // NOTE: This file is generated by the templates/template.rb script and should not
2
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.0/templates/src/include/ast_nodes.h.erb
2
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.1/templates/src/include/ast_nodes.h.erb
3
3
 
4
4
  #ifndef HERB_AST_NODES_H
5
5
  #define HERB_AST_NODES_H
@@ -57,6 +57,8 @@ typedef enum {
57
57
  AST_ERB_ENSURE_NODE,
58
58
  AST_ERB_BEGIN_NODE,
59
59
  AST_ERB_UNLESS_NODE,
60
+ AST_RUBY_RENDER_LOCAL_NODE,
61
+ AST_ERB_RENDER_NODE,
60
62
  AST_ERB_YIELD_NODE,
61
63
  AST_ERB_IN_NODE,
62
64
  } ast_node_type_T;
@@ -368,6 +370,39 @@ typedef struct AST_ERB_UNLESS_NODE_STRUCT {
368
370
  struct AST_ERB_END_NODE_STRUCT* end_node;
369
371
  } AST_ERB_UNLESS_NODE_T;
370
372
 
373
+ typedef struct AST_RUBY_RENDER_LOCAL_NODE_STRUCT {
374
+ AST_NODE_T base;
375
+ token_T* name;
376
+ struct AST_RUBY_LITERAL_NODE_STRUCT* value;
377
+ } AST_RUBY_RENDER_LOCAL_NODE_T;
378
+
379
+ typedef struct AST_ERB_RENDER_NODE_STRUCT {
380
+ AST_NODE_T base;
381
+ token_T* tag_opening;
382
+ token_T* content;
383
+ token_T* tag_closing;
384
+ analyzed_ruby_T* analyzed_ruby;
385
+ herb_prism_node_T prism_node;
386
+ token_T* partial;
387
+ token_T* template_path;
388
+ token_T* layout;
389
+ token_T* file;
390
+ token_T* inline_template;
391
+ token_T* body;
392
+ token_T* plain;
393
+ token_T* html;
394
+ token_T* renderable;
395
+ token_T* collection;
396
+ token_T* object;
397
+ token_T* as_name;
398
+ token_T* spacer_template;
399
+ token_T* formats;
400
+ token_T* variants;
401
+ token_T* handlers;
402
+ token_T* content_type;
403
+ hb_array_T* locals;
404
+ } AST_ERB_RENDER_NODE_T;
405
+
371
406
  typedef struct AST_ERB_YIELD_NODE_STRUCT {
372
407
  AST_NODE_T base;
373
408
  token_T* tag_opening;
@@ -420,6 +455,8 @@ AST_ERB_RESCUE_NODE_T* ast_erb_rescue_node_init(token_T* tag_opening, token_T* c
420
455
  AST_ERB_ENSURE_NODE_T* ast_erb_ensure_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, hb_array_T* statements, position_T start_position, position_T end_position, hb_array_T* errors, hb_allocator_T* allocator);
421
456
  AST_ERB_BEGIN_NODE_T* ast_erb_begin_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, herb_prism_node_T prism_node, hb_array_T* statements, struct AST_ERB_RESCUE_NODE_STRUCT* rescue_clause, struct AST_ERB_ELSE_NODE_STRUCT* else_clause, struct AST_ERB_ENSURE_NODE_STRUCT* ensure_clause, struct AST_ERB_END_NODE_STRUCT* end_node, position_T start_position, position_T end_position, hb_array_T* errors, hb_allocator_T* allocator);
422
457
  AST_ERB_UNLESS_NODE_T* ast_erb_unless_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, location_T* then_keyword, herb_prism_node_T prism_node, hb_array_T* statements, struct AST_ERB_ELSE_NODE_STRUCT* else_clause, struct AST_ERB_END_NODE_STRUCT* end_node, position_T start_position, position_T end_position, hb_array_T* errors, hb_allocator_T* allocator);
458
+ AST_RUBY_RENDER_LOCAL_NODE_T* ast_ruby_render_local_node_init(token_T* name, struct AST_RUBY_LITERAL_NODE_STRUCT* value, position_T start_position, position_T end_position, hb_array_T* errors, hb_allocator_T* allocator);
459
+ AST_ERB_RENDER_NODE_T* ast_erb_render_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, analyzed_ruby_T* analyzed_ruby, herb_prism_node_T prism_node, token_T* partial, token_T* template_path, token_T* layout, token_T* file, token_T* inline_template, token_T* body, token_T* plain, token_T* html, token_T* renderable, token_T* collection, token_T* object, token_T* as_name, token_T* spacer_template, token_T* formats, token_T* variants, token_T* handlers, token_T* content_type, hb_array_T* locals, position_T start_position, position_T end_position, hb_array_T* errors, hb_allocator_T* allocator);
423
460
  AST_ERB_YIELD_NODE_T* ast_erb_yield_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, position_T start_position, position_T end_position, hb_array_T* errors, hb_allocator_T* allocator);
424
461
  AST_ERB_IN_NODE_T* ast_erb_in_node_init(token_T* tag_opening, token_T* content, token_T* tag_closing, location_T* then_keyword, hb_array_T* statements, position_T start_position, position_T end_position, hb_array_T* errors, hb_allocator_T* allocator);
425
462
 
@@ -1,5 +1,5 @@
1
1
  // NOTE: This file is generated by the templates/template.rb script and should not
2
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.0/templates/src/include/ast_pretty_print.h.erb
2
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.9.1/templates/src/include/ast_pretty_print.h.erb
3
3
 
4
4
  #ifndef HERB_AST_PRETTY_PRINT_H
5
5
  #define HERB_AST_PRETTY_PRINT_H