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, line_breaks: true,
pop_mode: true, pop_mode: true,
}); });
export const CommentStartNewline = createToken({
name: "CommentStartNewline",
pattern: '\n#',
push_mode: "comment_mode",
});
export const CommentStart = createToken({ export const CommentStart = createToken({
name: "CommentStart", name: "CommentStart",
pattern: '#', pattern: '#',
@ -56,6 +61,7 @@ export const WhiteSpace = createToken({
export const tokens = [ export const tokens = [
CommentStart, CommentStart,
CommentStartNewline,
Value, Value,
Comment, Comment,
SectionHeading, SectionHeading,
@ -67,6 +73,7 @@ export default new Lexer({
defaultMode: "line_mode", defaultMode: "line_mode",
modes: { modes: {
line_mode: [ line_mode: [
CommentStartNewline,
CommentStart, CommentStart,
SectionHeading, SectionHeading,
Property, Property,

View file

@ -4,6 +4,7 @@ import {
tokens, tokens,
Comment, Comment,
CommentStart, CommentStart,
CommentStartNewline,
Property, Property,
SectionHeading, SectionHeading,
Value, Value,
@ -14,6 +15,11 @@ export default class UnitFileParser extends CstParser {
super(tokens); super(tokens);
const $ = this; const $ = this;
$.RULE("commentLine", () => {
$.CONSUME(CommentStartNewline);
$.CONSUME(Comment);
});
$.RULE("comment", () => { $.RULE("comment", () => {
$.CONSUME(CommentStart); $.CONSUME(CommentStart);
$.CONSUME(Comment); $.CONSUME(Comment);
@ -41,7 +47,7 @@ export default class UnitFileParser extends CstParser {
$.RULE("sectionStatement", () => { $.RULE("sectionStatement", () => {
$.OR([ $.OR([
{ ALT: () => $.SUBRULE($.propertyStatement) }, { ALT: () => $.SUBRULE($.propertyStatement) },
{ ALT: () => $.SUBRULE($.comment) }, { ALT: () => $.SUBRULE($.commentLine) },
]); ]);
}); });

View file

@ -7,13 +7,21 @@ export default (parser) => {
this.validateVisitor(); this.validateVisitor();
}; };
comment(ctx) { _comment(ctx) {
return { return {
type: "comment", type: "comment",
value: ctx.Comment.map(({ image }) => image.replace(/^\s/, '').replace(/\s$/, '')).join(''), 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) { propertyStatement(ctx) {
const name = ctx.Property[0].image; const name = ctx.Property[0].image;
return { return {
@ -25,7 +33,7 @@ export default (parser) => {
} }
sectionStatement(ctx) { sectionStatement(ctx) {
const content = ctx.propertyStatement?.[0] || ctx.comment?.[0]; const content = ctx.propertyStatement?.[0] || ctx.commentLine?.[0];
return this.visit(content); return this.visit(content);
} }

View file

@ -1,7 +1,7 @@
export const content = `# Outside comment export const content = `# Outside comment
[Unit] # Heading comment [Unit] # Heading comment
# Inline comment
Description=Idle manager for Wayland # End of value comment Description=Idle manager for Wayland # End of value comment
# Inline comment
ExecStart=echo\ ExecStart=echo\
"some string" # End of value comment "some string" # End of value comment
Alias=asdf#Comment Without spaces Alias=asdf#Comment Without spaces
@ -19,13 +19,13 @@ export const result = {
title: 'Unit', title: 'Unit',
titleComment: { type: 'comment', value: 'Heading comment' }, titleComment: { type: 'comment', value: 'Heading comment' },
body: [ body: [
{ type: 'comment', value: 'Inline comment' },
{ {
type: 'setting', type: 'setting',
name: 'Description', name: 'Description',
value: 'Idle manager for Wayland', value: 'Idle manager for Wayland',
comment: { type: 'comment', value: 'End of value comment' } comment: { type: 'comment', value: 'End of value comment' }
}, },
{ type: 'comment', value: 'Inline comment' },
{ {
type: 'setting', type: 'setting',
name: 'ExecStart', name: 'ExecStart',
@ -43,8 +43,10 @@ export const result = {
{ {
type: 'section', type: 'section',
title: 'Install', title: 'Install',
titleComment: { type: 'comment', value: 'Comment only in this body' }, titleComment: undefined,
body: [] body: [
{ type: 'comment', value: 'Comment only in this body' },
]
} }
] ]
}; };

View file

@ -6,7 +6,7 @@ import {
visitorCreator, visitorCreator,
} from "../src/mod.mjs"; } from "../src/mod.mjs";
const runTest = (input) => { const runTest = (input, result) => {
const parser = new Parser([], { outputCst: true }); const parser = new Parser([], { outputCst: true });
const lexingresult = Lexer.tokenize(input); const lexingresult = Lexer.tokenize(input);
@ -26,7 +26,25 @@ const runTest = (input) => {
const Visitor = visitorCreator(parser); const Visitor = visitorCreator(parser);
const visitor = new Visitor(); const visitor = new Visitor();
const ast = visitor.visit(cst); 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 () => { (async () => {
@ -45,35 +63,5 @@ const runTest = (input) => {
); );
const cases = await Promise.all(files.flat().map(file => import(file))); const cases = await Promise.all(files.flat().map(file => import(file)));
const results = cases.forEach(({ content, result }) => runTest(content, result));
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`);
}
})(); })();