class JsDuck::Js::Serializer
Transforms Esprima AST into string
Constants
- PRECEDENCE
Precedence rules of JavaScript operators.
Taken from: developer.mozilla.org/en/JavaScript/Reference/Operators/Operator_Precedence
Public Instance Methods
to_s(ast)
click to toggle source
Turns AST node into string
# File lib/jsduck/js/serializer.rb, line 8 def to_s(ast) case ast["type"] when "Program" ast["body"].map {|s| to_s(s) }.join # Statements when "BlockStatement" "{" + ast["body"].map {|s| to_s(s) }.join + "}" when "BreakStatement" "break" + (ast["label"] ? " " + to_s(ast["label"]) : "") + ";" when "ContinueStatement" "continue" + (ast["label"] ? " " + to_s(ast["label"]) : "") + ";" when "DoWhileStatement" "do " + to_s(ast["body"]) + " while (" + to_s(ast["test"]) + ");" when "DebuggerStatement" "debugger;" when "EmptyStatement" ";" when "ExpressionStatement" to_s(ast["expression"]) + ";" when "ForStatement" init = ast["init"] ? to_s(ast["init"]).sub(/;\z/, "") : "" test = ast["test"] ? to_s(ast["test"]) : "" update = ast["update"] ? to_s(ast["update"]) : "" "for (" + init + "; " + test + "; " + update + ") " + to_s(ast["body"]) when "ForInStatement" left = to_s(ast["left"]).sub(/;\z/, "") right = to_s(ast["right"]) "for (" + left + " in " + right + ") " + to_s(ast["body"]) when "IfStatement" alternate = ast["alternate"] ? " else " + to_s(ast["alternate"]) : "" "if (" + to_s(ast["test"]) + ") " + to_s(ast["consequent"]) + alternate when "LabeledStatement" to_s(ast["label"]) + ": " + to_s(ast["body"]) when "ReturnStatement" arg = ast["argument"] ? to_s(ast["argument"]) : "" "return " + arg + ";" when "SwitchStatement" "switch (" + to_s(ast["discriminant"]) + ") {" + ast["cases"].map {|c| to_s(c) }.join + "}" when "SwitchCase" test = ast["test"] ? "case " + to_s(ast["test"]) : "default" test + ": " + ast["consequent"].map {|c| to_s(c) }.join when "ThrowStatement" "throw " + to_s(ast["argument"]) + ";" when "TryStatement" handlers = ast["handlers"].map {|h| to_s(h) }.join finalizer = ast["finalizer"] ? " finally " + to_s(ast["finalizer"]) : "" "try " + to_s(ast["block"]) + handlers + finalizer when "CatchClause" param = ast["param"] ? to_s(ast["param"]) : "" " catch (" + param + ") " + to_s(ast["body"]) when "WhileStatement" "while (" + to_s(ast["test"]) + ") " + to_s(ast["body"]) when "WithStatement" "with (" + to_s(ast["object"]) + ") " + to_s(ast["body"]) # Declarations when "FunctionDeclaration" function(ast) when "VariableDeclaration" ast["kind"] + " " + list(ast["declarations"]) + ";" when "VariableDeclarator" if ast["init"] to_s(ast["id"]) + " = " + to_s(ast["init"]) else to_s(ast["id"]) end # Expressions when "AssignmentExpression" parens(ast, ast["left"]) + " " + ast["operator"] + " " + to_s(ast["right"]) when "ArrayExpression" "[" + list(ast["elements"]) + "]" when "BinaryExpression" binary(ast) when "CallExpression" call(ast) when "ConditionalExpression" parens(ast, ast["test"]) + " ? " + to_s(ast["consequent"]) + " : " + to_s(ast["alternate"]) when "FunctionExpression" function(ast) when "LogicalExpression" binary(ast) when "MemberExpression" if ast["computed"] parens(ast, ast["object"]) + "[" + to_s(ast["property"]) + "]" else parens(ast, ast["object"]) + "." + to_s(ast["property"]) end when "NewExpression" "new " + call(ast) when "ObjectExpression" "{" + list(ast["properties"]) + "}" when "Property" to_s(ast["key"]) + ": " + to_s(ast["value"]) when "SequenceExpression" list(ast["expressions"]) when "ThisExpression" "this" when "UnaryExpression" ast["operator"] + parens(ast, ast["argument"]) when "UpdateExpression" if ast["prefix"] ast["operator"] + parens(ast, ast["argument"]) else parens(ast, ast["argument"]) + ast["operator"] end # Basics when "Identifier" ast["name"] when "Literal" ast["raw"] else throw "Unknown node type: " + (ast["type"] || "nil") end end
Private Instance Methods
binary(ast)
click to toggle source
Handles both binary- and logical-expression
# File lib/jsduck/js/serializer.rb, line 187 def binary(ast) parens(ast, ast["left"]) + " " + ast["operator"] + " " + parens(ast, ast["right"]) end
call(ast)
click to toggle source
serializes call- and new-expression
# File lib/jsduck/js/serializer.rb, line 182 def call(ast) parens(ast, ast["callee"]) + "(" + list(ast["arguments"]) + ")" end
function(ast)
click to toggle source
serializes function declaration or expression
# File lib/jsduck/js/serializer.rb, line 170 def function(ast) params = list(ast["params"]) id = ast["id"] ? to_s(ast["id"]) : "" "function " + id + "(" + params + ") " + to_s(ast["body"]) end
list(array)
click to toggle source
serializes list of comma-separated items
# File lib/jsduck/js/serializer.rb, line 177 def list(array) array.map {|x| to_s(x) }.join(", ") end
parens(parent, child)
click to toggle source
serializes child node and wraps it inside parenthesis if the precedence rules compared to parent node would require so.
# File lib/jsduck/js/serializer.rb, line 193 def parens(parent, child) if precedence(parent) >= precedence(child) to_s(child) else "(" + to_s(child) + ")" end end
precedence(ast)
click to toggle source
Returns
the precedence of operator represented by given AST node
# File lib/jsduck/js/serializer.rb, line 202 def precedence(ast) p = PRECEDENCE[ast["type"]] if p.is_a? Fixnum p elsif p.is_a? Hash p[ast["operator"]] else 0 end end