Fixed inline comment on first body line

This commit is contained in:
Benjamin Bädorf 2020-11-25 03:45:26 +01:00
parent 643dc2e716
commit 3caad78015
No known key found for this signature in database
GPG key ID: 4406E80E13CD656C
5 changed files with 51 additions and 40 deletions

View file

@ -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,

View file

@ -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) },
]);
});

View file

@ -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);
}

View file

@ -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' },
]
}
]
};

View file

@ -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));
})();