Skip to content

Instantly share code, notes, and snippets.

@jbarnette
Created September 26, 2008 18:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jbarnette/13164 to your computer and use it in GitHub Desktop.
Save jbarnette/13164 to your computer and use it in GitHub Desktop.
require "rubygems"
require "johnson"
require "./visitor.rb"
js =<<-END
function top() {
"top docstring", { command: true }
doSomething();
};
function justADocstring() {
"justADocstring docstring"
doSomething();
}
function noMeta() {
doSomething();
};
Namespace = {
nested: function() {
"nested docstring", { command: true }
doSomething();
},
Doubly: {
nested: function() {
"doubly nested docstring", { command: true }
doSomething();
}
}
};
var NamespaceWithVar = {
nested: function() {
"nested with var docstring", { command: true }
doSomething();
}
};
END
ast = Johnson.parse(js);
visitor = MetaVisitor.new("inlineText") do |data|
puts data.inspect
end
ast.accept(visitor)
class Array
def poke(item, &block)
push(item)
yield(item)
pop
end
end
class MetaVisitor < Johnson::Visitors::EnumeratingVisitor
class Data
attr_reader :name, :file, :line, :column, :docs, :extras
def initialize(name, file, line, column, docs, extras={})
@name = name
@file = file
@line = line
@column = column
@docs = docs
@extras = extras
end
end
def initialize(file, &block)
@file = file
@block = lambda {} # FIXME: refactoring Johnson to make this better
@realblock = block
@namespace = []
end
def visit_Function(o)
name = (@namespace + [o.name]).compact.join(".")
docs = extract_docs(o)
extras = extract_extras(o)
if docs
data = Data.new(name, @file, o.line, o.column, docs, extras)
@realblock[data]
end
end
%w(OpEqual AssignExpr Property).each do |type|
define_method(:"visit_#{type}") do |o|
@namespace.poke(o.left.value) { super }
end
end
def extract_extras(function)
extras = {}
if Johnson::Nodes::Comma === comma = function.body.value.first
if Johnson::Nodes::ObjectLiteral === object = comma.value.last
object.value.each do |property|
extras[property.left.value.to_sym] = property.right.value
end
end
end
extras
end
def extract_docs(function)
case node = function.body.value.first
when Johnson::Nodes::String
node.value
when Johnson::Nodes::Comma
node.value.first.value
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment