89 lines
2.2 KiB
Ruby
89 lines
2.2 KiB
Ruby
module RKelly
|
|
module Nodes
|
|
class Node
|
|
include RKelly::Visitable
|
|
include RKelly::Visitors
|
|
include Enumerable
|
|
|
|
attr_accessor :value, :comments, :line, :filename
|
|
def initialize(value)
|
|
@value = value
|
|
@comments = []
|
|
@filename = @line = nil
|
|
end
|
|
|
|
def ==(other)
|
|
other.is_a?(self.class) && @value == other.value
|
|
end
|
|
alias :=~ :==
|
|
|
|
def ===(other)
|
|
other.is_a?(self.class) && @value === other.value
|
|
end
|
|
|
|
def pointcut(pattern)
|
|
case pattern
|
|
when String
|
|
ast = RKelly::Parser.new.parse(pattern)
|
|
# Only take the first statement
|
|
finder = ast.value.first.class.to_s =~ /StatementNode$/ ?
|
|
ast.value.first.value : ast.value.first
|
|
visitor = PointcutVisitor.new(finder)
|
|
else
|
|
visitor = PointcutVisitor.new(pattern)
|
|
end
|
|
|
|
visitor.accept(self)
|
|
visitor
|
|
end
|
|
alias :/ :pointcut
|
|
|
|
def to_sexp
|
|
SexpVisitor.new.accept(self)
|
|
end
|
|
|
|
def to_ecma
|
|
ECMAVisitor.new.accept(self)
|
|
end
|
|
|
|
def to_dots
|
|
visitor = DotVisitor.new
|
|
visitor.accept(self)
|
|
header = <<-END
|
|
digraph g {
|
|
graph [ rankdir = "TB" ];
|
|
node [
|
|
fontsize = "16"
|
|
shape = "ellipse"
|
|
];
|
|
edge [ ];
|
|
END
|
|
nodes = visitor.nodes.map { |x| x.to_s }.join("\n")
|
|
counter = 0
|
|
arrows = visitor.arrows.map { |x|
|
|
s = "#{x} [\nid = #{counter}\n];"
|
|
counter += 1
|
|
s
|
|
}.join("\n")
|
|
"#{header}\n#{nodes}\n#{arrows}\n}"
|
|
end
|
|
|
|
def each(&block)
|
|
EnumerableVisitor.new(block).accept(self)
|
|
end
|
|
|
|
def to_real_sexp
|
|
RealSexpVisitor.new.accept(self)
|
|
end
|
|
end
|
|
|
|
%w[EmptyStatement Parenthetical ExpressionStatement True Delete Return TypeOf
|
|
SourceElements Number LogicalNot AssignExpr FunctionBody
|
|
ObjectLiteral UnaryMinus Throw This BitwiseNot Element String
|
|
Array CaseBlock Null Break Parameter Block False Void Regexp
|
|
Arguments Attr Continue ConstStatement UnaryPlus VarStatement].each do |node|
|
|
eval "class #{node}Node < Node; end"
|
|
end
|
|
end
|
|
end
|