ParseTree 2.0.1 → 2.0.2

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 (4) hide show
  1. data/History.txt +13 -0
  2. data/Rakefile +1 -1
  3. data/lib/parse_tree.rb +101 -97
  4. metadata +2 -2
@@ -1,3 +1,16 @@
1
+ === 2.0.2 / 2007-09-20
2
+
3
+ * 2 minor enhancements:
4
+
5
+ * Deactivated gcc-specific compiler flags unless ENV['ANAL'] or on my domain.
6
+ * Minor code cleanup - happier with -pedantic and the like.
7
+
8
+ * 1 bug fix:
9
+
10
+ * FINALLY conquered the splat args bug on certain platforms/versions.
11
+ Special Thanks to Jonas Pfenniger for debugging this and providing
12
+ a patch.
13
+
1
14
  === 2.0.1 / 2007-08-21
2
15
 
3
16
  * 1 major enhancement:
data/Rakefile CHANGED
@@ -11,7 +11,7 @@ Hoe.new("ParseTree", ParseTree::VERSION) do |p|
11
11
  p.summary = "Extract and enumerate ruby parse trees."
12
12
  p.summary = p.paragraphs_of("README.txt", 2).join("\n\n")
13
13
  p.description = p.paragraphs_of("README.txt", 2..6, 8).join("\n\n")
14
- p.changes = p.paragraphs_of("History.txt", 1..6).join("\n\n")
14
+ p.changes = p.paragraphs_of("History.txt", 1..6).join("\n\n").gsub(/\s*===.*\Z/ms, '')
15
15
  p.clean_globs << File.expand_path("~/.ruby_inline")
16
16
  p.extra_deps << ['RubyInline', '>= 3.6.0']
17
17
  p.spec_extras[:require_paths] = proc { |paths| paths << 'test' }
@@ -41,7 +41,7 @@ end
41
41
 
42
42
  class ParseTree
43
43
 
44
- VERSION = '2.0.1'
44
+ VERSION = '2.0.2'
45
45
 
46
46
  ##
47
47
  # Front end translation method.
@@ -79,7 +79,7 @@ class ParseTree
79
79
 
80
80
  def initialize(include_newlines=$DEBUG)
81
81
  if include_newlines then
82
- warn "WARNING: include_newlines=true from #{caller[0..9].join(', ')}"
82
+ warn "WAR\NING: include_newlines=true from #{caller[0..9].join(', ')}"
83
83
  end
84
84
  @include_newlines = include_newlines
85
85
  end
@@ -100,8 +100,6 @@ class ParseTree
100
100
  def parse_tree(*klasses)
101
101
  result = []
102
102
  klasses.each do |klass|
103
- # TODO: remove this on v 1.1
104
- raise "You should call parse_tree_for_method(#{klasses.first}, #{klass}) instead of parse_tree" if Symbol === klass or String === klass
105
103
  klassname = klass.name rescue '' # HACK klass.name should never be nil
106
104
  # Tempfile's DelegateClass(File) seems to
107
105
  # cause this
@@ -123,14 +121,12 @@ class ParseTree
123
121
 
124
122
  method_names.sort.each do |m|
125
123
  r = parse_tree_for_method(klass, m.to_sym)
126
- p m => r if r == [nil]
127
124
  code << r
128
125
  end
129
126
 
130
127
  klass.modules.each do |mod| # TODO: add a test for this damnit
131
128
  mod.instance_methods.each do |m|
132
129
  r = parse_tree_for_method(mod, m.to_sym)
133
- p m => r if r == [nil]
134
130
  code << r
135
131
  end
136
132
  end
@@ -254,13 +250,27 @@ p m => r if r == [nil]
254
250
  builder.include '"node.h"'
255
251
  builder.include '"st.h"'
256
252
  builder.include '"env.h"'
