 
   # All the mucking about with commas is to make sure that CommentNodes and
   # AssignNodes get interleaved correctly, with no trailing commas or
-  # commas affixed to comments. TODO: Extract this and add it to ArrayNode.
+  # commas affixed to comments.
+  #
+  # *TODO: Extract this and add it to ArrayNode*.
   compile_node: (o) ->
     o.indent: @idt(1)
     non_comments: prop for prop in @properties when not (prop instanceof CommentNode)

    inner: if props then '\n' + props + '\n' + @idt() else ''
    "{$inner}"


# A class literal, including optional superclass and constructor.
exports.ClassNode: class ClassNode extends BaseNode
  type: 'Class'

  constructor: (variable, parent, props) ->
    @children: compact flatten [@variable: variable, @parent: parent, @properties: props or []]

  compile_node: (o) ->
    extension:   @parent and new ExtendsNode(@variable, @parent)
    constructor: null
    props:       new Expressions()
    o.top:       true
    ret:         del o, 'returns'

    for prop in @properties
      if prop.variable and prop.variable.base.value is 'constructor'
        func: prop.value
        func.body.push(new ReturnNode(literal('this')))
        constructor: new AssignNode(@variable, func)
      else
        if prop.variable
          val: new ValueNode(@variable, [new AccessorNode(prop.variable, 'prototype')])
          prop: new AssignNode(val, prop.value)
        props.push prop

    if not constructor
      if @parent
        applied: new ValueNode(@parent, [new AccessorNode(literal('apply'))])
        constructor: new AssignNode(@variable, new CodeNode([], new Expressions([
          new CallNode(applied, [literal('this'), literal('arguments')])
        ])))
      else
        constructor: new AssignNode(@variable, new CodeNode())

    construct:                       @idt() + constructor.compile(o) + ';\n'
    props:     if props.empty() then '' else props.compile(o) + '\n'
    extension: if extension     then @idt() + extension.compile(o) + ';\n' else ''
    returns:   if ret           then '\n' + @idt() + 'return ' + @variable.compile(o) + ';' else ''
    "$construct$extension$props$returns"

statement ClassNode


# An array literal.
exports.ArrayNode: class ArrayNode extends BaseNode


}

#### AssignNode

# The **AssignNode** is used to assign a local variable to value, or to set the
# property of an object -- including within object literals.
exports.AssignNode: class AssignNode extends BaseNode
  type: 'Assign'

  # Matchers for detecting prototype assignments.
  PROTO_ASSIGN: /^(\S+)\.prototype/
  LEADING_DOT:  /^\.(prototype\.)?/

