Skip to content

Commit 8a3e028

Browse files
committed
Parser: Expose Prism Nodes in Herb Syntax Tree
1 parent 2ec7dc8 commit 8a3e028

File tree

184 files changed

+10350
-151
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

184 files changed

+10350
-151
lines changed

.rubocop.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ Metrics/CyclomaticComplexity:
5858
- lib/herb/ast/nodes.rb
5959
- lib/herb/cli.rb
6060
- lib/herb/engine.rb
61+
- lib/herb/prism_inspect.rb
6162
- lib/herb/engine/**/*.rb
63+
- templates/template.rb
6264

6365
Metrics/MethodLength:
6466
Max: 20
@@ -68,6 +70,7 @@ Metrics/MethodLength:
6870
- lib/herb/project.rb
6971
- lib/herb/engine.rb
7072
- lib/herb/engine/**/*.rb
73+
- lib/herb/prism_inspect.rb
7174
- templates/template.rb
7275
- test/fork_helper.rb
7376
- test/snapshot_utils.rb
@@ -83,6 +86,7 @@ Metrics/AbcSize:
8386
- lib/herb/engine.rb
8487
- lib/herb/engine/**/*.rb
8588
- lib/herb/token.rb
89+
- lib/herb/prism_inspect.rb
8690
- templates/template.rb
8791
- test/fork_helper.rb
8892
- test/snapshot_utils.rb
@@ -98,6 +102,7 @@ Metrics/ClassLength:
98102
- lib/herb/engine/**/*.rb
99103
- lib/herb/project.rb
100104
- lib/herb/visitor.rb
105+
- lib/herb/ast/nodes.rb
101106
- test/**/*_test.rb
102107

103108
Metrics/ModuleLength:
@@ -121,14 +126,17 @@ Metrics/ParameterLists:
121126
Exclude:
122127
- lib/herb/ast/node.rb
123128
- lib/herb/ast/nodes.rb
124-
- lib/herb/errors.rb
125129
- lib/herb/engine/validators/security_validator.rb
130+
- lib/herb/errors.rb
131+
- lib/herb/parser_options.rb
132+
- lib/herb/prism_inspect.rb
126133

127134
Metrics/PerceivedComplexity:
128135
Exclude:
129136
- lib/herb/ast/nodes.rb
130137
- lib/herb/cli.rb
131138
- lib/herb/project.rb
139+
- lib/herb/prism_inspect.rb
132140
- lib/herb/engine.rb
133141
- lib/herb/engine/**/*.rb
134142
- templates/template.rb

