Class: ASTUtils::Scope
- Inherits:
-
Object
- Object
- ASTUtils::Scope
- Includes:
- NodeHelper
- Defined in:
- lib/ast_utils/scope.rb
Defined Under Namespace
Classes: Assignment
Instance Attribute Summary collapse
-
#all_scopes ⇒ Object
readonly
Returns the value of attribute all_scopes.
-
#assignment_nodes ⇒ Object
readonly
Returns the value of attribute assignment_nodes.
-
#child_scopes ⇒ Object
readonly
Returns the value of attribute child_scopes.
-
#parent_scopes ⇒ Object
readonly
Returns the value of attribute parent_scopes.
-
#reference_nodes ⇒ Object
readonly
Returns the value of attribute reference_nodes.
-
#root ⇒ Object
readonly
Returns the value of attribute root.
-
#sub_scopes ⇒ Object
readonly
Returns the value of attribute sub_scopes.
-
#super_scopes ⇒ Object
readonly
Returns the value of attribute super_scopes.
Class Method Summary collapse
Instance Method Summary collapse
- #add_scope(scope) ⇒ Object
- #assignments(scope, include_subs: false) ⇒ Object
- #child_scope!(scope, parent_scope) ⇒ Object
- #children(scope) ⇒ Object
- #construct ⇒ Object
- #construct_children(node, current_scope) ⇒ Object
- #construct_node(node, current_scope) ⇒ Object
- #each(&block) ⇒ Object
-
#initialize(root:) ⇒ Scope
constructor
A new instance of Scope.
- #nested_scope!(scope, super_scope) ⇒ Object
- #parent(scope) ⇒ Object
- #references(scope, include_subs: false) ⇒ Object
- #subs(scope) ⇒ Object
- #sup(scope) ⇒ Object
- #valid_scope!(node) ⇒ Object
Methods included from NodeHelper
#each_child_node, #map_child_node
Constructor Details
#initialize(root:) ⇒ Scope
Returns a new instance of Scope.
35 36 37 38 39 40 41 42 43 44 |
# File 'lib/ast_utils/scope.rb', line 35 def initialize(root:) @root = root @all_scopes = NodeSet.new @child_scopes = {} @parent_scopes = {} @sub_scopes = {} @super_scopes = {} @assignment_nodes = {} @reference_nodes = {} end |
Instance Attribute Details
#all_scopes ⇒ Object (readonly)
Returns the value of attribute all_scopes.
27 28 29 |
# File 'lib/ast_utils/scope.rb', line 27 def all_scopes @all_scopes end |
#assignment_nodes ⇒ Object (readonly)
Returns the value of attribute assignment_nodes.
32 33 34 |
# File 'lib/ast_utils/scope.rb', line 32 def assignment_nodes @assignment_nodes end |
#child_scopes ⇒ Object (readonly)
Returns the value of attribute child_scopes.
28 29 30 |
# File 'lib/ast_utils/scope.rb', line 28 def child_scopes @child_scopes end |
#parent_scopes ⇒ Object (readonly)
Returns the value of attribute parent_scopes.
29 30 31 |
# File 'lib/ast_utils/scope.rb', line 29 def parent_scopes @parent_scopes end |
#reference_nodes ⇒ Object (readonly)
Returns the value of attribute reference_nodes.
33 34 35 |
# File 'lib/ast_utils/scope.rb', line 33 def reference_nodes @reference_nodes end |
#root ⇒ Object (readonly)
Returns the value of attribute root.
26 27 28 |
# File 'lib/ast_utils/scope.rb', line 26 def root @root end |
#sub_scopes ⇒ Object (readonly)
Returns the value of attribute sub_scopes.
30 31 32 |
# File 'lib/ast_utils/scope.rb', line 30 def sub_scopes @sub_scopes end |
#super_scopes ⇒ Object (readonly)
Returns the value of attribute super_scopes.
31 32 33 |
# File 'lib/ast_utils/scope.rb', line 31 def super_scopes @super_scopes end |
Class Method Details
.from(node:) ⇒ Object
174 175 176 |
# File 'lib/ast_utils/scope.rb', line 174 def self.from(node:) new(root: node).tap(&:construct) end |
.scope_node?(node) ⇒ Boolean
178 179 180 181 182 183 184 185 |
# File 'lib/ast_utils/scope.rb', line 178 def self.scope_node?(node) case node.type when :class, :module, :def, :block true else false end end |
Instance Method Details
#add_scope(scope) ⇒ Object
96 97 98 99 100 101 102 |
# File 'lib/ast_utils/scope.rb', line 96 def add_scope(scope) all_scopes << scope child_scopes[scope.__id__] = NodeSet.new sub_scopes[scope.__id__] = NodeSet.new assignment_nodes[scope.__id__] = Set.new reference_nodes[scope.__id__] = Set.new end |
#assignments(scope, include_subs: false) ⇒ Object
62 63 64 65 66 67 68 69 70 |
# File 'lib/ast_utils/scope.rb', line 62 def assignments(scope, include_subs: false) if include_subs subs(scope).inject(assignment_nodes[scope.__id__]) {|assignments, scope_| assignments + assignments(scope_, include_subst: true) } else assignment_nodes[scope.__id__] end end |
#child_scope!(scope, parent_scope) ⇒ Object
104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/ast_utils/scope.rb', line 104 def child_scope!(scope, parent_scope) add_scope(scope) if parent_scope parent_scopes[scope.__id__] = parent_scope child_scopes[parent_scope.__id__] << scope end each_child_node(scope) do |child| construct_node(child, scope) end end |
#children(scope) ⇒ Object
46 47 48 |
# File 'lib/ast_utils/scope.rb', line 46 def children(scope) child_scopes[scope.__id__] end |
#construct ⇒ Object
87 88 89 90 91 92 93 94 |
# File 'lib/ast_utils/scope.rb', line 87 def construct if Scope.scope_node?(root) child_scope!(root, nil) else add_scope(root) construct_node(root, root) end end |
#construct_children(node, current_scope) ⇒ Object
162 163 164 165 166 |
# File 'lib/ast_utils/scope.rb', line 162 def construct_children(node, current_scope) each_child_node(node) do |child| construct_node(child, current_scope) end end |
#construct_node(node, current_scope) ⇒ Object
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/ast_utils/scope.rb', line 132 def construct_node(node, current_scope) case node.type when :class, :module, :def child_scope!(node, current_scope) when :block nested_scope!(node, current_scope) when :lvar reference_nodes[current_scope.__id__] << node when :lvasgn, :arg, :optarg, :restarg, :kwarg, :kwoptarg, :kwrestarg, :blockarg assignment_nodes[current_scope.__id__] << Assignment.new(node: node, variable: node.children[0]) construct_children(node, current_scope) when :procarg0 case node.children[0] when AST::Node construct_children(node, current_scope) else assignment_nodes[current_scope.__id__] << Assignment.new(node: node, variable: node.children[0]) construct_children(node, current_scope) end when :match_with_lvasgn node.children[2].each do |var| assignment_nodes[current_scope.__id__] << Assignment.new(node: node, variable: var) end construct_children(node, current_scope) else construct_children(node, current_scope) end end |
#each(&block) ⇒ Object
83 84 85 |
# File 'lib/ast_utils/scope.rb', line 83 def each(&block) all_scopes.each(&block) end |
#nested_scope!(scope, super_scope) ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/ast_utils/scope.rb', line 117 def nested_scope!(scope, super_scope) add_scope(scope) if super_scope parent_scopes[scope.__id__] = super_scope child_scopes[super_scope.__id__] << scope super_scopes[scope.__id__] = super_scope sub_scopes[super_scope.__id__] << scope end each_child_node(scope) do |child| construct_node(child, scope) end end |
#parent(scope) ⇒ Object
50 51 52 |
# File 'lib/ast_utils/scope.rb', line 50 def parent(scope) parent_scopes[scope.__id__] end |
#references(scope, include_subs: false) ⇒ Object
72 73 74 75 76 77 78 79 80 81 |
# File 'lib/ast_utils/scope.rb', line 72 def references(scope, include_subs: false) if include_subs subs(scope).inject(reference_nodes[scope.__id__]) {|references, scope_| references + references(scope_, include_subs: true) } else reference_nodes[scope.__id__] end end |
#subs(scope) ⇒ Object
54 55 56 |
# File 'lib/ast_utils/scope.rb', line 54 def subs(scope) sub_scopes[scope.__id__] end |
#sup(scope) ⇒ Object
58 59 60 |
# File 'lib/ast_utils/scope.rb', line 58 def sup(scope) super_scopes[scope.__id__] end |
#valid_scope!(node) ⇒ Object
168 169 170 171 172 |
# File 'lib/ast_utils/scope.rb', line 168 def valid_scope!(node) unless root.equal?(node) || Scope.scope_node?(node) raise "Invalid scope node given: #{node}" end end |