Fixed inline comment on first body line
This commit is contained in:
parent
643dc2e716
commit
3caad78015
|
@ -37,6 +37,11 @@ export const Value = createToken({
|
|||
line_breaks: true,
|
||||
pop_mode: true,
|
||||
});
|
||||
export const CommentStartNewline = createToken({
|
||||
name: "CommentStartNewline",
|
||||
pattern: '\n#',
|
||||
push_mode: "comment_mode",
|
||||
});
|
||||
export const CommentStart = createToken({
|
||||
name: "CommentStart",
|
||||
pattern: '#',
|
||||
|
@ -56,6 +61,7 @@ export const WhiteSpace = createToken({
|
|||
|
||||
export const tokens = [
|
||||
CommentStart,
|
||||
CommentStartNewline,
|
||||
Value,
|
||||
Comment,
|
||||
SectionHeading,
|
||||
|
@ -67,6 +73,7 @@ export default new Lexer({
|
|||
defaultMode: "line_mode",
|
||||
modes: {
|
||||
line_mode: [
|
||||
CommentStartNewline,
|
||||
CommentStart,
|
||||
SectionHeading,
|
||||
Property,
|
||||
|
|
|
@ -4,6 +4,7 @@ import {
|
|||
tokens,
|
||||
Comment,
|
||||
CommentStart,
|
||||
CommentStartNewline,
|
||||
Property,
|
||||
SectionHeading,
|
||||
Value,
|
||||
|
@ -14,6 +15,11 @@ export default class UnitFileParser extends CstParser {
|
|||
super(tokens);
|
||||
const $ = this;
|
||||
|
||||
$.RULE("commentLine", () => {
|
||||
$.CONSUME(CommentStartNewline);
|
||||
$.CONSUME(Comment);
|
||||
});
|
||||
|
||||
$.RULE("comment", () => {
|
||||
$.CONSUME(CommentStart);
|
||||
$.CONSUME(Comment);
|
||||
|
@ -41,7 +47,7 @@ export default class UnitFileParser extends CstParser {
|
|||
$.RULE("sectionStatement", () => {
|
||||
$.OR([
|
||||
{ ALT: () => $.SUBRULE($.propertyStatement) },
|
||||
{ ALT: () => $.SUBRULE($.comment) },
|
||||
{ ALT: () => $.SUBRULE($.commentLine) },
|
||||
]);
|
||||
});
|
||||
|
||||
|
|
|
@ -7,13 +7,21 @@ export default (parser) => {
|
|||
this.validateVisitor();
|
||||
};
|
||||
|
||||
comment(ctx) {
|
||||
_comment(ctx) {
|
||||
return {
|
||||
type: "comment",
|
||||
value: ctx.Comment.map(({ image }) => image.replace(/^\s/, '').replace(/\s$/, '')).join(''),
|
||||
};
|
||||
}
|
||||
|
||||
comment(ctx) {
|
||||
return this._comment(ctx);
|
||||
}
|
||||
|
||||
commentLine(ctx) {
|
||||
return this._comment(ctx);
|
||||
}
|
||||
|
||||
propertyStatement(ctx) {
|
||||
const name = ctx.Property[0].image;
|
||||
return {
|
||||
|
@ -25,7 +33,7 @@ export default (parser) => {
|
|||
}
|
||||
|
||||
sectionStatement(ctx) {
|
||||
const content = ctx.propertyStatement?.[0] || ctx.comment?.[0];
|
||||
const content = ctx.propertyStatement?.[0] || ctx.commentLine?.[0];
|
||||
return this.visit(content);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
export const content = `# Outside comment
|
||||
[Unit] # Heading comment
|
||||
# Inline comment
|
||||
Description=Idle manager for Wayland # End of value comment
|
||||
# Inline comment
|
||||
ExecStart=echo\
|
||||
"some string" # End of value comment
|
||||
Alias=asdf#Comment Without spaces
|
||||
|
@ -19,13 +19,13 @@ export const result = {
|
|||
title: 'Unit',
|
||||
titleComment: { type: 'comment', value: 'Heading comment' },
|
||||
body: [
|
||||
{ type: 'comment', value: 'Inline comment' },
|
||||
{
|
||||
type: 'setting',
|
||||
name: 'Description',
|
||||
value: 'Idle manager for Wayland',
|
||||
comment: { type: 'comment', value: 'End of value comment' }
|
||||
},
|
||||
{ type: 'comment', value: 'Inline comment' },
|
||||
{
|
||||
type: 'setting',
|
||||
name: 'ExecStart',
|
||||
|
@ -43,8 +43,10 @@ export const result = {
|
|||
{
|
||||
type: 'section',
|
||||
title: 'Install',
|
||||
titleComment: { type: 'comment', value: 'Comment only in this body' },
|
||||
body: []
|
||||
titleComment: undefined,
|
||||
body: [
|
||||
{ type: 'comment', value: 'Comment only in this body' },
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@ import {
|
|||
visitorCreator,
|
||||
} from "../src/mod.mjs";
|
||||
|
||||
const runTest = (input) => {
|
||||
const runTest = (input, result) => {
|
||||
const parser = new Parser([], { outputCst: true });
|
||||
const lexingresult = Lexer.tokenize(input);
|
||||
|
||||
|
@ -26,7 +26,25 @@ const runTest = (input) => {
|
|||
const Visitor = visitorCreator(parser);
|
||||
const visitor = new Visitor();
|
||||
const ast = visitor.visit(cst);
|
||||
return ast;
|
||||
|
||||
const resultString = JSON.stringify(ast, null, 2);
|
||||
const expectedString = JSON.stringify(result, null, 2);
|
||||
if (resultString !== expectedString) {
|
||||
console.dir(ast, { depth: Infinity });
|
||||
console.dir(lexingresult, { depth: Infinity });
|
||||
throw new Error(`Mismatching result on testcase:
|
||||
${input}
|
||||
|
||||
=======Result======
|
||||
|
||||
${resultString}
|
||||
|
||||
=======Expected======
|
||||
|
||||
${expectedString}
|
||||
|
||||
`);
|
||||
}
|
||||
};
|
||||
|
||||
(async () => {
|
||||
|
@ -45,35 +63,5 @@ const runTest = (input) => {
|
|||
);
|
||||
|
||||
const cases = await Promise.all(files.flat().map(file => import(file)));
|
||||
|
||||
const results = cases.map(
|
||||
({ content, result }) => {
|
||||
const ast = runTest(content);
|
||||
const resultString = JSON.stringify(ast);
|
||||
const expectedString = JSON.stringify(result);
|
||||
if (resultString !== expectedString) {
|
||||
console.dir(ast, { depth: Infinity });
|
||||
throw new Error(`Mismatching result on testcase:
|
||||
${content}
|
||||
|
||||
=======Result======
|
||||
|
||||
${resultString}
|
||||
|
||||
=======Expected======
|
||||
|
||||
${expectedString}
|
||||
|
||||
`);
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
)
|
||||
.filter(r => r !== null);
|
||||
|
||||
if (results.length) {
|
||||
results.forEach(err => console.error(err));
|
||||
throw new Error(`${results.length} failed tests`);
|
||||
}
|
||||
const results = cases.forEach(({ content, result }) => runTest(content, result));
|
||||
})();
|
||||
|
|
Loading…
Reference in a new issue