config.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,12 @@ nodes:
369369
type: array
370370
kind: Node
371371
372+
- name: prism_context
373+
type: prism_context
374+
375+
- name: prism_node
376+
type: prism_node
377+
372378
- name: LiteralNode
373379
fields:
374380
- name: content
@@ -643,6 +649,9 @@ nodes:
643649
- name: valid
644650
type: boolean
645651
652+
- name: prism_node
653+
type: prism_node
654+
646655
- name: ERBEndNode
647656
fields:
648657
- name: tag_opening
@@ -686,6 +695,9 @@ nodes:
686695
# - name: predicate
687696
# type: prism_node
688697
698+
- name: prism_node
699+
type: prism_node
700+
689701
- name: statements
690702
type: array
691703
kind: Node
@@ -717,6 +729,9 @@ nodes:
717729
# - name: opener
718730
# type: prism_node
719731
732+
- name: prism_node
733+
type: prism_node
734+
720735
- name: body
721736
type: array
722737
kind: Node
@@ -765,6 +780,9 @@ nodes:
765780
# - name: predicate
766781
# type: prism_node
767782
783+
- name: prism_node
784+
type: prism_node
785+
768786
- name: conditions
769787
type: array
770788
kind: ERBWhenNode
@@ -795,6 +813,9 @@ nodes:
795813
# - name: predicate
796814
# type: prism_node
797815
816+
- name: prism_node
817+
type: prism_node
818+
798819
- name: conditions
799820
type: array
800821
kind: ERBInNode
@@ -821,6 +842,9 @@ nodes:
821842
# - name: predicate
822843
# type: prism_node
823844
845+
- name: prism_node
846+
type: prism_node
847+
824848
- name: statements
825849
type: array
826850
kind: Node
@@ -843,6 +867,9 @@ nodes:
843867
# - name: predicate
844868
# type: prism_node
845869
870+
- name: prism_node
871+
type: prism_node
872+
846873
- name: statements
847874
type: array
848875
kind: Node
@@ -868,6 +895,9 @@ nodes:
868895
# - name: collection
869896
# type: prism_node
870897
898+
- name: prism_node
899+
type: prism_node
900+
871901
- name: statements
872902
type: array
873903
kind: Node
@@ -928,6 +958,9 @@ nodes:
928958
- name: tag_closing
929959
type: token
930960
961+
- name: prism_node
962+
type: prism_node
963+
931964
- name: statements
932965
type: array
933966
kind: Node
@@ -965,6 +998,9 @@ nodes:
965998
# - name: predicate
966999
# type: prism_node
9671000
1001+
- name: prism_node
1002+
type: prism_node
1003+
9681004
- name: statements
9691005
type: array
9701006
kind: Node

ext/herb/extconf.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
$CFLAGS << " -DPRISM_EXCLUDE_PRETTYPRINT"
2828
$CFLAGS << " -DPRISM_EXCLUDE_JSON"
2929
$CFLAGS << " -DPRISM_EXCLUDE_PACK"
30-
$CFLAGS << " -DPRISM_EXCLUDE_SERIALIZATION"
3130

3231
herb_src_files = Dir.glob("#{$srcdir}/../../src/**/*.c").map { |file| file.delete_prefix("../../../../ext/herb/") }.sort
3332

ext/herb/extension.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,18 @@ static VALUE Herb_parse(int argc, VALUE* argv, VALUE self) {
136136
}
137137
if (!NIL_P(action_view_helpers) && RTEST(action_view_helpers)) { parser_options.action_view_helpers = true; }
138138

139+
VALUE prism_nodes = rb_hash_lookup(options, rb_utf8_str_new_cstr("prism_nodes"));
140+
if (NIL_P(prism_nodes)) { prism_nodes = rb_hash_lookup(options, ID2SYM(rb_intern("prism_nodes"))); }
141+
if (!NIL_P(prism_nodes) && RTEST(prism_nodes)) { parser_options.prism_nodes = true; }
142+
143+
VALUE prism_nodes_deep = rb_hash_lookup(options, rb_utf8_str_new_cstr("prism_nodes_deep"));
144+
if (NIL_P(prism_nodes_deep)) { prism_nodes_deep = rb_hash_lookup(options, ID2SYM(rb_intern("prism_nodes_deep"))); }
145+
if (!NIL_P(prism_nodes_deep) && RTEST(prism_nodes_deep)) { parser_options.prism_nodes_deep = true; }
146+
147+
VALUE prism_program = rb_hash_lookup(options, rb_utf8_str_new_cstr("prism_program"));
148+
if (NIL_P(prism_program)) { prism_program = rb_hash_lookup(options, ID2SYM(rb_intern("prism_program"))); }
149+
if (!NIL_P(prism_program) && RTEST(prism_program)) { parser_options.prism_program = true; }
150+
139151
VALUE arena_stats = rb_hash_lookup(options, rb_utf8_str_new_cstr("arena_stats"));
140152
if (NIL_P(arena_stats)) { arena_stats = rb_hash_lookup(options, ID2SYM(rb_intern("arena_stats"))); }
141153
if (!NIL_P(arena_stats) && RTEST(arena_stats)) { print_arena_stats = true; }

ext/herb/extension_helpers.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ VALUE create_parse_result(AST_DOCUMENT_NODE_T* root, VALUE source, const parser_
8989
rb_hash_aset(kwargs, ID2SYM(rb_intern("track_whitespace")), options->track_whitespace ? Qtrue : Qfalse);
9090
rb_hash_aset(kwargs, ID2SYM(rb_intern("analyze")), options->analyze ? Qtrue : Qfalse);
9191
rb_hash_aset(kwargs, ID2SYM(rb_intern("action_view_helpers")), options->action_view_helpers ? Qtrue : Qfalse);
92+
rb_hash_aset(kwargs, ID2SYM(rb_intern("prism_nodes")), options->prism_nodes ? Qtrue : Qfalse);
93+
rb_hash_aset(kwargs, ID2SYM(rb_intern("prism_nodes_deep")), options->prism_nodes_deep ? Qtrue : Qfalse);
94+
rb_hash_aset(kwargs, ID2SYM(rb_intern("prism_program")), options->prism_program ? Qtrue : Qfalse);
9295

9396
VALUE parser_options_args[1] = { kwargs };
9497
VALUE parser_options = rb_class_new_instance_kw(1, parser_options_args, cParserOptions, RB_PASS_KEYWORDS);

java/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ PRISM_BUILD = $(PRISM_PATH)/build
3030

3131
JAVAC = $(JAVA_HOME)/bin/javac
3232
JAVA_CMD = $(JAVA_HOME)/bin/java
33-
CFLAGS = -std=c99 -Wall -Wextra -fPIC -O2 -DHERB_EXCLUDE_PRETTYPRINT -DPRISM_EXCLUDE_PRETTYPRINT -DPRISM_EXCLUDE_JSON -DPRISM_EXCLUDE_PACK -DPRISM_EXCLUDE_SERIALIZATION
33+
CFLAGS = -std=c99 -Wall -Wextra -fPIC -O2 -DHERB_EXCLUDE_PRETTYPRINT -DPRISM_EXCLUDE_PRETTYPRINT -DPRISM_EXCLUDE_JSON -DPRISM_EXCLUDE_PACK
3434
INCLUDES = -I. -I$(SRC_DIR)/include -I$(PRISM_INCLUDE) $(JNI_INCLUDES)
3535
LDFLAGS = -shared
3636
LIBS = $(PRISM_BUILD)/libprism.a

java/herb_jni.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,30 @@ Java_org_herb_Herb_parse(JNIEnv* env, jclass clazz, jstring source, jobject opti
6868
jboolean actionViewHelpers = (*env)->CallBooleanMethod(env, options, getActionViewHelpers);
6969
parser_options.action_view_helpers = (actionViewHelpers == JNI_TRUE);
7070
}
71+
72+
jmethodID getPrismNodes =
73+
(*env)->GetMethodID(env, optionsClass, "isPrismNodes", "()Z");
74+
75+
if (getPrismNodes != NULL) {
76+
jboolean prismNodes = (*env)->CallBooleanMethod(env, options, getPrismNodes);
77+
parser_options.prism_nodes = (prismNodes == JNI_TRUE);
78+
}
79+
80+
jmethodID getPrismNodesDeep =
81+
(*env)->GetMethodID(env, optionsClass, "isPrismNodesDeep", "()Z");
82+
83+
if (getPrismNodesDeep != NULL) {
84+
jboolean prismNodesDeep = (*env)->CallBooleanMethod(env, options, getPrismNodesDeep);
85+
parser_options.prism_nodes_deep = (prismNodesDeep == JNI_TRUE);
86+
}
87+
88+
jmethodID getPrismProgram =
89+
(*env)->GetMethodID(env, optionsClass, "isPrismProgram", "()Z");
90+
91+
if (getPrismProgram != NULL) {
92+
jboolean prismProgram = (*env)->CallBooleanMethod(env, options, getPrismProgram);
93+
parser_options.prism_program = (prismProgram == JNI_TRUE);
94+
}
7195
}
7296

7397
hb_allocator_T allocator;

java/org/herb/HerbTest.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,51 @@ void testParserOptionsTrackWhitespace() {
102102
assertFalse(inspectWithout.contains("WhitespaceNode"));
103103
}
104104

105+
@Test
106+
void testParserOptionsPrismNodes() {
107+
String source = "<%= user.name %>";
108+
109+
ParseResult withPrism = Herb.parse(source, ParserOptions.create().prismNodes(true));
110+
String inspected = withPrism.inspect();
111+
112+
assertTrue(inspected.contains("prism_node:"));
113+
}
114+
115+
@Test
116+
void testParserOptionsPrismNodesString() {
117+
String source = "<%= \"String\" %>";
118+
119+
ParseResult withPrism = Herb.parse(source, ParserOptions.create().prismNodes(true));
120+
String inspected = withPrism.inspect();
121+
122+
assertTrue(inspected.contains("prism_node:"));
123+
assertTrue(inspected.contains("String"));
124+
}
125+
126+
@Test
127+
void testParserOptionsPrismProgram() {
128+
String source = "<%= \"hello\" %>";
129+
130+
ParseResult withPrism = Herb.parse(source, ParserOptions.create().prismProgram(true));
131+
String inspected = withPrism.inspect();
132+
133+
assertTrue(inspected.contains("prism_node:"));
134+
}
135+
136+
@Test
137+
void testParserOptionsPrismNodesDeep() {
138+
String source = "<% if true %><%= \"yes\" %><% end %>";
139+
140+
ParseResult withDeep = Herb.parse(source, ParserOptions.create().prismNodes(true).prismNodesDeep(true));
141+
ParseResult withoutDeep = Herb.parse(source, ParserOptions.create().prismNodes(true).prismNodesDeep(false));
142+
143+
String inspectDeep = withDeep.inspect();
144+
String inspectShallow = withoutDeep.inspect();
145+
146+
assertTrue(inspectDeep.contains("prism_node:"));
147+
assertTrue(inspectShallow.contains("prism_node:"));
148+
}
149+
105150
@Test
106151
void testParserOptionsAnalyze() {
107152
String source = "<% if true %><div></div><% end %>";

java/org/herb/ParseResult.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public String inspect() {
5050
StringBuilder builder = new StringBuilder();
5151

5252
if (value != null) {
53-
builder.append(value.inspect());
53+
builder.append(value.inspect(source));
5454
}
5555

5656
if (hasErrors()) {

java/org/herb/ParserOptions.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ public class ParserOptions {
55
private boolean analyze = true;
66
private boolean strict = true;
77
private boolean actionViewHelpers = false;
8+
private boolean prismNodes = false;
9+
private boolean prismNodesDeep = false;
10+
private boolean prismProgram = false;
811

912
public ParserOptions() {}
1013

@@ -44,6 +47,33 @@ public boolean isActionViewHelpers() {
4447
return actionViewHelpers;
4548
}
4649

50+
public ParserOptions prismNodes(boolean value) {
51+
this.prismNodes = value;
52+
return this;
53+
}
54+
55+
public boolean isPrismNodes() {
56+
return prismNodes;
57+
}
58+
59+
public ParserOptions prismNodesDeep(boolean value) {
60+
this.prismNodesDeep = value;
61+
return this;
62+
}
63+
64+
public boolean isPrismNodesDeep() {
65+
return prismNodesDeep;
66+
}
67+
68+
public ParserOptions prismProgram(boolean value) {
69+
this.prismProgram = value;
70+
return this;
71+
}
72+
73+
public boolean isPrismProgram() {
74+
return prismProgram;
75+
}
76+
4777
public static ParserOptions create() {
4878
return new ParserOptions();
4979
}

0 commit comments

Comments
 (0)