riml 0.3.9 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MDk4OTEyMjkyYTk1YzVjYjEzNzAxNTllZGVmNjY0NGE5YTJjZWZmYQ==
4
+ YzcxODgxN2I3YzM3MjdlZjdhMDM1Y2E4NzhmZmM1ZjM3YWQ1ZjQ0YQ==
5
5
  data.tar.gz: !binary |-
6
- OTY1ZDRlMDVjNGY3ZjA3YmViZGE2M2RjY2VkODg2ZjJhMDk5NTkxZA==
6
+ NjcxN2EzNDgyZTVjODZkZjE3MGIyZTk2MmQwMzI1NDRhNmViZjI0NA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MTk4MTY0Y2FiMGQ0ZDc4ODNjNDk4NDdmOGViZmFhODUxMmYxY2E1NjY5Njk4
10
- ZDIxNGI3ZjI3ZjQyZjcxNDNmYWQxYWUyNTNlNzk0ODc1ZmEzZDU1YmUwZGQ1
11
- YmQ1Y2E0N2M4YzE1OWFhMmZlNjkzYTZlOWQ4OWUyYmFlOWVlZmU=
9
+ YTU5N2JjMjdkODhhZjBkOTlkNmMwYjdkMTg5ZmUxZTIwNzAyNTZhYmMwMGZl
10
+ ZWE3MmI1ODI3Nzk3OTliOTcwZWZiOTcwMzkwY2I2OTUyZDQwZWNjYmI1ZmQy
11
+ NDVjYTIzNjdlNWQzNzk5YjBiOGMwZWY4NDBkNmZlZGE1MmU1ZDQ=
12
12
  data.tar.gz: !binary |-
13
- MTc4ZjZkZjE1MmU3YTRkNDVlYjA2NTE4YzRhYjk1MGE1NTkwM2FlMjM1NTYw
14
- OGU2ZWRmZDM2YmM2OTZlZmIwODI0ZmYxNTFjMWNlZWIxM2EyNWMyNDQxYzBk
15
- MTU3NjJhMjNlM2Q3YTVkNDYxNjljZjZiNDNlMzA2NzQyOTZlODI=
13
+ NjhmMTc0MjIzMDMzNmU2ZDIyMWIyZTZlYWZkNWZmNDNkMzVhMzYzYWE4NWQ0
14
+ YjU5NDI2ZTQ5MmJhYmJjODE1ZDg0ZjFiMTg1MDllNWE3NDJjNjQwZjBlZDhj
15
+ YzQ4ODgyNTA5Y2JjNWFhZmVhNmIyZWZjMzVlODIxMGFhY2ZmOTI=
@@ -63,7 +63,7 @@ module Riml
63
63
  DefaultParamToIfNode.new(ast, classes),
64
64
  DeserializeVarAssignment.new(ast, classes),
65
65
  TopLevelDefMethodToDef.new(ast, classes),
66
- SplatsToExecuteInCallingContext.new(ast, classes)
66
+ SplatsToCallFunctionInCallingContext.new(ast, classes)
67
67
  ]
68
68
  rewriters.each do |rewriter|
69
69
  rewriter.rewrite_on_match
@@ -414,10 +414,11 @@ module Riml
414
414
 
415
415
  InitializeSuperToObjectExtension.new(constructor, classes, node).rewrite_on_match
416
416
  ExtendObjectWithMethods.new(node, classes).rewrite_on_match
417
- SelfToDictName.new(dict_name).rewrite_on_match(constructor)
417
+ SelfToDictNameInAssignments.new(dict_name).rewrite_on_match(constructor)
418
418
  SuperToSuperclassFunction.new(node, classes).rewrite_on_match
419
419
  PrivateFunctionCallToPassObjExplicitly.new(node, classes).rewrite_on_match
420
- SplatsToExecuteInCallingContext.new(node, classes).rewrite_on_match
420
+ SplatsToCallFunctionInCallingContext.new(node, classes).rewrite_on_match
421
+ SelfToDictName.new(dict_name).rewrite_on_match(constructor)
421
422
 
