riml 0.3.9 → 0.4.0
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.
- checksums.yaml +8 -8
- data/lib/riml/ast_rewriter.rb +99 -171
- data/lib/riml/compiler.rb +3 -10
- data/lib/riml/constants.rb +0 -1
- data/lib/riml/lexer.rb +2 -2
- data/lib/riml/nodes.rb +24 -125
- data/lib/riml/walkable.rb +97 -0
- data/version.rb +2 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YzcxODgxN2I3YzM3MjdlZjdhMDM1Y2E4NzhmZmM1ZjM3YWQ1ZjQ0YQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NjcxN2EzNDgyZTVjODZkZjE3MGIyZTk2MmQwMzI1NDRhNmViZjI0NA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YTU5N2JjMjdkODhhZjBkOTlkNmMwYjdkMTg5ZmUxZTIwNzAyNTZhYmMwMGZl
|
10
|
+
ZWE3MmI1ODI3Nzk3OTliOTcwZWZiOTcwMzkwY2I2OTUyZDQwZWNjYmI1ZmQy
|
11
|
+
NDVjYTIzNjdlNWQzNzk5YjBiOGMwZWY4NDBkNmZlZGE1MmU1ZDQ=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NjhmMTc0MjIzMDMzNmU2ZDIyMWIyZTZlYWZkNWZmNDNkMzVhMzYzYWE4NWQ0
|
14
|
+
YjU5NDI2ZTQ5MmJhYmJjODE1ZDg0ZjFiMTg1MDllNWE3NDJjNjQwZjBlZDhj
|
15
|
+
YzQ4ODgyNTA5Y2JjNWFhZmVhNmIyZWZjMzVlODIxMGFhY2ZmOTI=
|
data/lib/riml/ast_rewriter.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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 &&
|
499
|
-
node.name.dict.
|
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
|
-
|
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
|
-
|
730
|
-
|
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
|
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
|
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
|
831
|
+
class SplatsToCallFunctionInCallingContext < AST_Rewriter
|
820
832
|
|
821
833
|
def match?(node)
|
822
|
-
|
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
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
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
|
-
|
845
|
+
StringNode.new("_s:#{call_node.name.keys.last}", :s)
|
935
846
|
])
|
936
|
-
|
937
|
-
|
938
|
-
|
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
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
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
|
-
|
1029
|
-
|
1030
|
-
|
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
|
1042
|
-
|
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
|
data/lib/riml/compiler.rb
CHANGED
@@ -46,9 +46,10 @@ module Riml
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def visitor_for_node(node, params={})
|
49
|
-
|
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(
|
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`.
|
data/lib/riml/constants.rb
CHANGED
data/lib/riml/lexer.rb
CHANGED
@@ -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 &&
|
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]+/)
|
data/lib/riml/nodes.rb
CHANGED
@@ -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
|
-
|
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
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.
|
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-
|
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
|