Skip to content

Commit 4db08bf

Browse files
committed
rewrote some serialiser code which deals with whitespace to avoid coffee parse errors for some output
1 parent b645e4f commit 4db08bf

File tree

3 files changed

+37
-27
lines changed

3 files changed

+37
-27
lines changed

src/parser.coffee

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ module.exports = class Parser
131131

132132
unless tagName is @activeBranchNode().value
133133
throwSyntaxError \
134-
"$.CJSX_START tag #{@activeBranchNode().value} doesn't match $.CJSX_END tag #{tagName}",
134+
"opening CJSX tag #{@activeBranchNode().value} doesn't match closing CJSX tag #{tagName}",
135135
first_line: @chunkLine, first_column: @chunkColumn
136136

137137
@popActiveBranchNode() # close cjsx tag

src/serialiser.coffee

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ serialise.serialisers = serialisers =
4949
serialisedChildren = []
5050
accumulatedWhitespace = ''
5151

52-
node.children.forEach (child) ->
52+
for child in node.children
5353
serialisedChild = env.serialiseNode child
5454
if child? # filter empty text nodes
5555
if WHITESPACE_ONLY.test serialisedChild
56-
accumulatedWhitespace += serialisedChild.replace('\n','\\\n')
56+
accumulatedWhitespace += serialisedChild
5757
else
5858
serialisedChildren.push(accumulatedWhitespace + serialisedChild)
5959
accumulatedWhitespace = ''
@@ -72,29 +72,44 @@ serialise.serialisers = serialisers =
7272
'('+childrenSerialised+')'
7373

7474
CJSX_ATTRIBUTES: (node, env) ->
75-
# whitespace (particularly newlines) must be maintained for attrs
75+
# whitespace (particularly newlines) must be maintained
7676
# to ensure line number parity
77-
nonWhitespaceChildren = node.children.filter (child) ->
78-
child.type isnt $.CJSX_WHITESPACE
7977

80-
lastNonWhitespaceChild = last(nonWhitespaceChildren)
81-
82-
if nonWhitespaceChildren.length
83-
childrenSerialised = node.children
84-
.map (child) ->
85-
serialised = env.serialiseNode child
86-
if child.type is $.CJSX_WHITESPACE
87-
if containsNewlines(serialised)
88-
serialised.replace('\n',' \\\n')
78+
# sort children into whitespace and semantic (non whitespace) groups
79+
# this seems wrong :\
80+
[whitespaceChildren, semanticChildren] = node.children.reduce((partitionedChildren, child) ->
81+
if child.type is $.CJSX_WHITESPACE
82+
partitionedChildren[0].push child
83+
else
84+
partitionedChildren[1].push child
85+
partitionedChildren
86+
, [[],[]])
87+
88+
indexOfLastSemanticChild = node.children.lastIndexOf(last(semanticChildren))
89+
90+
isBeforeLastSemanticChild = (childIndex) ->
91+
childIndex < indexOfLastSemanticChild
92+
93+
if semanticChildren.length
94+
serialisedChildren = for child, childIndex in node.children
95+
serialisedChild = env.serialiseNode child
96+
if child.type is $.CJSX_WHITESPACE
97+
if containsNewlines(serialisedChild)
98+
if isBeforeLastSemanticChild(childIndex)
99+
# escaping newlines within attr object helps avoid
100+
# parse errors in tags which span multiple lines
101+
serialisedChild.replace('\n',' \\\n')
89102
else
90-
null # whitespace without newlines is not significant
91-
else if child is lastNonWhitespaceChild
92-
serialised
103+
# but escaped newline at end of attr object is not allowed
104+
serialisedChild
93105
else
94-
serialised+', '
95-
.join('')
106+
null # whitespace without newlines is not significant
107+
else if isBeforeLastSemanticChild(childIndex)
108+
serialisedChild+', '
109+
else
110+
serialisedChild
96111

97-
'{'+childrenSerialised+'}'
112+
'{'+serialisedChildren.join('')+'}'
98113
else
99114
'null'
100115

@@ -145,7 +160,6 @@ serialise.serialisers = serialisers =
145160
CJSX_ATTR_VAL: genericLeafSerialiser
146161

147162

148-
149163
containsNewlines = (text) -> text.indexOf('\n') > -1
150164

151165
SPACES_ONLY = /^\s+$/

src/transformer.coffee

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11

2-
# Import the helpers we need.
3-
{count, starts, compact, last, repeat,
4-
locationDataToString, throwSyntaxError} = require './helpers'
5-
62
Parser = require './parser'
73
serialise = require './serialiser'
84

95
module.exports.transform = (code, opts) ->
10-
serialise new Parser().parse code, opts
6+
serialise(new Parser().parse(code, opts))

0 commit comments

Comments
 (0)