Class: Ibex::Runtime::CST::SyntaxRewriter

Inherits:
Object
  • Object
show all
Defined in:
lib/ibex/runtime/cst/rewriter.rb,
sig/ibex/runtime/cst/rewriter.rbs

Overview

Bottom-up syntax rewriter with kind-name dispatch.

Instance Method Summary collapse

Instance Method Details

#method_name(name) ⇒ String

RBS:

  • (String name) -> String

Parameters:

  • name (String)

Returns:

  • (String)


69
70
71
# File 'lib/ibex/runtime/cst/rewriter.rb', line 69

def method_name(name)
  name.gsub(/[^a-zA-Z0-9_]/, "_")
end

#rewrite(root) ⇒ SyntaxNode

RBS:

  • (SyntaxNode root) -> SyntaxNode

Parameters:

Returns:



15
16
17
18
19
20
21
# File 'lib/ibex/runtime/cst/rewriter.rb', line 15

def rewrite(root)
  green = visit(root)
  return root if green.equal?(root.green)
  raise TypeError, "a syntax root must remain a GreenNode" unless green.is_a?(GreenNode)

  Editing.red_root(root, green)
end

#rewritten_view(original, rewritten) ⇒ element

RBS:

  • (element original, green rewritten) -> element

Parameters:

  • original (element)
  • rewritten (green)

Returns:

  • (element)


51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/ibex/runtime/cst/rewriter.rb', line 51

def rewritten_view(original, rewritten)
  if rewritten.is_a?(GreenNode)
    raise TypeError, "a node rewrite requires its original node" unless original.is_a?(SyntaxNode)

    source = SourceText.new(rewritten.to_source, file: original.root.source_text.file)
    return SyntaxNode.new(
      green: rewritten, kinds: original.kinds,
      trivia_policy: original.root.trivia_policy, source_text: source
    )
  end

  parent = original.parent
  raise TypeError, "a token rewrite requires its original parent" unless parent

  SyntaxToken.new(green: rewritten, parent: parent, index: original.index, offset: original.offset)
end

#visit(element) ⇒ green

RBS:

  • (element element) -> green

Parameters:

  • element (element)

Returns:

  • (green)


24
25
26
27
28
29
30
# File 'lib/ibex/runtime/cst/rewriter.rb', line 24

def visit(element)
  rewritten = element.is_a?(SyntaxNode) ? visit_children(element) : element.green
  method = :"visit_#{method_name(element.kind_name)}"
  return rewritten unless respond_to?(method, true)

  Editing.green_element(__send__(method, rewritten_view(element, rewritten)))
end

#visit_children(node) ⇒ GreenNode

RBS:

  • (SyntaxNode node) -> GreenNode

Parameters:

Returns:



35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/ibex/runtime/cst/rewriter.rb', line 35

def visit_children(node)
  changed = false
  children = node.children.map do |child|
    green = visit(child)
    changed ||= !green.equal?(child.green)
    green
  end
  return node.green unless changed

  GreenNode.new(
    kind: node.green.kind, children: children,
    flags: node.green.intrinsic_flags, annotations: node.green.annotations
  )
end