code-red
Advanced tools
Comparing version 0.0.18 to 0.0.19
# code-red changelog | ||
## 0.0.19 | ||
* Attach comments | ||
## 0.0.18 | ||
@@ -4,0 +8,0 @@ |
@@ -14,3 +14,15 @@ (function (global, factory) { | ||
return handler(node, state); | ||
const result = handler(node, state); | ||
if (node.leadingComments) { | ||
result.unshift(c(node.leadingComments.map(comment => comment.type === 'Block' | ||
? `/*${comment.value}*/${(comment ).has_trailing_newline ? `\n${state.indent}` : ` `}` | ||
: `//${comment.value}${(comment ).has_trailing_newline ? `\n${state.indent}` : ` `}`).join(``))); | ||
} | ||
if (node.trailingComments) { | ||
state.comments.push(node.trailingComments[0]); // there is only ever one | ||
} | ||
return result; | ||
} | ||
@@ -188,7 +200,18 @@ | ||
const body = nodes.map(statement => handle(statement, { | ||
...state, | ||
indent: state.indent | ||
})); | ||
const body = nodes.map(statement => { | ||
const chunks = handle(statement, { | ||
...state, | ||
indent: state.indent | ||
}); | ||
while (state.comments.length) { | ||
const comment = state.comments.shift(); | ||
chunks.push(c(comment.type === 'Block' | ||
? ` /*${comment.value}*/` | ||
: ` //${comment.value}`)); | ||
} | ||
return chunks; | ||
}); | ||
let needed_padding = false; | ||
@@ -332,4 +355,2 @@ | ||
const child_state = { ...state, indent: `${state.indent}\t\t` }; | ||
node.cases.forEach(block => { | ||
@@ -868,17 +889,49 @@ if (block.test) { | ||
const properties = node.properties.map(p => handle(p, { | ||
...state, | ||
indent: state.indent + '\t' | ||
})); | ||
let has_inline_comment = false; | ||
const chunks = []; | ||
const separator = c(', '); | ||
node.properties.forEach((p, i) => { | ||
chunks.push(...handle(p, { | ||
...state, | ||
indent: state.indent + '\t' | ||
})); | ||
if (state.comments.length) { | ||
// TODO generalise this, so it works with ArrayExpressions and other things. | ||
// At present, stuff will just get appended to the closest statement/declaration | ||
chunks.push(c(', ')); | ||
while (state.comments.length) { | ||
const comment = state.comments.shift(); | ||
chunks.push(c(comment.type === 'Block' | ||
? `/*${comment.value}*/\n${state.indent}\t` | ||
: `//${comment.value}\n${state.indent}\t`)); | ||
if (comment.type === 'Line') { | ||
has_inline_comment = true; | ||
} | ||
} | ||
} else { | ||
if (i < node.properties.length - 1) { | ||
chunks.push(separator); | ||
} | ||
} | ||
}); | ||
const multiple_lines = ( | ||
properties.some(has_newline) || | ||
(properties.map(get_length).reduce(sum, 0) + (state.indent.length + properties.length - 1) * 2) > 40 | ||
has_inline_comment || | ||
has_newline(chunks) || | ||
get_length(chunks) > 40 | ||
); | ||
const separator = c(multiple_lines ? `,\n${state.indent}\t` : ', '); | ||
if (multiple_lines) { | ||
separator.content = `,\n${state.indent}\t`; | ||
} | ||
return [ | ||
c(multiple_lines ? `{\n${state.indent}\t` : `{ `), | ||
...join(properties, separator) , | ||
...chunks, | ||
c(multiple_lines ? `\n${state.indent}}` : ` }`) | ||
@@ -1278,3 +1331,4 @@ ]; | ||
scope_map, | ||
deconflicted | ||
deconflicted, | ||
comments: [] | ||
}); | ||
@@ -1366,2 +1420,7 @@ | ||
if (Array.isArray(statement.expression)) { | ||
// TODO this is hacktacular | ||
let node = statement.expression[0]; | ||
while (Array.isArray(node)) node = node[0]; | ||
if (node) node.leadingComments = statement.leadingComments; | ||
flatten_body(statement.expression, target); | ||
@@ -1371,6 +1430,12 @@ continue; | ||
if (!/Expression$/.test(statement.expression.type)) { | ||
target.push(statement.expression); | ||
if (/(Expression|Literal)$/.test(statement.expression.type)) { | ||
target.push(statement); | ||
continue; | ||
} | ||
if (statement.leadingComments) statement.expression.leadingComments = statement.leadingComments; | ||
if (statement.trailingComments) statement.expression.trailingComments = statement.trailingComments; | ||
target.push(statement.expression); | ||
continue; | ||
} | ||
@@ -1420,4 +1485,44 @@ | ||
const inject = (node, values) => { | ||
const acorn_opts = (comments, raw) => { | ||
return { | ||
ecmaVersion: 11, | ||
sourceType: 'module', | ||
allowAwaitOutsideFunction: true, | ||
allowImportExportEverywhere: true, | ||
allowReturnOutsideFunction: true, | ||
onComment: (block, value, start, end) => { | ||
if (block && /\n/.test(value)) { | ||
let a = start; | ||
while (a > 0 && raw[a - 1] !== '\n') a -= 1; | ||
let b = a; | ||
while (/[ \t]/.test(raw[b])) b += 1; | ||
const indentation = raw.slice(a, b); | ||
value = value.replace(new RegExp(`^${indentation}`, 'gm'), ''); | ||
} | ||
comments.push({ type: block ? 'Block' : 'Line', value, start, end }); | ||
} | ||
} ; | ||
}; | ||
const inject = (raw, node, values, comments) => { | ||
estreeWalker.walk(node, { | ||
enter(node) { | ||
let comment; | ||
while (comments[0] && comments[0].start < (node ).start) { | ||
comment = comments.shift(); | ||
const next = comments[0] || node; | ||
(comment ).has_trailing_newline = ( | ||
comment.type === 'Line' || | ||
/\n/.test(raw.slice(comment.end, (next ).start)) | ||
); | ||
(node.leadingComments || (node.leadingComments = [])).push(comment); | ||
} | ||
}, | ||
leave(node, parent, key, index) { | ||
@@ -1434,12 +1539,8 @@ if (node.type === 'Identifier') { | ||
if (typeof value === 'string') { | ||
value = { type: 'Identifier', name: value }; | ||
value = { type: 'Identifier', name: value, leadingComments: node.leadingComments, trailingComments: node.trailingComments }; | ||
} else if (typeof value === 'number') { | ||
value = { type: 'Literal', value }; | ||
value = { type: 'Literal', value, leadingComments: node.leadingComments, trailingComments: node.trailingComments }; | ||
} | ||
if (index === null) { | ||
(parent )[key] = value || EMPTY; | ||
} else { | ||
(parent )[key][index] = value || EMPTY; | ||
} | ||
this.replace(value || EMPTY); | ||
} | ||
@@ -1452,2 +1553,16 @@ } else { | ||
if (node.leadingComments) { | ||
node.leadingComments = node.leadingComments.map(c => ({ | ||
...c, | ||
value: c.value.replace(re, (m, i) => +i in values ? values[+i] : m) | ||
})); | ||
} | ||
if (node.trailingComments) { | ||
node.trailingComments = node.trailingComments.map(c => ({ | ||
...c, | ||
value: c.value.replace(re, (m, i) => +i in values ? values[+i] : m) | ||
})); | ||
} | ||
if (node.type === 'Literal') { | ||
@@ -1494,2 +1609,10 @@ if (typeof node.value === 'string') { | ||
} | ||
if (comments[0]) { | ||
const slice = raw.slice((node ).end, comments[0].start); | ||
if (/^[,) \t]*$/.test(slice)) { | ||
node.trailingComments = [comments.shift()]; | ||
} | ||
} | ||
} | ||
@@ -1501,11 +1624,8 @@ }); | ||
const str = join$1(strings); | ||
const comments = []; | ||
try { | ||
const ast = acorn.parse(str, { | ||
ecmaVersion: 11, | ||
sourceType: 'module', | ||
allowAwaitOutsideFunction: true, | ||
allowReturnOutsideFunction: true | ||
} ); | ||
const ast = acorn.parse(str, acorn_opts(comments, str)); | ||
inject(ast, values); | ||
inject(str, ast, values, comments); | ||
@@ -1520,12 +1640,8 @@ return ast.body; | ||
const str = join$1(strings); | ||
const comments = []; | ||
try { | ||
const expression = acorn.parseExpressionAt(str, 0, { | ||
ecmaVersion: 11, | ||
sourceType: 'module', | ||
allowAwaitOutsideFunction: true, | ||
allowImportExportEverywhere: true | ||
} ) ; | ||
const expression = acorn.parseExpressionAt(str, 0, acorn_opts(comments, str)) ; | ||
inject(expression, values); | ||
inject(str, expression, values, comments); | ||
@@ -1540,12 +1656,8 @@ return expression; | ||
const str = `{${join$1(strings)}}`; | ||
const comments = []; | ||
try { | ||
const expression = acorn.parseExpressionAt(str, 0, { | ||
ecmaVersion: 11, | ||
sourceType: 'module', | ||
allowAwaitOutsideFunction: true, | ||
allowImportExportEverywhere: true | ||
} ) ; | ||
const expression = acorn.parseExpressionAt(str, 0, acorn_opts(comments, str)) ; | ||
inject(expression, values); | ||
inject(str, expression, values, comments); | ||
@@ -1552,0 +1664,0 @@ return expression.properties[0]; |
{ | ||
"name": "code-red", | ||
"description": "code-red", | ||
"version": "0.0.18", | ||
"version": "0.0.19", | ||
"repository": "Rich-Harris/code-red", | ||
@@ -6,0 +6,0 @@ "main": "dist/code-red.js", |
@@ -1,2 +0,2 @@ | ||
import { Node } from 'estree'; | ||
import { Comment, Node } from 'estree'; | ||
declare type Chunk = { | ||
@@ -22,4 +22,5 @@ content: string; | ||
deconflicted: WeakMap<Node, Map<string, string>>; | ||
comments: Comment[]; | ||
}; | ||
export declare function handle(node: Node, state: State): Chunk[]; | ||
export {}; |
Sorry, the diff of this file is not supported yet
78006
2756