ParseTree 2.0.1 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
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