422
423
  constructor.expressions.nodes.push(
423
424
  ReturnNode.new(GetVariableNode.new(nil, dict_name))
@@ -495,8 +496,11 @@ module Riml
495
496
 
496
497
  class PrivateFunctionCallToPassObjExplicitly < AST_Rewriter
497
498
  def match?(node)
498
- CallNode === node && DictGetDotNode === node.name && node.name.dict.scope_modifier.nil? &&
499
- node.name.dict.name == 'self' && (node.name.keys & ast.private_function_names).size == 1
499
+ CallNode === node && node.name.instance_of?(DictGetDotNode) &&
500
+ !node.name.dict.is_a?(ListOrDictGetNode) &&
501
+ node.name.dict.scope_modifier.nil? &&
502
+ node.name.dict.name == 'self' &&
503
+ (node.name.keys & ast.private_function_names).size == 1
500
504
  end
501
505
 
502
506
  def replace(node)
@@ -575,7 +579,12 @@ module Riml
575
579
  end
576
580
  end
577
581
 
578
- class SelfToDictName < AST_Rewriter
582
+ # if inside 'Foo' class,
583
+ # transforms:
584
+ # self.something = 1
585
+ # to:
586
+ # fooObj.something = 1
587
+ class SelfToDictNameInAssignments < AST_Rewriter
579
588
  attr_reader :dict_name
580
589
  def initialize(dict_name)
581
590
  @dict_name = dict_name
@@ -586,7 +595,27 @@ module Riml
586
595
  end
587
596
 
588
597
  def replace(node)
589
- node.lhs.dict.name = dict_name
598
+ node.lhs.dict.name = @dict_name
599
+ end
600
+ end
601
+
602
+ # if inside 'Foo' class,
603
+ # transforms:
604
+ # extend(self, {})
605
+ # to:
606
+ # extend(fooObj, {})
607
+ class SelfToDictName < AST_Rewriter
608
+ attr_reader :dict_name
609
+ def initialize(dict_name)
610
+ @dict_name = dict_name
611
+ end
612
+
613
+ def match?(node)
614
+ GetVariableNode === node && node.name == "self" && node.scope_modifier.nil?
615
+ end
616
+
617
+ def replace(node)
618
+ node.name = @dict_name
590
619
  end
591
620
  end
592
621
 
@@ -726,20 +755,11 @@ module Riml
726
755
  # parameter to the function we're in) to the splat arg
727
756
  if @function_node.private_function?
728
757
  if (splat_node = node_args.detect { |arg| SplatNode === arg })
729
- splat_node.expression = WrapInParensNode.new(
730
- BinaryOperatorNode.new(
731
- '+',
732
- [
733
- ListNode.new([
734
- GetVariableNode.new('a:', @function_node.parameters.first)
735
- ]),
736
- GetVariableNode.new('a:', '000')
737
- ]
738
- )
739
- )
758
+ self_var = GetVariableNode.new('a:', @function_node.parameters.first)
759
+ splat_node.expression = BinaryOperatorNode.new('+', [ListNode.wrap(self_var), splat_node.expression])
740
760
  establish_parents(splat_node.expression)
741
761
  end
742
- # call s.ClassA_private_func(args)
762
+ # call s:ClassA_private_func(args)
743
763
  call_node_name = superclass_func_name(superclass)
744
764
  else
745
765
  # call self.ClassA_public_func(args)
@@ -754,6 +774,7 @@ module Riml
754
774
  node_args
755
775
  )
756
776
 
777
+ call_node.super_call = true
757
778
  node.replace_with(call_node)
758
779
  # private functions are NOT extended in constructor function
759
780
  unless @function_node.private_function?
@@ -803,164 +824,39 @@ module Riml
803
824
  #
804
825
  # to:
805
826
  #
806
- # let __riml_splat_list = a:000
807
- # let __riml_splat_size = len(__riml_splat_list)
808
- # let __riml_splat_str_vars = []
809
- # let __riml_splat_idx = 1
810
- # while __riml_splat_idx <=# __riml_splat_size
811
- # let __riml_splat_var_{__riml_splat_idx} = get(__riml_splat_list, __riml_splat_idx - 1)
812
- # call add(__riml_splat_str_vars, __riml_splat_var_{__riml_splat_idx})
813
- # let __riml_splat_idx += 1
814
- # endwhile
815
- # execute 'let s:animalObj = s:AnimalConstructor(' . join(__riml_splat_str_vars, ', ') . ')'
827
+ # let animalObj = call('s:AnimalConstructor', a:000)
816
828
  #
817
829
  # Basically, mimic Ruby's approach to expanding lists to their
818
830
  # constituent argument parts with '*' in calling context.
819
- class SplatsToExecuteInCallingContext < AST_Rewriter
831
+ class SplatsToCallFunctionInCallingContext < AST_Rewriter
820
832
 
821
833
  def match?(node)
822
- if SplatNode === node && CallNode === node.parent
823
- @splat_node = node
824
- end
834
+ SplatNode === node && CallNode === node.parent
825
835
  end
826
836
 
827
837
  def replace(node)
828
- construct_splat_str_vars_node = build_construct_splat_str_vars_node
829
- call_node_args =
830
- CallNode.new(
831
- nil,
832
- 'join',
833
- [
834
- GetVariableNode.new(tmp_var_modifier.dup, '__riml_splat_str_vars'),
835
- StringNode.new(', ', :s)
836
- ]
837
- )
838
838
  call_node = node.parent