257
- builder.add_compile_flags "-Wall"
258
- builder.add_compile_flags "-W"
259
- builder.add_compile_flags "-Wpointer-arith"
260
- builder.add_compile_flags "-Wcast-qual"
261
- builder.add_compile_flags "-Wcast-align"
262
- builder.add_compile_flags "-Wwrite-strings"
263
- builder.add_compile_flags "-Wmissing-noreturn"
253
+
254
+ if ENV['ANAL'] or ENV['DOMAIN'] =~ /zenspider/ then
255
+ builder.add_compile_flags "-Wall"
256
+ builder.add_compile_flags "-W"
257
+ builder.add_compile_flags "-Wpointer-arith"
258
+ builder.add_compile_flags "-Wcast-qual"
259
+ builder.add_compile_flags "-Wcast-align"
260
+ builder.add_compile_flags "-Wwrite-strings"
261
+ builder.add_compile_flags "-Wmissing-noreturn"
262
+ builder.add_compile_flags "-Wno-long-long"
263
+
264
+ # NOTE: this flag doesn't work w/ gcc 2.95.x - the FreeBSD default
265
+ # builder.add_compile_flags "-Wno-strict-aliasing"
266
+ # ruby.h screws these up hardcore:
267
+ # builder.add_compile_flags "-Wundef"
268
+ # builder.add_compile_flags "-Wconversion"
269
+ # builder.add_compile_flags "-Wstrict-prototypes"
270
+ # builder.add_compile_flags "-Wmissing-prototypes"
271
+ # builder.add_compile_flags "-Wsign-compare"
272
+ end
273
+
264
274
  # NOTE: If you get weird compiler errors like:
265
275
  # dereferencing type-punned pointer will break strict-aliasing rules
266
276
  # PLEASE do one of the following:
@@ -268,18 +278,6 @@ p m => r if r == [nil]
268
278
  # 2) Fix it and send me the patch
269
279
  # 3) (quick, but dirty and bad), comment out the following line:
270
280
  builder.add_compile_flags "-Werror"
271
- # NOTE: this flag doesn't work w/ gcc 2.95.x - the FreeBSD default
272
- # builder.add_compile_flags "-Wno-strict-aliasing"
273
- # ruby.h screws these up hardcore:
274
- # builder.add_compile_flags "-Wundef"
275
- # builder.add_compile_flags "-Wconversion"
276
- # builder.add_compile_flags "-Wstrict-prototypes"
277
- # builder.add_compile_flags "-Wmissing-prototypes"
278
- # builder.add_compile_flags "-Wsign-compare"
279
-
280
- def self.if_version(test, version, str)
281
- RUBY_VERSION.send(test, version) ? str : ""
282
- end
283
281
 
284
282
  builder.prefix %{
285
283
  #define nd_3rd u3.node
@@ -300,7 +298,9 @@ p m => r if r == [nil]
300
298
  VALUE klass, rklass;
301
299
  VALUE recv;
302
300
  ID id, oid;
303
- #{if_version :>, "1.8.2", "int safe_level;"}
301
+ #if RUBY_VERSION_CODE > 182
302
+ int safe_level;
303
+ #endif
304
304
  NODE *body;
305
305
  };
306
306
 
@@ -376,7 +376,7 @@ again_no_block:
376
376
  }
377
377
  contnode = node->nd_next;
378
378
 
379
- // FIX: this will break the moment there is a block w/in a block
379
+ /* FIX: this will break the moment there is a block w/in a block */
380
380
  old_ary = ary;
381
381
  ary = current;
382
382
  node = node->nd_head;
@@ -501,10 +501,12 @@ again_no_block:
501
501
  add_to_parse_tree(current, node->nd_3rd, newlines, locals);
502
502
  break;
503
503
 
504
+ /*
504
505
  // rescue body:
505
506
  // begin stmt rescue exception => var; stmt; [rescue e2 => v2; s2;]* end
506
507
  // stmt rescue stmt
507
508
  // a = b rescue c
509
+ */
508
510
 
509
511
  case NODE_RESBODY:
510
512
  if (node->nd_3rd) {
@@ -576,7 +578,7 @@ again_no_block:
576
578
  }
