Class: Iro::Ruby::Parser

Inherits:
Ripper::SexpBuilderPP
  • Object
show all
Defined in:
lib/iro/ruby/parser.rb

Constant Summary collapse

EVENT_NAME_TO_HIGHLIGT_NAME =
{
  tstring_content: 'String',
  CHAR: 'Character',
  int: 'Number',
  float: 'Float',
  label: 'rubySymbol',
  
  comment: 'Comment',
  embdoc: 'Comment',
  embdoc_beg: 'Comment',
  embdoc_end: 'Comment',

  const: 'Type',
  
  regexp_beg: 'Delimiter',
  regexp_end: 'Delimiter',
  heredoc_beg: 'Delimiter',
  heredoc_end: 'Delimiter',
  tstring_beg: 'Delimiter',
  tstring_end: 'Delimiter',
  embexpr_beg: 'Delimiter',
  embexpr_end: 'Delimiter',
  backtick: 'Delimiter',

  symbeg: 'rubySymbolDelimiter',

  ivar: 'rubyInstanceVariable',
  cvar: 'rubyClassVariable',
  gvar: 'rubyGlobalVariable',
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeParser

Returns a new instance of Parser.



39
40
41
42
# File 'lib/iro/ruby/parser.rb', line 39

def initialize(*)
  super
  @tokens = {}
end

Instance Attribute Details

#tokensObject (readonly)

Returns the value of attribute tokens.



37
38
39
# File 'lib/iro/ruby/parser.rb', line 37

def tokens
  @tokens
end

Class Method Details

.tokens(source) ⇒ Object



132
133
134
135
136
137
# File 'lib/iro/ruby/parser.rb', line 132

def self.tokens(source)
  parser = self.new(source)
  sexp = parser.parse
  parser.traverse(sexp) unless parser.error?
  parser.tokens
end

Instance Method Details

#kw_group(str) ⇒ Object



86
87
88
89
90
91
# File 'lib/iro/ruby/parser.rb', line 86

def kw_group(str)
  {
    'def' => 'rubyDefine',
    'alias' => 'rubyDefine',
  }[str] || 'Keyword'
end

#on_def(name, params, body) ⇒ Object



93
94
95
96
97
# File 'lib/iro/ruby/parser.rb', line 93

def on_def(name, params, body)
  super.tap do
    register_scanner_event 'rubyFunction', name
  end
end

#on_defs(recv, period, name, params, body) ⇒ Object



99
100
101
102
103
# File 'lib/iro/ruby/parser.rb', line 99

def on_defs(recv, period, name, params, body)
  super.tap do
    register_scanner_event 'rubyFunction', name
  end
end

#on_kw(str) ⇒ Object



80
81
82
83
84
# File 'lib/iro/ruby/parser.rb', line 80

def on_kw(str)
  group = kw_group(str)
  register_token group, [lineno, column+1, str.size]
  super
end

#on_symbol(node) ⇒ Object



105
106
107
108
109
110
# File 'lib/iro/ruby/parser.rb', line 105

def on_symbol(node)
  super.tap do
    unhighlight! node if node.gvar_type? || node.ivar_type? || node.cvar_type?
    register_scanner_event 'rubySymbol', node
  end
end

#on_var_ref(name) ⇒ Object



112
113
114
115
116
117
118
# File 'lib/iro/ruby/parser.rb', line 112

def on_var_ref(name)
  super.tap do
    if name.ident_type?
      register_scanner_event 'rubyLocalVariable', name
    end
  end
end

#register_scanner_event(group, event) ⇒ Object

TODO: Maybe multiline support is needed.



50
51
52
53
# File 'lib/iro/ruby/parser.rb', line 50

def register_scanner_event(group, event)
  pos = event.position
  register_token group, [pos[0], pos[1]+1, event.content.size]
end

#register_token(group, token) ⇒ Object



44
45
46
47
# File 'lib/iro/ruby/parser.rb', line 44

def register_token(group, token)
  @tokens[group] ||= []
  @tokens[group] << token
end

#traverse(node) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
# File 'lib/iro/ruby/parser.rb', line 120

def traverse(node)
  if node.kw_type?
    unhighlight!(node)
  end

  return if node.scanner_event?

  node.children.each do |child|
    traverse(child) if child.is_a?(Array)
  end
end

#unhighlight!(scanner_event) ⇒ Object



55
56
57
58
59
60
61
62
63
64
# File 'lib/iro/ruby/parser.rb', line 55

def unhighlight!(scanner_event)
  t = scanner_event.type[1..-1].to_sym
  group = EVENT_NAME_TO_HIGHLIGT_NAME[t] ||
    (scanner_event.kw_type? && kw_group(scanner_event.content))
  raise 'bug' unless group

  t = scanner_event.position + [scanner_event.content.size]
  t[1] += 1
  @tokens[group].reject! { |ev| ev == t }
end