cql_ruby 0.0.14 → 0.0.15

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a2d4b179a2563722c3dc2ef101ec10f817b1f79b3ce7d81a9ca6550fd088f39d
4
- data.tar.gz: 3cace84921a72b38150aa52d60d1a48a48775b20234a3f4094e58939cf1c6058
3
+ metadata.gz: f10c73e5413cfa12307f6343a47469c7b4836e682d31847f5786539a2edff359
4
+ data.tar.gz: 4c54670fbfea11478aefd78b266448f9776988ce2089df53ceae001ae35b57eb
5
5
  SHA512:
6
- metadata.gz: e4c5f5f1e37f8520a7e366d6dc1bb07792ba8062230cd41a068cb846516e76497639131d0f93a0b60c360586bc886743d0a02aac4d3c3660281e1c8a18021f26
7
- data.tar.gz: 65b4991554e454c0ca76f1077ae19665b3b4b27fc48243d301fb873e36af0da6652dcb6d741a249f529f72263866c4a5d2104b9fd5c958c0ed6c307218f829eb
6
+ metadata.gz: f7b22f9f736297227407e8abfaddc33329d3564174dce7072330149d84d15a160df6ce18b34bf3237977af5cf467370d983536bd7c453d3d8d398950644562f0
7
+ data.tar.gz: a3e8fcf9c81fff91cf9f807ba5ce8185b97e354842e1f95e694528badd93cdde19dbbccd22d2ede34d8309df268b1fbebd162cf14df03e35f4b950d72e24a05e
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'parser'
4
4
  require 'cql_ruby'
5
+ require 'pry-byebug'
5
6
 
6
7
  def show_help
7
8
  puts <<~HELP
@@ -18,6 +19,7 @@ def show_help
18
19
  \t\tNesting under: nest:T(=NAME) Example: nest:def=save_user nest:class=UserManager
19
20
  \t\tHas child: has:T(=NAME) Example: has:const has:def=valid?
20
21
  \t\tPattern: pattern:(T-)*X(-T)* Example: pattern:class-def-X-block
22
+ \t\tAssignment left side: assigned Example: assigned
21
23
 
22
24
  \tOPTIONS
23
25
  \t\t--include=PATTERN Parses only files whose name matches the pattern.
@@ -12,5 +12,6 @@ require 'cql_ruby/crumb_collector'
12
12
  require 'cql_ruby/abstract_printer'
13
13
  require 'cql_ruby/console_printer'
14
14
  require 'cql_ruby/filter_reader'
15
+ require 'cql_ruby/filters/assignments'
15
16
  require 'cql_ruby/filter_evaluator'
16
17
  require 'cql_ruby/pattern_matcher'
@@ -78,7 +78,11 @@ module CqlRuby
78
78
  from = crumb.line_col_no
79
79
  to = from + crumb.expression_size
80
80
 
81
- prefix = source[0..from - 1] || ''
81
+ prefix = if from > 0
82
+ source[0..from - 1] || ''
83
+ else
84
+ ''
85
+ end
82
86
  subject = source[from..to - 1] || ''
83
87
  suffix = source[to..] || ''
84
88
 
@@ -9,6 +9,7 @@ module CqlRuby
9
9
  pass_nesting?(filter_reader, ancestors),
10
10
  pass_has?(filter_reader, ancestors, node),
11
11
  pass_pattern?(filter_reader, ancestors, node),
12
+ pass_assignment?(filter_reader, ancestors, node),
12
13
  ].all?
13
14
  end
14
15
 
@@ -56,6 +57,8 @@ module CqlRuby
56
57
  # @param [Array<Parser::AST::Node>] ancestors
57
58
  # @param [Any<Parser::AST::Node, Symbol>] node
58
59
  #
60
+ # @return [Boolean]
61
+ #
59
62
  def pass_has?(filter_reader, ancestors, node)
60
63
  return true unless filter_reader.restrict_children?
61
64
 
@@ -76,6 +79,8 @@ module CqlRuby
76
79
  # @param [Array<Parser::AST::Node>] ancestors
77
80
  # @param [Any<Parser::AST::Node, Symbol>] node
78
81
  #
