Class: HumanQL::TreeNormalizer

Inherits:
Object
  • Object
show all
Defined in:
lib/human-ql/tree_normalizer.rb

Overview

Normalizes and imposes various limitations on query abstract syntax trees (ASTs).

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ TreeNormalizer

Construct given options that are applied via same name setters on self.



69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/human-ql/tree_normalizer.rb', line 69

def initialize( opts = {} )
  @nested_scope = false
  @nested_not = false
  @unconstrained_not = true
  @scope_can_constrain = true
  @scope_at_top_only = false
  @scope_and_only = false
  @not_scope = :invert

  opts.each do |name,val|
    send( name.to_s + '=', val )
  end
end

Instance Attribute Details

#nested_notObject

Allow nested :not (in other words, double negatives)? Default: false -> nested :not nodes are removed.



29
30
31
# File 'lib/human-ql/tree_normalizer.rb', line 29

def nested_not
  @nested_not
end

#nested_scopeObject

Allow nested scopes? Default: false -> nested scope nodes are removed.



25
26
27
# File 'lib/human-ql/tree_normalizer.rb', line 25

def nested_scope
  @nested_scope
end

#not_scopeObject

Allow SCOPE within :not?

  • If set to :invert normalizes ‘[:not, [’SCOPE’, ‘a’]]‘ to `[’SCOPE’, [:not, ‘a’]]‘.

  • If set to false, the nested scope node is removed.

  • For either :invert or false, the scope node is otherwise removed if found below a :not node.

Default: :invert



57
58
59
# File 'lib/human-ql/tree_normalizer.rb', line 57

def not_scope
  @not_scope
end

#scope_and_onlyObject

Allow only scopes combined with :and condition? Default: false



61
62
63
# File 'lib/human-ql/tree_normalizer.rb', line 61

def scope_and_only
  @scope_and_only
end

#scope_at_top_onlyObject

Allow scope at root or first level only? Default: false



65
66
67
# File 'lib/human-ql/tree_normalizer.rb', line 65

def scope_at_top_only
  @scope_at_top_only
end

#scope_can_constrainObject

Does a scope count as a constraint? Default: true -> a scope is a constraint if its argument is a constraint. If it depends on the scope, you can override #scope_can_constrain? with this logic.



48
49
50
# File 'lib/human-ql/tree_normalizer.rb', line 48

def scope_can_constrain
  @scope_can_constrain
end

#unconstrained_notObject

Allow unconstrained :not? Queries containing an unsconstrained :not may be costly to execute. If false the unconstrained :not will be removed.

A :not node is considered “constrained” if it has an :and ancestor with at least one contraint argument. A constraint argument is a term, phrase, or :and node matching this same criteria, or an :or node where all arguments match this criteria. See also #scope_can_constrain. Default: true



41
42
43
# File 'lib/human-ql/tree_normalizer.rb', line 41

def unconstrained_not
  @unconstrained_not
end

Instance Method Details

#normalize(node) ⇒ Object

Return a new normalized AST from the given AST root node.



84
85
86
87
88
89
90
# File 'lib/human-ql/tree_normalizer.rb', line 84

def normalize( node )
  node = normalize_1( node, EMPTY_STACK, @unconstrained_not )
  if ( @not_scope != true ) || @scope_and_only || @scope_at_top_only
    node = normalize_2( node, EMPTY_STACK )
  end
  node
end