577
579
  break;
578
580
 
579
- #{if_version :>, "1.9", '#if 0'}
581
+ #if RUBY_VERSION_CODE < 190
580
582
  case NODE_DMETHOD:
581
583
  {
582
584
  struct METHOD *data;
@@ -585,10 +587,9 @@ again_no_block:
585
587
  add_to_parse_tree(current, data->body, newlines, locals);
586
588
  break;
587
589
  }
588
- #{if_version :>, "1.9", '#endif'}
590
+ #endif
589
591
 
590
592
  case NODE_METHOD:
591
- fprintf(stderr, "u1 = %p u2 = %p u3 = %p\\n", node->nd_1st, node->nd_2nd, node->nd_3rd);
592
593
  add_to_parse_tree(current, node->nd_3rd, newlines, locals);
593
594
  break;
594
595
 
@@ -598,10 +599,9 @@ again_no_block:
598
599
 
599
600
  case NODE_OP_ASGN1:
600
601
  add_to_parse_tree(current, node->nd_recv, newlines, locals);
601
- #{if_version :>, "1.8.4", "#if 0"}
602
- #{if_version :<=, "1.8.4", "#if 1"}
602
+ #if RUBY_VERSION_CODE < 185
603
603
  add_to_parse_tree(current, node->nd_args->nd_next, newlines, locals);
604
- rb_ary_pop(rb_ary_entry(current, -1)); // no idea why I need this
604
+ rb_ary_pop(rb_ary_entry(current, -1)); /* no idea why I need this */
605
605
  #else
606
606
  add_to_parse_tree(current, node->nd_args->nd_2nd, newlines, locals);
607
607
  #endif
@@ -664,9 +664,8 @@ again_no_block:
664
664
  add_to_parse_tree(current, node->nd_value, newlines, locals);
665
665
  break;
666
666
 
667
- case NODE_VALIAS: // u1 u2 (alias $global $global2)
668
- #{if_version :>, "1.8.4", "#if 0"}
669
- #{if_version :<=, "1.8.4", "#if 1"}
667
+ case NODE_VALIAS: /* u1 u2 (alias $global $global2) */
668
+ #if RUBY_VERSION_CODE < 185
670
669
  rb_ary_push(current, ID2SYM(node->u2.id));
671
670
  rb_ary_push(current, ID2SYM(node->u1.id));
672
671
  #else
@@ -674,9 +673,8 @@ again_no_block:
674
673
  rb_ary_push(current, ID2SYM(node->u2.id));
675
674
  #endif
676
675
  break;
677
- case NODE_ALIAS: // u1 u2 (alias :blah :blah2)
678
- #{if_version :>, "1.8.4", "#if 0"}
679
- #{if_version :<=, "1.8.4", "#if 1"}
676
+ case NODE_ALIAS: /* u1 u2 (alias :blah :blah2) */
677
+ #if RUBY_VERSION_CODE < 185
680
678
  rb_ary_push(current, wrap_into_node("lit", ID2SYM(node->u2.id)));
681
679
  rb_ary_push(current, wrap_into_node("lit", ID2SYM(node->u1.id)));
682
680
  #else
@@ -685,16 +683,15 @@ again_no_block:
685
683
  #endif
686
684
  break;
687
685
 
688
- case NODE_UNDEF: // u2 (undef name, ...)
689
- #{if_version :>, "1.8.4", "#if 0"}
690
- #{if_version :<=, "1.8.4", "#if 1"}
686
+ case NODE_UNDEF: /* u2 (undef name, ...) */
687
+ #if RUBY_VERSION_CODE < 185
691
688
  rb_ary_push(current, wrap_into_node("lit", ID2SYM(node->u2.id)));
692
689
  #else
693
690
  add_to_parse_tree(current, node->nd_value, newlines, locals);
694
691
  #endif
695
692
  break;
696
693
 