82
+ # @return [Boolean]
83
+ #
79
84
  def pass_pattern?(filter_reader, ancestors, node)
80
85
  return true unless filter_reader.restrict_pattern?
81
86
 
@@ -97,10 +102,23 @@ module CqlRuby
97
102
  end
98
103
  end
99
104
 
105
+ #
106
+ # @param [CqlRuby::FilterReader] filter_reader
107
+ # @param [Array<Parser::AST::Node>] ancestors
108
+ # @param [Parser::AST::Node] node
109
+ #
110
+ # @return [Boolean]
111
+ #
112
+ def pass_assignment?(filter_reader, ancestors, node)
113
+ CqlRuby::Filters::Assignments.pass?(filter_reader, ancestors, node)
114
+ end
115
+
100
116
  #
101
117
  # @param [Array<String>] pattern_descendants
102
118
  # @param [Parser::AST::Node] node
103
119
  #
120
+ # @return [Boolean]
121
+ #
104
122
  def match_descendant_pattern?(pattern_descendants, node)
105
123
  return true if pattern_descendants.empty?
106
124
  # If we're at the end and we're still expecting a type - no match.
@@ -67,6 +67,8 @@ module CqlRuby
67
67
  attr_reader :has_leaves
68
68
  # @attribute [Array<CqlRuby::FilterReader::HierarchyPattern>] patterns
69
69
  attr_reader :patterns
70
+ # @attribute [Boolean] is_assigned
71
+ attr_reader :is_assigned
70
72
 
71
73
  def initialize(raw_filters = [])
72
74
  super()
@@ -75,6 +77,7 @@ module CqlRuby
75
77
  @nest_under = []
76
78
  @has_leaves = []
77
79
  @patterns = []
80
+ @is_assigned = false
78
81
 
79
82
  parse_raw_filters(raw_filters)
80
83
  end
@@ -95,13 +98,17 @@ module CqlRuby
95
98
  !@patterns.empty?
96
99
  end
97
100
 
101
+ def restrict_assignment?
102
+ @is_assigned
103
+ end
104
+
98
105
  private
99
106
 
100
107
  # @param [Array<String>] raw_filters
101
108
  def parse_raw_filters(raw_filters)
102
109
  raw_filters.each do |raw_filter|
103
110
  name, value = raw_filter.split(':')
104
- raise "Unrecognized filter: #{raw_filter}" if name.nil? || value.nil?
111
+ raise "Unrecognized filter: #{raw_filter}" if name.nil?
105
112
 
106
113
  if %w[type t].include?(name)
107
114
  @allowed_types += value.split(',').map(&:to_sym)
@@ -115,6 +122,8 @@ module CqlRuby
115
122
  @has_leaves << NodeSpec.from(value)
116
123
  elsif %w[pattern p].include?(name)
117
124
  @patterns << HierarchyPattern.from(value)
125
+ elsif name == 'assigned'
126
+ @is_assigned = true
118
127
  end
119
128
  end
120
129
 
@@ -0,0 +1,151 @@
1
+ module CqlRuby
2
+ module Filters
3
+ class Assignments
4
+ class << self
5
+ #
6
+ # @param [CqlRuby::FilterReader] filter_reader
7
+ # @param [Array<Parser::AST::Node>] ancestors
8
+ # @param [Parser::AST::Node] node
9
+ #
10
+ # @return [Boolean]
11
+ #
12
+ def pass?(filter_reader, ancestors, node)
13
+ return true unless filter_reader.restrict_assignment?
14
+ return true if lvar_assign?(ancestors, node)
15
+ return true if instance_attr_assign?(ancestors, node)
16
+ return true if array_sym_key_assign?(ancestors, node)
17
+ return true if array_string_key_assign?(ancestors, node)
18
+ return true if hash_sym_key_assign?(ancestors, node)
19
+ return true if hash_string_key_assign?(ancestors, node)
20
+ false
21
+ end
22
+
23
+ private
24
+
25
+ #
26
+ # @param [Array<Parser::AST::Node>] ancestors
27
+ # @param [Parser::AST::Node] node
28
+ #
29
+ # @return [Boolean]
30
+ #
31
+ def lvar_assign?(ancestors, node)
32
+ pattern_pass?({
33
+ nth_child: 0,
34
+ parent: {
35
+ type: :lvasgn
36
+ }
37
+ }, ancestors, node)
38
+ end
39
+
40
+ # TODO This does not work as symbol token is suffixed with =, eg foo= for bar.foo = x.
41
+ # Workaround for now is to use a =-alloed pattern, such as 'r/^token(|=)$/'
42
+ def instance_attr_assign?(ancestors, node)
43
+ pattern_pass?({
44
+ nth_child: 1,
45
+ parent: {
46
+ type: :send
47
+ }
48
+ }, ancestors, node)
49
+ end
50
+
51
+ def array_sym_key_assign?(ancestors, node)
52
+ pattern_pass?({
53
+ nth_child: 0,
54
+ parent: {
55
+ type: :sym,
56
+ nth_child: 2,
57
+ parent: {
58
+ type: :send,
59
+ child: {
60
+ nth: 1,
61
+ token: :[]=
62
+ }
63
+ }
64
+ }
65
+ }, ancestors, node)
66
+ end
67
+
68
+ def array_string_key_assign?(ancestors, node)
69
+ pattern_pass?({
70
+ nth_child: 0,
71
+ parent: {
72
+ type: :str,
73
+ nth_child: 2,
74
+ parent: {
75
+ type: :send,
76
+ child: {
77
+ nth: 1,
78
+ token: :[]=
79
+ }
80
+ }
81
+ }
82
+ }, ancestors, node)
83
+ end
84
+
85
+ def hash_sym_key_assign?(ancestors, node)
86
+ pattern_pass?({
87
+ nth_child: 0,
88
+ parent: {
89
+ type: :sym,
90
+ nth_child: 0,
91
+ parent: {
92
+ type: :pair,
93
+ parent: {
94
+ type: :hash
95
+ }
96
+ }
97
+ }
98
+ }, ancestors, node)
99
+ end
100
+
101
+ def hash_string_key_assign?(ancestors, node)
102
+ pattern_pass?({
103
+ nth_child: 0,
104
+ parent: {
105
+ type: :str,
106
+ nth_child: 0,
107
+ parent: {
108
+ type: :pair,
109
+ parent: {
110
+ type: :hash
111
+ }
112
+ }
113
+ }
114
+ }, ancestors, node)
115
+ end
116
+
117
+ def pattern_pass?(pattern, ancestors, node)
118
+ ancestor_idx = ancestors.size
119
+ current_node = node
120
+ current_pattern = pattern
121
+
122
+ loop do
123
+ if current_pattern.key?(:nth_child)
124
+ return false unless ancestor_idx - 1 >= 0
125
+ return false unless ancestors[ancestor_idx - 1].is_a?(Parser::AST::Node)
126
+ return false unless ancestors[ancestor_idx - 1].children[current_pattern[:nth_child]] == current_node
127
+ end
128
+
129
+ if current_pattern.key?(:type)
130
+ return false unless current_node.type == current_pattern[:type]
131
+ end
132
+
133
+ if current_pattern.key?(:child)
134
+ return false if current_node.children.size <= current_pattern[:child][:nth]
135
+ return false unless current_node.children[current_pattern[:child][:nth]] == current_pattern[:child][:token]
136
+ end
137
+
138
+ break unless current_pattern.key?(:parent)
139
+
140
+ ancestor_idx -= 1
141
+ return false unless ancestor_idx >= 0
142
+ current_node = ancestors[ancestor_idx]
143
+ current_pattern = current_pattern[:parent]
144
+ end
145
+
146
+ true
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cql_ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.14
4
+ version: 0.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - itarato
@@ -60,6 +60,7 @@ files:
60
60
  - lib/cql_ruby/executor.rb
61
61
  - lib/cql_ruby/filter_evaluator.rb
62
62
  - lib/cql_ruby/filter_reader.rb
63
+ - lib/cql_ruby/filters/assignments.rb
63
64
  - lib/cql_ruby/pattern_matcher.rb
64
65
  homepage: https://github.com/itarato/cql
65
66
  licenses: