grunt-dust
Version:
Grunt.js plugin to compile dustjs templates.
123 lines (101 loc) • 3.53 kB
text/coffeescript
esprima = require "esprima"
path = require "path"
class Parser
constructor: ( ) ->
=
path:
wrapperType: null
returning: null
exports: null
templates: null
wrappers: null
raw: null
name: null
deps: null
callbackParams: null
parse: ->
if .wrapperType is "amd"
body =
body
body
else if .wrapperType is "commonjs"
body = .body[0]?.expression?.right?.callee?.body?.body
.exports = .body[0]?.expression?.right
body
body
.wrappers = null
else if .wrapperType is "raw"
.body
.wrappers = null
_extractArray: ( array ) ->
element.value for element in array
raw: ->
.raw = grunt.file.read
ast: ->
= esprima.parse .raw
type: ->
if path.basename( ) is "dust-runtime.js"
.wrapperType = "dust_runtime"
else if .body[0].type is "ExpressionStatement"
if .body[0].expression.callee?.name is "define"
.wrapperType = "amd"
else if .body[0]?.expression?.type is "AssignmentExpression"
.wrapperType = "commonjs"
else
.wrapperType = "raw"
else
.wrapperType = null
_parseArgs: ( args ) ->
res = {}
for argument in args
switch argument.type
when "Literal"
res.name = argument.value
when "ArrayExpression"
res.deps = argument.elements
when "FunctionExpression"
res.callbackParams = argument.params
res.body = argument.body.body
res
defineArgs: ->
parsed = .body[0].expression?.arguments
.name = parsed.name ? null
.deps = parsed.deps ? null
.callbackParams = parsed.callbackParams ? null
parsed.body
definitions: ( body ) ->
.templates = []
.wrappers = []
.deps ?= []
for expression in body when expression.type in [ "ExpressionStatement", "VariableDeclaration" ]
fn = expression.expression
if expression.type is "VariableDeclaration"
for declaration in expression.declarations
# declaration.id.name
.deps.push [ 0 ]
else if fn.callee.type is "Identifier" and fn.callee.name is "define"
# template amd wrapper
.wrappers.push name if ( name = .name )?
else if fn.callee.type is "FunctionExpression"
# template definition
try
fnBody = fn.callee.body.body
templateName = [0]
.templates.push templateName
returning: ( body ) ->
for expression in body when expression.type is "ReturnStatement"
.returning = switch expression.argument.type
when "ArrayExpression"
expression.argument.elements
when "Literal"
expression.argument.value
when "FunctionExpression", "Identifier"
expression.argument
return @
module.exports = ( abspath ) ->
parser = new Parser abspath
parser.parse()