697
- case NODE_COLON3: // u2 (::OUTER_CONST)
694
+ case NODE_COLON3: /* u2 (::OUTER_CONST) */
698
695
  rb_ary_push(current, ID2SYM(node->u2.id));
699
696
  break;
700
697
 
@@ -777,28 +774,37 @@ again_no_block:
777
774
  break;
778
775
 
779
776
  case NODE_ARGS: {
780
- long arg_count = (long)node->nd_rest;
781
- if (locals && (node->nd_cnt || node->nd_opt || arg_count != -1)) {
782
- int i;
783
- int max_args;
784
- NODE *optnode;
785
-
786
- max_args = node->nd_cnt;
787
- for (i = 0; i < max_args; i++) {
788
- // regular arg names
789
- rb_ary_push(current, ID2SYM(locals[i + 3]));
790
- }
777
+ NODE *optnode;
778
+ int i = 0, max_args = node->nd_cnt;
791
779
 
792
- optnode = node->nd_opt;
793
- while (optnode) {
794
- // optional arg names
795
- rb_ary_push(current, ID2SYM(locals[i + 3]));
796
- i++;
797
- optnode = optnode->nd_next;
798
- }
780
+ /* push regular argument names */
781
+ for (; i < max_args; i++) {
782
+ rb_ary_push(current, ID2SYM(locals[i + 3]));
783
+ }
784
+
785
+ /* look for optional arguments */
786
+ optnode = node->nd_opt;
787
+ while (optnode) {
788
+ rb_ary_push(current, ID2SYM(locals[i + 3]));
789
+ i++;
790
+ optnode = optnode->nd_next;
791
+ }
799
792
 
793
+ /* look for vargs */
794
+ #if RUBY_VERSION_CODE > 184
795
+ if (node->nd_rest) {
796
+ VALUE sym = rb_str_new2("*");
797
+ if (locals[i + 3]) {
798
+ rb_str_concat(sym, rb_str_new2(rb_id2name(locals[i + 3])));
799
+ }
800
+ sym = rb_str_intern(sym);
801
+ rb_ary_push(current, sym);
802
+ }
803
+ #else
804
+ {
805
+ long arg_count = (long)node->nd_rest;
800
806
  if (arg_count > 0) {
801
- // *arg name
807
+ /* *arg name */
802
808
  VALUE sym = rb_str_new2("*");
803
809
  if (locals[i + 3]) {
804
810
  rb_str_concat(sym, rb_str_new2(rb_id2name(locals[i + 3])));
@@ -806,24 +812,22 @@ again_no_block:
806
812
  sym = rb_str_intern(sym);
807
813
  rb_ary_push(current, sym);
808
814
  } else if (arg_count == 0) {
809
- // nothing to do in this case, empty list
815
+ /* nothing to do in this case, empty list */
810
816
  } else if (arg_count == -1) {
811
- // nothing to do in this case, handled above
817
+ /* nothing to do in this case, handled above */
812
818
  } else if (arg_count == -2) {
813
- // nothing to do in this case, no name == no use
814
- #if RUBY_VERSION_CODE < 185
819
+ /* nothing to do in this case, no name == no use */
815
820
  rb_ary_push(current, rb_str_intern(rb_str_new2("*")));
816
- #endif
817
821
  } else {
818
822
  rb_raise(rb_eArgError,
819
823
  "not a clue what this arg value is: %ld", arg_count);
820
824
  }
825
+ }
826
+ #endif
821
827
 
822
- optnode = node->nd_opt;
823
- // block?
824
- if (optnode) {
825
- add_to_parse_tree(current, node->nd_opt, newlines, locals);
826
- }
828
+ optnode = node->nd_opt;
829
+ if (optnode) {
830
+ add_to_parse_tree(current, node->nd_opt, newlines, locals);
827
831
  }
828
832
  } break;
829
833
 
@@ -837,13 +841,13 @@ again_no_block:
837
841
  rb_ary_push(current, ID2SYM(node->nd_vid));
838
842
  break;
839
843
 
840
- case NODE_XSTR: // u1 (%x{ls})
841
- case NODE_STR: // u1
844
+ case NODE_XSTR: /* u1 (%x{ls}) */
845
+ case NODE_STR: /* u1 */
842
846
  case NODE_LIT:
843
847
  rb_ary_push(current, node->nd_lit);
844
848
  break;
845
849
 
846
- case NODE_MATCH: // u1 -> [:lit, u1]
850
+ case NODE_MATCH: /* u1 -> [:lit, u1] */
847
851
  {
848
852
  rb_ary_push(current, wrap_into_node("lit", node->nd_lit));
849
853
  }
@@ -853,28 +857,28 @@ again_no_block:
853
857
  rb_ary_push(current, INT2FIX(nd_line(node)));
854
858
  rb_ary_push(current, rb_str_new2(node->nd_file));
855
859
 
856
- if (! RTEST(newlines)) rb_ary_pop(ary); // nuke it
860
+ if (! RTEST(newlines)) rb_ary_pop(ary); /* nuke it */
857
861
 
858
862
  node = node->nd_next;
859
863
  goto again;
860
864
  break;
861
865
 
862
- case NODE_NTH_REF: // u2 u3 ($1) - u3 is local_cnt('~') ignorable?
866
+ case NODE_NTH_REF: /* u2 u3 ($1) - u3 is local_cnt('~') ignorable? */
863
867
  rb_ary_push(current, INT2FIX(node->nd_nth));
864
868
  break;
865
869
 
866
- case NODE_BACK_REF: // u2 u3 ($& etc)
870
+ case NODE_BACK_REF: /* u2 u3 ($& etc) */
867
871
  {
868
872
  char c = node->nd_nth;
869
873
  rb_ary_push(current, rb_str_intern(rb_str_new(&c, 1)));
870
874
  }
871
875
  break;
872
876
 
873
- case NODE_BLOCK_ARG: // u1 u3 (def x(&b)
877
+ case NODE_BLOCK_ARG: /* u1 u3 (def x(&b) */
874
878
  rb_ary_push(current, ID2SYM(node->u1.id));
875
879
  break;
876
880
 
877
- // these nodes are empty and do not require extra work:
881
+ /* these nodes are empty and do not require extra work: */
878
882
  case NODE_RETRY:
879
883
  case NODE_FALSE:
880
884
  case NODE_NIL:
@@ -887,12 +891,12 @@ again_no_block:
887
891
 
888
892
  case NODE_SPLAT:
889
893
  case NODE_TO_ARY:
890
- case NODE_SVALUE: // a = b, c
894
+ case NODE_SVALUE: /* a = b, c */
891
895
  add_to_parse_tree(current, node->nd_head, newlines, locals);
892
896
  break;
893
897
 
894
- case NODE_ATTRASGN: // literal.meth = y u1 u2 u3
895
- // node id node
898
+ case NODE_ATTRASGN: /* literal.meth = y u1 u2 u3 */
899
+ /* node id node */
896
900
  if (node->nd_1st == RNODE(1)) {
897
901
  add_to_parse_tree(current, NEW_SELF(), newlines, locals);
898
902
  } else {
@@ -906,8 +910,8 @@ again_no_block:
906
910
  add_to_parse_tree(current, node->nd_2nd, newlines, locals);
907
911
  break;
908
912
 
909
- case NODE_POSTEXE: // END { ... }
910
- // Nothing to do here... we are in an iter block
913
+ case NODE_POSTEXE: /* END { ... } */
914
+ /* Nothing to do here... we are in an iter block */
911
915
  break;
912
916
 
913
917
  case NODE_CFUNC:
@@ -916,28 +920,28 @@ again_no_block:
916
920
  rb_ary_push(current, INT2NUM(node->nd_argc));
917
921
  break;
918
922
 
919
- #{if_version :<, "1.9", "#if 0"}
923
+ #if RUBY_VERSION_CODE >= 190
920
924
  case NODE_ERRINFO:
921
925
  case NODE_VALUES:
922
926
  case NODE_PRELUDE:
923
927
  case NODE_LAMBDA:
924
928
  puts("no worky in 1.9 yet");
925
929
  break;
926
- #{if_version :<, "1.9", "#endif"}
930
+ #endif
927
931
 
928
- // Nodes we found but have yet to decypher
929
- // I think these are all runtime only... not positive but...
930
- case NODE_MEMO: // enum.c zip
932
+ /* Nodes we found but have yet to decypher */
933
+ /* I think these are all runtime only... not positive but... */
934
+ case NODE_MEMO: /* enum.c zip */
931
935
  case NODE_CREF:
932
- // #defines:
933
- // case NODE_LMASK:
934
- // case NODE_LSHIFT:
936
+ /* #defines: */
937
+ /* case NODE_LMASK: */
938
+ /* case NODE_LSHIFT: */
935
939
  default:
936
940
  rb_warn("Unhandled node #%d type '%s'", nd_type(node), rb_id2name(SYM2ID(rb_ary_entry(node_names, nd_type(node)))));
937
941
  if (RNODE(node)->u1.node != NULL) rb_warning("unhandled u1 value");
938
942
  if (RNODE(node)->u2.node != NULL) rb_warning("unhandled u2 value");
939
943
  if (RNODE(node)->u3.node != NULL) rb_warning("unhandled u3 value");
940
- if (RTEST(ruby_debug)) fprintf(stderr, "u1 = %p u2 = %p u3 = %p\\n", node->nd_1st, node->nd_2nd, node->nd_3rd);
944
+ if (RTEST(ruby_debug)) fprintf(stderr, "u1 = %p u2 = %p u3 = %p\\n", (void*)node->nd_1st, (void*)node->nd_2nd, (void*)node->nd_3rd);
941
945
  rb_ary_push(current, INT2FIX(-99));
942
946
  rb_ary_push(current, INT2FIX(nd_type(node)));
943
947
  break;
@@ -963,14 +967,14 @@ static VALUE parse_tree_for_meth(VALUE klass, VALUE method, VALUE newlines, VALU
963
967
  VALUE result = rb_ary_new();
964
968
  VALUE version = rb_const_get_at(rb_cObject,rb_intern("RUBY_VERSION"));
965
969
 
966
- (void) self; // quell warnings
970
+ (void) self; /* quell warnings */
967
971
 
968
972
  if (strcmp(StringValuePtr(version), #{RUBY_VERSION.inspect})) {
969
973
  rb_fatal("bad version, %s != #{RUBY_VERSION}\\n", StringValuePtr(version));
970
974
  }
971
975
 
972
976
  id = rb_to_id(method);
973
- if (RTEST(is_cls_meth)) { // singleton method
977
+ if (RTEST(is_cls_meth)) { /* singleton method */
974
978
  klass = CLASS_OF(klass);
975
979
  }
976
980
  if (st_lookup(RCLASS(klass)->m_tbl, id, &n)) {
@@ -1000,7 +1004,7 @@ static VALUE parse_tree_for_str(VALUE source, VALUE filename, VALUE line,
1000
1004
  NODE *node = NULL;
1001
1005
  int critical;
1002
1006
 
1003
- (void) self; // quell warnings
1007
+ (void) self; /* quell warnings */
1004
1008
 
1005
1009
  tmp = rb_check_string_type(filename);
1006
1010
  if (NIL_P(tmp)) {
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
3
3
  specification_version: 1
4
4
  name: ParseTree
5
5
  version: !ruby/object:Gem::Version
6
- version: 2.0.1
7
- date: 2007-08-21 00:00:00 -07:00
6
+ version: 2.0.2
7
+ date: 2007-09-20 00:00:00 -07:00
8
8
  summary: ParseTree is a C extension (using RubyInline) that extracts the parse tree for an entire class or a specific method and returns it as a s-expression (aka sexp) using ruby's arrays, strings, symbols, and integers.
9
9
  require_paths:
10
10
  - lib