Skip to content

Commit

Permalink
Simplify fix for jashkenas#4464
Browse files Browse the repository at this point in the history
This uses more of the existing machinery for moving class body
expressions into the initializer.
  • Loading branch information
connec committed Sep 20, 2017
1 parent becdf50 commit 1d3af8c
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 58 deletions.
41 changes: 14 additions & 27 deletions lib/coffeescript/nodes.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 21 additions & 31 deletions src/nodes.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -1636,16 +1636,17 @@ exports.Class = class Class extends Base
super()

compileNode: (o) ->
@name = @determineName()
@walkBody()
@name = @determineName()
executableBody = @walkBody()

# Special handling to allow `class expr.A extends A` declarations
parentName = @parent.base.value if @parent instanceof Value and not @parent.hasProperties()
@hasNameClash = @name? and @name is parentName

node = @
if @executableBody or @hasNameClash
node = new ExecutableClassBody node, @executableBody

if executableBody or @hasNameClash
node = new ExecutableClassBody node, executableBody
else if not @name? and o.level is LEVEL_TOP
# Anonymous classes are only valid in expressions
node = new Parens node
Expand All @@ -1665,7 +1666,7 @@ exports.Class = class Class extends Base

compileClassDeclaration: (o) ->
@ctor ?= @makeDefaultConstructor() if @externalCtor or @boundMethods.length
@ctor?.noReturn = yes
@ctor?.noReturn = true

@proxyBoundMethods() if @boundMethods.length

Expand All @@ -1677,14 +1678,10 @@ exports.Class = class Class extends Base
result.push @makeCode('extends '), @parent.compileToFragments(o)..., @makeCode ' ' if @parent

result.push @makeCode '{'
unless @passthroughBody.isEmpty() and @body.isEmpty()
@body.spaced = yes
unless @body.isEmpty()
@body.spaced = true
result.push @makeCode '\n'
unless @passthroughBody.isEmpty()
result.push @passthroughBody.compileToFragments(o, LEVEL_TOP)...
result.push @makeCode '\n\n' unless @body.isEmpty()
unless @body.isEmpty()
result.push @body.compileToFragments(o, LEVEL_TOP)...
result.push @body.compileToFragments(o, LEVEL_TOP)...
result.push @makeCode "\n#{@tab}"
result.push @makeCode '}'

Expand All @@ -1707,21 +1704,21 @@ exports.Class = class Class extends Base
if name in JS_FORBIDDEN then "_#{name}" else name

walkBody: ->
@ctor = null
@boundMethods = []
@ctor = null
@boundMethods = []
executableBody = null

initializer = []
passthroughBodyExpressions = []
{ expressions } = @body
initializer = []
{ expressions } = @body

i = 0
for expression, expressionIndex in expressions.slice()
if expression instanceof Value and expression.isObject yes
for expression in expressions.slice()
if expression instanceof Value and expression.isObject true
{ properties } = expression.base
exprs = []
end = 0
start = 0
pushSlice = -> exprs.push new Value new Obj properties[start...end], yes if end > start
pushSlice = -> exprs.push new Value new Obj properties[start...end], true if end > start

while assign = properties[end]
if initializerExpression = @addInitializerExpression assign
Expand All @@ -1734,9 +1731,6 @@ exports.Class = class Class extends Base

expressions[i..i] = exprs
i += exprs.length
else if expression instanceof Value and expression.base instanceof PassthroughLiteral
passthroughBodyExpressions.push expression
expressions.splice expressionIndex, 1
else
if initializerExpression = @addInitializerExpression expression
initializer.push initializerExpression
Expand All @@ -1752,19 +1746,15 @@ exports.Class = class Class extends Base
else if method.bound
@boundMethods.push method

@passthroughBody = new Block passthroughBodyExpressions

if initializer.length isnt expressions.length
@body.expressions = (expression.hoist() for expression in initializer)
@executableBody = new Block expressions

new Block expressions

# Add an expression to the class initializer
#
# NOTE Currently, only methods and static methods are valid in ES class initializers.
# When additional expressions become valid, this method should be updated to handle them.
addInitializerExpression: (node) ->
if @validInitializerMethod node
if node.unwrapAll() instanceof PassthroughLiteral
node
else if @validInitializerMethod node
@addInitializerMethod node
else
null
Expand Down

0 comments on commit 1d3af8c

Please sign in to comment.