 		isA @expression, 'boolean'
 
 class FunctionExpression extends Expression #, Function
-	constructor: (@id, @params, @defaults, @rest, @body, isGenerator = false, isExpression = false, loc = null) ->
+	constructor: (@id = null, @params = [], @defaults = [], @rest = null, @body, isGenerator = false, isExpression = false, loc = null) ->
 		super 'FunctionExpression', loc
 		@generator = isGenerator
 		@expression = isExpression

		isNullOr @value, [ 'string', 'boolean', 'number', RegExp ]

class LogicalExpression extends Expression
	constructor: (op, @left, @right, loc = null) ->
		super 'LogicalExpression', loc
		@operator = op
		isLiterally @operator, LogicalOperator
		isA @left, Expression
		isA @right, Expression

class MemberExpression extends Expression
	constructor: (obj, prop, isComputed, loc = null) ->
		super 'MemberExpression', loc
		@object = obj
		@property = prop
		@computed = isComputed
		isA @object, Expression
		isOneOf @property, [ Identifier, Expression ]
		isA @computed, 'boolean'

class NewExpression extends Expression
	constructor: (@callee, args, loc = null) ->
		super 'NewExpression', loc
		@arguments = args
		isA @callee, Expression
		isArrayOf @arguments, Expression

class ObjectExpression extends Expression
	constructor: (props, loc = null) ->
		super 'ObjectExpression', loc
		@properties = props
		isArrayOf @properties, Property

class ObjectPattern extends Pattern
	constructor: (props, loc = null) ->
		super 'ObjectPattern', loc
		@properties = props
		isArrayOf @properties, PropertyPattern

class Program extends Node
	constructor: (@body, loc = null) ->
		super 'Program', loc
		isArrayOf @body, Statement

class Property extends Node
	constructor: (@key, val, @kind, loc = null) ->
		super 'Property', loc
		@value = val
		isOneOf @key, [ Literal, Identifier ]
		isA @value, Expression
		isLiterally @kind, [ 'init', 'get', 'set' ]

class PropertyPattern extends Node
	constructor: (@key, patt, loc = null) ->
		super 'PropertyPattern', loc
		@value = patt
		isOneOf @key, [ Literal, Identifier ]
		isA @value, Pattern

class ReturnStatement extends Statement
	constructor: (arg, loc = null) ->
		super 'ReturnStatement', loc
		@argument = arg
		isNullOr @argument, Expression

class SequenceExpression extends Expression
	constructor: (exprs, loc = null) ->
		super 'SequenceExpression', loc
		@expressions = exprs
		isArrayOf @expressions, Expression

class SpreadExpression extends Expression
	constructor: (argument, loc = null) ->
		super 'SpreadExpression', loc
		@argument = argument
		isA @argument, Expression

class SwitchCase extends Node
	constructor: (@test, cons, loc = null) ->
		super 'SwitchCase', loc
		@consequent = cons
		isNullOr @test, Expression
		isArrayOf @consequent, Statement

class SwitchStatement extends Statement
	constructor: (disc, @cases, isLexical, loc = null) ->
		super 'SwitchStatement', loc
		@discriminant = disc
		@lexical = isLexical
		isA @discriminant, Expression
		isArrayOf @cases, SwitchCase

		isA @name, 'string'

class IfStatement extends Statement
	constructor: (@test, @consequent, @alternate = null, loc = null) ->
		super 'IfStatement', loc
		isA @test, Expression
		isA @consequent, Statement
		isNullOr @alternate, Statement