839
- node_to_execute = if AssignNode === call_node.parent
840
- assign_node = call_node.parent
841
- n = call_node
842
- until DefNode === n || n.nil?
843
- n = n.parent
844
- end
845
- # This is necessary because this node is getting put into a new
846
- # compiler where it not wrapped in a function context, therefore
847
- # variables will be script-local there unless their scope_modifier
848
- # is set
849
- if n && assign_node.lhs.scope_modifier.nil?
850
- if global_scope?
851
- assign_node.lhs.scope_modifier = 's:'
852
- else
853
- assign_node.lhs.scope_modifier = 'l:'
854
- end
855
- end
856
- assign_node
857
- else
858
- call_node
859
- end
860
- call_node.arguments.clear
861
- compiler = Compiler.new
862
- # have to dup node_to_execute here because, if not, its parent will
863
- # get reset during this next compilation step
864
- output = compiler.compile(Nodes.new([node_to_execute.clone]))
865
- execute_string_node = StringNode.new(output.chomp[0..-2], :s)
866
- if node_to_execute.instance_of?(CallNode)
867
- execute_string_node.value.insert(0, 'call ')
868
- end
869
- execute_arg = BinaryOperatorNode.new(
870
- '.',
871
- [
872
- execute_string_node,
873
- BinaryOperatorNode.new(
874
- '.',
875
- [
876
- call_node_args,
877
- StringNode.new(')', :s)
878
- ]
879
- )
880
- ]
881
- )
882
- execute_node = CallNode.new(nil, 'execute', [execute_arg])
883
- establish_parents(execute_node)
884
- node.remove
885
- node_to_execute.replace_with(construct_splat_str_vars_node)
886
- execute_node.parent = construct_splat_str_vars_node.parent
887
- construct_splat_str_vars_node.parent.insert_after(construct_splat_str_vars_node, execute_node)
888
- end
889
-
890
- private
891
-
892
- def build_construct_splat_str_vars_node
893
- nodes = Nodes.new([])
894
- splat_list_init = AssignNode.new(
895
- '=',
896
- GetVariableNode.new(tmp_var_modifier.dup, '__riml_splat_list'),
897
- @splat_node.expression
898
- )
899
- splat_size = AssignNode.new(
900
- '=',
901
- GetVariableNode.new(tmp_var_modifier.dup, '__riml_splat_size'),
902
- CallNode.new(nil, 'len', [GetVariableNode.new(tmp_var_modifier.dup, '__riml_splat_list')])
903
- )
904
- splat_string_vars_init = AssignNode.new(
905
- '=',
906
- GetVariableNode.new(tmp_var_modifier.dup, '__riml_splat_str_vars'),
907
- ListNode.new([])
908
- )
909
- splat_list_idx_init = AssignNode.new(
910
- '=',
911
- GetVariableNode.new(tmp_var_modifier.dup, '__riml_splat_idx'),
912
- NumberNode.new('1')
913
- )
914
- while_loop = WhileNode.new(
915
- # condition
916
- BinaryOperatorNode.new('<=', [GetVariableNode.new(tmp_var_modifier.dup, '__riml_splat_idx'), GetVariableNode.new(tmp_var_modifier.dup, '__riml_splat_size')]),
917
- # body
918
- Nodes.new([
919
- AssignNode.new(
920
- '=',
921
- GetCurlyBraceNameNode.new(tmp_var_modifier.dup, CurlyBraceVariable.new([CurlyBracePart.new('__riml_splat_var_'), CurlyBraceVariable.new([CurlyBracePart.new(GetVariableNode.new(tmp_var_modifier.dup, '__riml_splat_idx'))])])),
922
- CallNode.new(nil, 'get', [
923
- GetVariableNode.new(tmp_var_modifier.dup, '__riml_splat_list'),
924
- BinaryOperatorNode.new('-', [
925
- GetVariableNode.new(tmp_var_modifier.dup, '__riml_splat_idx'),
926
- NumberNode.new('1')
927
- ])
928
- ])
929
- ),
930
- ExplicitCallNode.new(nil, 'add', [
931
- GetVariableNode.new(tmp_var_modifier.dup, '__riml_splat_str_vars'),
932
- BinaryOperatorNode.new('.', [StringNode.new('__riml_splat_var_', :s), GetVariableNode.new(tmp_var_modifier.dup, '__riml_splat_idx')])
839
+ is_method_call = call_node.method_call?
840
+ function_name_expr = if is_method_call && call_node.super_call?
841
+ BinaryOperatorNode.new('.', [
842
+ BinaryOperatorNode.new('.', [
843
+ StringNode.new('<SNR>', :s), CallNode.new('s:', 'SID', [])
933
844
  ]),
934
- AssignNode.new('+=', GetVariableNode.new(tmp_var_modifier.dup, '__riml_splat_idx'), NumberNode.new('1'))
845
+ StringNode.new("_s:#{call_node.name.keys.last}", :s)
935
846
  ])
936
- )
937
- nodes << splat_list_init << splat_size << splat_string_vars_init <<
938
- splat_list_idx_init << while_loop
939
- establish_parents(nodes)
940
- nodes
941
- end
942
-
943
- def tmp_var_modifier
944
- @tmp_var_modifier ||= begin
945
- n = @splat_node
946
- while n != nil && !(DefNode === n)
947
- n = n.parent
948
- end
949
- # n is either `nil` or DefNode
950
- if n.nil?
951
- 's:'
952
- else
953
- 'n:'
954
- end
847
+ else
848
+ call_node.scope_modifier = 's:' if call_node.scope_modifier.nil?
849
+ StringNode.new(call_node.full_name, :s)
955
850
  end
956
- end
957
-
958
- def global_scope?
959
- tmp_var_modifier == 's:'
960
- end
961
-
962
- def local_scope?
963
- not global_scope?
851
+ call_node.scope_modifier = ''
852
+ call_node.name = 'call'
853
+ call_node.arguments = []
854
+ call_node.arguments << function_name_expr
855
+ call_node.arguments << node.expression
856
+ if is_method_call
857
+ call_node.arguments << GetVariableNode.new(nil, 'self')
858
+ end
859
+ reestablish_parents(call_node)
964
860
  end
965
861
  end
966
862
 
@@ -978,6 +874,13 @@ module Riml
978
874
  call_node = node.call_node
979
875
  call_node.name = class_node.constructor_name
980
876
  call_node.scope_modifier = class_node.constructor.scope_modifier
877
+ # FIXME: `replace_with` doesn't take into account this scenario!
878
+ if CallNode === node.parent && node.parent.arguments.include?(node)
879
+ idx = node.parent.arguments.index(node)
880
+ node.parent.arguments[idx] = call_node
881
+ else
882
+ node.replace_with(call_node)
883
+ end
981
884
  end
982
885
  end
983
886
 
@@ -1015,19 +918,26 @@ module Riml
1015
918
  end
1016
919
 
1017
920
  if_expression = construct_if_expression(node)
921
+ if insert_idx.zero?
922
+ def_node.expressions.nodes.unshift(construct_copy_splat_var_assignment)
923
+ SplatVarToCopiedSplatVar.new(def_node, classes).rewrite_on_match
924
+ end
1018
925
 
1019
926
  if last_default_param == node
1020
927
  def_node.parameters.delete_if(&DefNode::DEFAULT_PARAMS)
1021
928
  def_node.parameters << SPLAT_LITERAL unless def_node.splat
1022
929
  end
1023
- def_node.expressions.nodes.insert(insert_idx, if_expression)
930
+ def_node.expressions.nodes.insert(insert_idx + 1, if_expression)
1024
931
  reestablish_parents(def_node)
1025
932
  end
1026
933
 
934
+ private
935
+
1027
936
  def construct_if_expression(node)
1028
- get_splat_node = CallNode.new(nil, 'get', [ GetVariableNode.new('a:', '000'), NumberNode.new(0), StringNode.new('rimldefault', :s) ])
1029
- condition_node = BinaryOperatorNode.new('!=#', [ get_splat_node, StringNode.new('rimldefault', :s) ])
1030
- remove_from_splat_node = CallNode.new(nil, 'remove', [ GetVariableNode.new('a:', '000'), NumberNode.new(0) ])
937
+ condition_node = UnaryOperatorNode.new('!', [
938
+ CallNode.new(nil, 'empty', [ GetVariableNode.new('', '__splat_var_cpy') ])
939
+ ])
940
+ remove_from_splat_node = CallNode.new(nil, 'remove', [ GetVariableNode.new('', '__splat_var_cpy'), NumberNode.new(0) ])
1031
941
  IfNode.new(condition_node,
1032
942
  Nodes.new([
1033
943
  AssignNode.new('=', GetVariableNode.new(nil, node.parameter), remove_from_splat_node),
@@ -1038,9 +948,27 @@ module Riml
1038
948
  )
1039
949
  end
1040
950
 
1041
- def max_recursion_lvl
1042
- 3
951
+ def construct_copy_splat_var_assignment
952
+ AssignNode.new('=', GetVariableNode.new('', '__splat_var_cpy'), CallNode.new('', 'copy', [GetVariableNode.new('a:', '000')]))
1043
953
  end
954
+
955
+ # rewrites a:000 or args (if function used *args parameter name) to:
956
+ # __splat_var_cpy
957
+ class SplatVarToCopiedSplatVar < AST_Rewriter
958
+ def initialize(def_node, classes)
959
+ super(def_node, classes)
960
+ end
961
+
962
+ def match?(node)
963
+ GetVariableNode === node &&
964
+ ( (node.name == '000' && node.scope_modifier.nil?) || ast.is_splat_arg?(node) )
965
+ end
966
+
967
+ def replace(node)
968
+ node.name = '__splat_var_cpy'
969
+ end
970
+ end
971
+
1044
972
  end
1045
973
 
1046
974
  class DeserializeVarAssignment < AST_Rewriter
@@ -46,9 +46,10 @@ module Riml
46
46
  end
47
47
 
48
48
  def visitor_for_node(node, params={})
49
- Compiler.const_get("#{node.class.name.split('::').last}Visitor").new(params)
49
+ class_name = "#{node.class.name.split('::').last}Visitor"
50
+ Compiler.const_get(class_name).new(params)
50
51
  rescue NameError
51
- error = CompileError.new('unexpected construct', node)
52
+ error = CompileError.new("unexpected construct: #{class_name}", node)
52
53
  raise error
53
54
  end
54
55
 
@@ -756,14 +757,6 @@ module Riml
756
757
  end
757
758
  end
758
759
 
759
- class ObjectInstantiationNodeVisitor < Visitor
760
- def compile(node)
761
- node.call_node.parent_node = node
762
- node.call_node.accept(visitor_for_node(node.call_node))
763
- node.compiled_output
764
- end
765
- end
766
-
767
760
  # root node has access to compiler instance in order to append to
768
761
  # the compiler's `compile_queue`. This happens when another file is
769
762
  # sourced using `riml_source`.
@@ -65,7 +65,6 @@ abs
65
65
  acos
66
66
  add
67
67
  append
68
- append
69
68
  argc
70
69
  argidx
71
70
  argv
@@ -150,8 +150,8 @@ module Riml
150
150
 
151
151
  elsif @in_function_declaration && (splat_param = @s.scan(/\A(\.{3}|\*[a-zA-Z_]\w*)/))
152
152
  @token_buf << [:SPLAT_PARAM, splat_param]
153
- # splat in calling context. ex: super(*args) or super(*(args + other_args))
154
- elsif !@in_function_declaration && prev_token && prev_token[0] == '(' && @s.check(/\A\*(\w+|\()/)
153
+ # splat in calling context. ex: super(*args) or super(*(args + other_args)) or func('hey', *args)
154
+ elsif !@in_function_declaration && prev_token && @s.check(/\A\*(\w+|\()/)
155
155
  @token_buf << [:SPLAT_ARG, @s.getch]
156
156
  # integer (octal)
157
157
  elsif octal = @s.scan(/\A0[0-7]+/)
@@ -1,9 +1,12 @@
1
1
  require File.expand_path('../constants', __FILE__)
2
2
  require File.expand_path('../errors', __FILE__)
3
+ require File.expand_path('../walkable', __FILE__)
3
4
  require 'set'
4
5
 
5
6
  module Riml
6
7
  module Visitable
8
+ include Walkable
9
+
7
10
  def accept(visitor)
8
11
  visitor.visit(self)
9
12
  end
@@ -17,7 +20,7 @@ module Riml
17
20
  @compiled_output ||= ''
18
21
  end
19
22
 
20
- EMPTY_CHILDREN = []
23
+ EMPTY_CHILDREN = [].freeze
21
24
 
22
25
  def children
23
26
  EMPTY_CHILDREN
@@ -40,101 +43,6 @@ module Riml
40
43
  end
41
44
  end
42
45
 
43
- module Walkable
44
- include Enumerable
45
-
46
- def each(&block)
47
- children.each(&block)
48
- end
49
- alias walk each
50
-
51
- def previous
52
- idx = index_by_member
53
- if idx && parent.members[idx - 1]
54
- attr = parent.members[idx - 1]
55
- return send(attr)
56
- else
57
- idx = index_by_children
58
- return unless idx
59
- parent.children.fetch(idx - 1)
60
- end
61
- end
62
-
63
- def child_previous_to(node)
64
- node.previous
65
- end
66
-
67
- def insert_before(node, new_node)
68
- idx = children.find_index(node)
69
- return unless idx
70
- children.insert(idx - 1, new_node)
71
- end
72
-
73
- def next
74
- idx = index_by_member
75
- if idx && parent.members[idx + 1]
76
- attr = parent.members[idx + 1]
77
- return parent.send(attr)
78
- else
79
- idx = index_by_children
80
- return unless idx
81
- parent.children.fetch(idx + 1)
82
- end
83
- end
84
-
85
- def child_after(node)
86
- node.next
87
- end
88
-
89
- def insert_after(node, new_node)
90
- idx = children.find_index(node)
91
- return unless idx
92
- children.insert(idx + 1, new_node)
93
- end
94
-
95
- def index_by_member
96
- attrs = parent.members
97
- attrs.each_with_index do |attr, i|
98
- if parent.send(attr) == self
99
- return i
100
- end
101
- end
102
- nil
103
- end
104
-
105
- def index_by_children
106
- parent.children.find_index(self)
107
- end
108
-
109
- def remove
110
- idx = index_by_member
111
- if idx
112
- attr = parent.members[idx]
113
- parent.send("#{attr}=", nil)
114
- else
115
- idx = index_by_children
116
- parent.children.slice!(idx) if idx
117
- end
118
- end
119
-
120
- def replace_with(new_node)
121
- idx = index_by_member
122
- if idx
123
- attr = parent.members[idx]
124
- new_node.parent = parent
125
- parent.send("#{attr}=", new_node)
126
- new_node
127
- else
128
- idx = index_by_children
129
- return unless idx
130
- new_node.parent = parent
131
- parent.children.insert(idx, new_node)
132
- parent.children.slice!(idx + 1)
133
- new_node
134
- end
135
- end
136
- end
137
-
138
46
  module Indentable
139
47
  def indent
140
48
  @indent ||= ' ' * 2
@@ -167,7 +75,6 @@ module Riml
167
75
  # Collection of nodes each one representing an expression.
168
76
  class Nodes < Struct.new(:nodes)
169
77
  include Visitable
170
- include Walkable
171
78
 
172
79
  def <<(node)
173
80
  nodes << node
@@ -212,7 +119,6 @@ module Riml
212
119
 
213
120
  class StringLiteralConcatNode < Struct.new(:string_nodes)
214
121
  include Visitable
215
- include Walkable
216
122
 
217
123
  def initialize(*string_nodes)
218
124
  super(string_nodes)
@@ -227,7 +133,6 @@ module Riml
227
133
  class RegexpNode < LiteralNode; end
228
134
 
229
135
  class ListNode < LiteralNode
230
- include Walkable
231
136
  def self.wrap(value)
232
137
  val = Array === value ? value : [value]
233
138
  new(val)
@@ -249,7 +154,6 @@ module Riml
249
154
  end
250
155
 
251
156
  class DictionaryNode < LiteralNode
252
- include Walkable
253
157
 
254
158
  def initialize(value)
255
159
  super(value.to_a)
@@ -287,7 +191,6 @@ module Riml
287
191
  # Ex: `super(*args)`, `super(*a:000)`, `someFunc(*(list + ['item']))`
288
192
  class SplatNode < Struct.new(:expression)
289
193
  include Visitable
290
- include Walkable
291
194
 
292
195
  def children
293
196
  [expression]
@@ -316,7 +219,6 @@ module Riml
316
219
 
317
220
  class ReturnNode < Struct.new(:expression)
318
221
  include Visitable
319
- include Walkable
320
222
 
321
223
  def children
322
224
  [expression]
@@ -325,7 +227,6 @@ module Riml
325
227
 
326
228
  class WrapInParensNode < Struct.new(:expression)
327
229
  include Visitable
328
- include Walkable
329
230
 
330
231
  def force_newline_if_child_call_node?
331
232
  false
@@ -360,7 +261,8 @@ module Riml
360
261
  include Riml::Constants
361
262
  include Visitable
362
263
  include FullyNameable
363
- include Walkable
264
+
265
+ attr_accessor :super_call
364
266
 
365
267
  ALL_BUILTIN_FUNCTIONS = BUILTIN_FUNCTIONS + BUILTIN_COMMANDS
366
268
  ALL_BUILTIN_COMMANDS = BUILTIN_COMMANDS + RIML_COMMANDS + VIML_COMMANDS
@@ -391,6 +293,14 @@ module Riml
391
293
  false
392
294
  end
393
295
 
296
+ def method_call?
297
+ name.instance_of?(DictGetDotNode) &&
298
+ name.dict.name == 'self' &&
299
+ name.dict.scope_modifier.nil?
300
+ end
301
+
302
+ alias super_call? super_call
303
+
394
304
  def autoload?
395
305
  name.include?('#')
396
306
  end
@@ -519,7 +429,6 @@ module Riml
519
429
 
520
430
  class OperatorNode < Struct.new(:operator, :operands)
521
431
  include Visitable
522
- include Walkable
523
432
 
524
433
  def force_newline_if_child_call_node?
525
434
  false
@@ -575,7 +484,6 @@ module Riml
575
484
  # let s:var = 4
576
485
  class AssignNode < Struct.new(:operator, :lhs, :rhs)
577
486
  include Visitable
578
- include Walkable
579
487
 
580
488
  def children
581
489
  [lhs, rhs]
@@ -584,7 +492,6 @@ module Riml
584
492
 
585
493
  class MultiAssignNode < Struct.new(:assigns)
586
494
  include Visitable
587
- include Walkable
588
495
 
589
496
  def children
590
497
  assigns
@@ -618,6 +525,10 @@ module Riml
618
525
  include Visitable
619
526
  include FullyNameable
620
527
  include QuestionVariableExistence
528
+
529
+ def arguments_variable?
530
+ scope_modifier == 'a:' && name == '000'
531
+ end
621
532
  end
622
533
 
623
534
  # &autoindent
@@ -629,7 +540,6 @@ module Riml
629
540
 
630
541
  class GetCurlyBraceNameNode < Struct.new(:scope_modifier, :variable)
631
542
  include Visitable
632
- include Walkable
633
543
 
634
544
  def children
635
545
  [variable]
@@ -638,7 +548,6 @@ module Riml
638
548
 
639
549
  class CurlyBraceVariable < Struct.new(:parts)
640
550
  include Visitable
641
- include Walkable
642
551
 
643
552
  def <<(part)
644
553
  parts << part
@@ -652,7 +561,6 @@ module Riml
652
561
 
653
562
  class CurlyBracePart < Struct.new(:value)
654
563
  include Visitable
655
- include Walkable
656
564
 
657
565
  def interpolated?
658
566
  GetVariableNode === value || GetSpecialVariableNode === value ||
@@ -680,7 +588,6 @@ module Riml
680
588
 
681
589
  class UnletVariableNode < Struct.new(:bang, :variables)
682
590
  include Visitable
683
- include Walkable
684
591
 
685
592
  def <<(variable)
686
593
  variables << variable
@@ -697,7 +604,6 @@ module Riml
697
604
  include Visitable
698
605
  include Indentable
699
606
  include FullyNameable
700
- include Walkable
701
607
 
702
608
  attr_accessor :private_function
703
609
  alias private_function? private_function
@@ -783,6 +689,12 @@ module Riml
783
689
  parameters.select(&DEFAULT_PARAMS)
784
690
  end
785
691
 
692
+ def is_splat_arg?(node)
693
+ splat = splat()
694
+ return false unless splat
695
+ GetVariableNode === node && node.scope_modifier.nil? && node.name == splat[1..-1]
696
+ end
697
+
786
698
  def children
787
699
  children = if sid?
788
700
  [sid, expressions]
@@ -795,7 +707,6 @@ module Riml
795
707
 
796
708
  class DefaultParamNode < Struct.new(:parameter, :expression)
797
709
  include Visitable
798
- include Walkable
799
710
 
800
711
  def children
801
712
  [parameter, expression]
@@ -856,7 +767,6 @@ module Riml
856
767
  class ControlStructure < Struct.new(:condition, :body)
857
768
  include Visitable
858
769
  include Indentable
859
- include Walkable
860
770
 
861
771
  def force_newline_if_child_call_node?
862
772
  false
@@ -894,7 +804,6 @@ module Riml
894
804
 
895
805
  class ElseNode < Struct.new(:expressions)
896
806
  include Visitable
897
- include Walkable
898
807
  alias body expressions
899
808
 
900
809
  def <<(expr)
@@ -917,7 +826,6 @@ module Riml
917
826
 
918
827
  class ElseifNode < ControlStructure
919
828
  include Visitable
920
- include Walkable
921
829
  alias expressions body
922
830
 
923
831
  def <<(expr)
@@ -950,7 +858,6 @@ module Riml
950
858
  class ForNode < Struct.new(:variable, :in_expression, :expressions)
951
859
  include Visitable
952
860
  include Indentable
953
- include Walkable
954
861
 
955
862
  alias for_variable variable
956
863
 
@@ -981,7 +888,6 @@ module Riml
981
888
 
982
889
  class DictGetNode < Struct.new(:dict, :keys)
983
890
  include Visitable
984
- include Walkable
985
891
 
986
892
  def children
987
893
  [dict] + keys
@@ -1006,7 +912,6 @@ module Riml
1006
912
  # function()[identifier]
1007
913
  class ListOrDictGetNode < Struct.new(:list_or_dict, :keys)
1008
914
  include Visitable
1009
- include Walkable
1010
915
 
1011
916
  alias list list_or_dict
1012
917
  alias dict list_or_dict
@@ -1022,7 +927,6 @@ module Riml
1022
927
 
1023
928
  class GetVariableByScopeAndDictNameNode < Struct.new(:scope_modifier, :keys)
1024
929
  include Visitable
1025
- include Walkable
1026
930
 
1027
931
  def children
1028
932
  [scope_modifier] + keys
@@ -1032,7 +936,6 @@ module Riml
1032
936
  class TryNode < Struct.new(:try_block, :catch_nodes, :finally_block)
1033
937
  include Visitable
1034
938
  include Indentable
1035
- include Walkable
1036
939
 
1037
940
  def children
1038
941
  [try_block] + catch_nodes.to_a + [finally_block].compact
@@ -1041,7 +944,6 @@ module Riml
1041
944
 
1042
945
  class CatchNode < Struct.new(:regexp, :expressions)
1043
946
  include Visitable
1044
- include Walkable
1045
947
  include NotNestedUnder
1046
948
 
1047
949
  def children
@@ -1052,7 +954,6 @@ module Riml
1052
954
 
1053
955
  class ClassDefinitionNode < Struct.new(:scope_modifier, :name, :superclass_name, :expressions)
1054
956
  include Visitable
1055
- include Walkable
1056
957
 
1057
958
  FUNCTIONS = lambda {|expr| DefNode === expr}
1058
959
  DEFAULT_SCOPE_MODIFIER = 's:'
@@ -1126,7 +1027,6 @@ module Riml
1126
1027
 
1127
1028
  class SuperNode < Struct.new(:arguments, :with_parens)
1128
1029
  include Visitable
1129
- include Walkable
1130
1030
 
1131
1031
  def use_all_arguments?
1132
1032
  arguments.empty? && !with_parens
@@ -1139,7 +1039,6 @@ module Riml
1139
1039
 
1140
1040
  class ObjectInstantiationNode < Struct.new(:call_node)
1141
1041
  include Visitable
1142
- include Walkable
1143
1042
 
1144
1043
  def force_newline_if_child_call_node?
1145
1044
  false
@@ -0,0 +1,97 @@
1
+ module Riml
2
+ module Walkable
3
+ include Enumerable
4
+
5
+ def each(&block)
6
+ children.each(&block)
7
+ end
8
+ alias walk each
9
+
10
+ def previous
11
+ idx = index_by_member
12
+ if idx && parent.members[idx - 1]
13
+ attr = parent.members[idx - 1]
14
+ return send(attr)
15
+ else
16
+ idx = index_by_children
17
+ return unless idx
18
+ parent.children.fetch(idx - 1)
19
+ end
20
+ end
21
+
22
+ def child_previous_to(node)
23
+ node.previous
24
+ end
25
+
26
+ def insert_before(node, new_node)
27
+ idx = children.find_index(node)
28
+ return unless idx
29
+ children.insert(idx - 1, new_node)
30
+ end
31
+
32
+ def next
33
+ idx = index_by_member
34
+ if idx && parent.members[idx + 1]
35
+ attr = parent.members[idx + 1]
36
+ return parent.send(attr)
37
+ else
38
+ idx = index_by_children
39
+ return unless idx
40
+ parent.children.fetch(idx + 1)
41
+ end
42
+ end
43
+
44
+ def child_after(node)
45
+ node.next
46
+ end
47
+
48
+ def insert_after(node, new_node)
49
+ idx = children.find_index(node)
50
+ return unless idx
51
+ children.insert(idx + 1, new_node)
52
+ end
53
+
54
+ def index_by_member
55
+ attrs = parent.members
56
+ attrs.each_with_index do |attr, i|
57
+ if parent.send(attr) == self
58
+ return i
59
+ end
60
+ end
61
+ nil
62
+ end
63
+
64
+ def index_by_children
65
+ parent.children.find_index(self)
66
+ end
67
+
68
+ def remove
69
+ idx = index_by_member
70
+ if idx
71
+ attr = parent.members[idx]
72
+ parent.send("#{attr}=", nil)
73
+ else
74
+ idx = index_by_children
75
+ parent.children.slice!(idx) if idx
76
+ end
77
+ end
78
+
79
+ def replace_with(new_node)
80
+ idx = index_by_member
81
+ if idx
82
+ attr = parent.members[idx]
83
+ new_node.parent = parent
84
+ parent.send("#{attr}=", new_node)
85
+ new_node
86
+ else
87
+ idx = index_by_children
88
+ return unless idx
89
+ new_node.parent = parent
90
+ parent.children.insert(idx, new_node)
91
+ parent.children.slice!(idx + 1)
92
+ new_node
93
+ end
94
+ end
95
+
96
+ end
97
+ end
data/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Riml
2
- # release date: Jan. 12, 2014
3
- VERSION = [0,3,9]
2
+ # release date: Feb 2, 2014
3
+ VERSION = [0,4,0]
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.9
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luke Gruber
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-12 00:00:00.000000000 Z
11
+ date: 2014-02-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: racc
@@ -118,6 +118,7 @@ files:
118
118
  - lib/riml/path_cache.rb
119
119
  - lib/riml/repl.rb
120
120
  - lib/riml/rewritten_ast_cache.rb
121
+ - lib/riml/walkable.rb
121
122
  - lib/riml/walker.rb
122
123
  - lib/riml/warning_buffer.rb
123
124
  - version.rb