beancount 0.2.5 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/src/classes/Node.mjs +7 -7
- package/build/src/classes/nodes/Blankline.mjs +2 -6
- package/build/src/classes/nodes/Transaction/Posting.mjs +2 -2
- package/build/src/genericParse.d.mts +4 -3
- package/build/src/genericParse.mjs +18 -19
- package/build/src/main.d.mts +1 -1
- package/build/src/parse.d.mts +1 -1
- package/build/src/parse.mjs +1 -1
- package/build/src/utils/SourceLocation.d.mts +27 -4
- package/build/src/utils/splitStringIntoSourceFragments.js +30 -8
- package/build/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +7 -7
- package/build/src/classes/DateEntry.d.mts +0 -47
- package/build/src/classes/DateEntry.mjs +0 -60
- package/build/src/classes/Entry.d.mts +0 -92
- package/build/src/classes/Entry.mjs +0 -107
- package/build/src/classes/entryTypes/Balance.d.mts +0 -32
- package/build/src/classes/entryTypes/Balance.mjs +0 -50
- package/build/src/classes/entryTypes/Blankline.d.mts +0 -24
- package/build/src/classes/entryTypes/Blankline.mjs +0 -38
- package/build/src/classes/entryTypes/Close.d.mts +0 -20
- package/build/src/classes/entryTypes/Close.mjs +0 -31
- package/build/src/classes/entryTypes/Comment.d.mts +0 -25
- package/build/src/classes/entryTypes/Comment.mjs +0 -42
- package/build/src/classes/entryTypes/Commodity.d.mts +0 -20
- package/build/src/classes/entryTypes/Commodity.mjs +0 -31
- package/build/src/classes/entryTypes/Custom.d.mts +0 -23
- package/build/src/classes/entryTypes/Custom.mjs +0 -38
- package/build/src/classes/entryTypes/Document.d.mts +0 -22
- package/build/src/classes/entryTypes/Document.mjs +0 -34
- package/build/src/classes/entryTypes/Event.d.mts +0 -23
- package/build/src/classes/entryTypes/Event.mjs +0 -34
- package/build/src/classes/entryTypes/Include.d.mts +0 -20
- package/build/src/classes/entryTypes/Include.mjs +0 -31
- package/build/src/classes/entryTypes/Note.d.mts +0 -22
- package/build/src/classes/entryTypes/Note.mjs +0 -34
- package/build/src/classes/entryTypes/Open.d.mts +0 -27
- package/build/src/classes/entryTypes/Open.mjs +0 -66
- package/build/src/classes/entryTypes/Option.d.mts +0 -23
- package/build/src/classes/entryTypes/Option.mjs +0 -32
- package/build/src/classes/entryTypes/Pad.d.mts +0 -22
- package/build/src/classes/entryTypes/Pad.mjs +0 -33
- package/build/src/classes/entryTypes/Plugin.d.mts +0 -22
- package/build/src/classes/entryTypes/Plugin.mjs +0 -36
- package/build/src/classes/entryTypes/Poptag.d.mts +0 -21
- package/build/src/classes/entryTypes/Poptag.mjs +0 -34
- package/build/src/classes/entryTypes/Price.d.mts +0 -32
- package/build/src/classes/entryTypes/Price.mjs +0 -57
- package/build/src/classes/entryTypes/Pushtag.d.mts +0 -21
- package/build/src/classes/entryTypes/Pushtag.mjs +0 -34
- package/build/src/classes/entryTypes/Query.d.mts +0 -22
- package/build/src/classes/entryTypes/Query.mjs +0 -34
- package/build/src/classes/entryTypes/Transaction/Posting.d.mts +0 -59
- package/build/src/classes/entryTypes/Transaction/Posting.mjs +0 -97
- package/build/src/classes/entryTypes/Transaction/Tag.d.mts +0 -28
- package/build/src/classes/entryTypes/Transaction/Tag.mjs +0 -28
- package/build/src/classes/entryTypes/Transaction/index.d.mts +0 -70
- package/build/src/classes/entryTypes/Transaction/index.mjs +0 -193
- package/build/src/classes/entryTypes/index.d.mts +0 -19
- package/build/src/classes/entryTypes/index.mjs +0 -19
- package/build/src/entryTypeToClass.d.mts +0 -73
- package/build/src/entryTypeToClass.mjs +0 -37
- package/build/src/entryTypes.d.mts +0 -10
- package/build/src/entryTypes.mjs +0 -29
- package/build/src/utils/splitStringIntoUnparsedEntries.d.ts +0 -14
- package/build/src/utils/splitStringIntoUnparsedEntries.js +0 -48
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { genericParse } from '../genericParse.mjs';
|
|
2
|
-
import { stringAwareSplitLine } from '../utils/stringAwareSplitLine.mjs';
|
|
3
2
|
import { assignWithTrimmedStrings } from '../utils/assignWithTrimmedStrings.mjs';
|
|
4
3
|
import { defaultFormatOptions } from './ParseResult.mjs';
|
|
4
|
+
import { splitStringIntoSourceFragments } from '../utils/splitStringIntoSourceFragments.js';
|
|
5
5
|
/**
|
|
6
6
|
* Abstract base class for all nodes.
|
|
7
7
|
*
|
|
@@ -27,8 +27,11 @@ export class Node {
|
|
|
27
27
|
* @returns A new instance of the Node subclass
|
|
28
28
|
*/
|
|
29
29
|
static fromString(input) {
|
|
30
|
-
const sourceFragment =
|
|
31
|
-
|
|
30
|
+
const sourceFragment = splitStringIntoSourceFragments(input);
|
|
31
|
+
if (sourceFragment.length !== 1) {
|
|
32
|
+
throw new Error('Wrong directive count, expected 1');
|
|
33
|
+
}
|
|
34
|
+
const genericParseResult = genericParse(sourceFragment[0]);
|
|
32
35
|
const result = this.fromGenericParseResult(genericParseResult);
|
|
33
36
|
if (result.type !== genericParseResult.type) {
|
|
34
37
|
console.warn('Parse result type is not equal to requested object type, make sure the correct class is initiated');
|
|
@@ -70,7 +73,6 @@ export class Node {
|
|
|
70
73
|
* @param _formatOptions - Formatting options (unused in base implementation)
|
|
71
74
|
* @returns The formatted string representation of this node
|
|
72
75
|
*/
|
|
73
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
74
76
|
toFormattedString(_formatOptions = defaultFormatOptions) {
|
|
75
77
|
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
76
78
|
return this.toString();
|
|
@@ -103,6 +105,4 @@ export class Node {
|
|
|
103
105
|
* @param _ctor - The constructor to validate (unused at runtime)
|
|
104
106
|
* @internal
|
|
105
107
|
*/
|
|
106
|
-
export function assertNodeConstructor(
|
|
107
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
108
|
-
_ctor) { }
|
|
108
|
+
export function assertNodeConstructor(_ctor) { }
|
|
@@ -13,9 +13,7 @@ export class Blankline extends Node {
|
|
|
13
13
|
* @param _genericParseResult - Unused, blank lines have no content
|
|
14
14
|
* @returns A new Blankline instance
|
|
15
15
|
*/
|
|
16
|
-
static fromGenericParseResult(
|
|
17
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
18
|
-
_genericParseResult) {
|
|
16
|
+
static fromGenericParseResult(_genericParseResult) {
|
|
19
17
|
return new Blankline({});
|
|
20
18
|
}
|
|
21
19
|
/** @inheritdoc */
|
|
@@ -27,9 +25,7 @@ export class Blankline extends Node {
|
|
|
27
25
|
* @param _input - Unused, blank lines have no content
|
|
28
26
|
* @returns A new Blankline instance
|
|
29
27
|
*/
|
|
30
|
-
static fromString(
|
|
31
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
32
|
-
_input) {
|
|
28
|
+
static fromString(_input) {
|
|
33
29
|
return this.fromGenericParseResult({});
|
|
34
30
|
}
|
|
35
31
|
}
|
|
@@ -48,8 +48,8 @@ export class Posting {
|
|
|
48
48
|
const accountPattern = `([^ ]*)`;
|
|
49
49
|
const amountPattern = `([^A-Z;]*)`;
|
|
50
50
|
const costPattern = `{(.*)}`;
|
|
51
|
-
const pricePattern =
|
|
52
|
-
const amountCurrenyCostPattern = `${amountPattern}(?: +${currencyPattern})?(?: +${costPattern})?(
|
|
51
|
+
const pricePattern = ` *(@@|@) *(?:([^A-Z;]+) ${currencyPattern})`;
|
|
52
|
+
const amountCurrenyCostPattern = `${amountPattern}(?: +${currencyPattern})?(?: +${costPattern})?(?:${pricePattern})?`;
|
|
53
53
|
const commentPattern = `( *;.*)?`;
|
|
54
54
|
const pattern = `^(?:${flagPattern})?${accountPattern}(?: +${amountCurrenyCostPattern})?${commentPattern}$`;
|
|
55
55
|
const matches = RegExp(pattern).exec(unparsedline);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { BeancountDirectiveNodeType, SyntheticNodeType } from './nodeTypeToClass.mjs';
|
|
2
2
|
import { type Metadata } from './utils/parseMetadata.mjs';
|
|
3
|
+
import { type SourceFragmentWithLocation } from './utils/SourceLocation.mjs';
|
|
3
4
|
/**
|
|
4
5
|
* The basic result structure from generic parsing of a Beancount directive.
|
|
5
6
|
* Contains the directive type, header line content, and any properties like comments.
|
|
@@ -58,7 +59,7 @@ export interface GenericParseResultTransaction extends Omit<GenericParseResultWi
|
|
|
58
59
|
};
|
|
59
60
|
}
|
|
60
61
|
/**
|
|
61
|
-
* Regex pattern to identify Beancount directives
|
|
62
|
+
* Regex pattern to identify Beancount directives
|
|
62
63
|
* Generated from {@link NON_DATED_DIRECTIVE_TYPES} and {@link DATED_DIRECTIVE_TYPES} to ensure validation of directive types.
|
|
63
64
|
*/
|
|
64
65
|
export declare const beanCountDirectiveRegex: RegExp;
|
|
@@ -72,7 +73,7 @@ export declare const beanCountDirectiveRegex: RegExp;
|
|
|
72
73
|
* - Handles transaction-specific parsing (flags, body lines)
|
|
73
74
|
* - Parses metadata for dated directives
|
|
74
75
|
*
|
|
75
|
-
* @param sourceFragment -
|
|
76
|
+
* @param sourceFragment - A single source fragment
|
|
76
77
|
* @returns A generic parse result object appropriate for the node type
|
|
77
78
|
*/
|
|
78
|
-
export declare const genericParse: (sourceFragment:
|
|
79
|
+
export declare const genericParse: (sourceFragment: SourceFragmentWithLocation) => GenericParseResult | GenericParseResultTransaction | GenericParseResultWithDate | GenericParseResultSyntheticNode;
|
|
@@ -28,13 +28,13 @@ function compileDirectivePattern() {
|
|
|
28
28
|
'txn',
|
|
29
29
|
'[^ ]' /* flag */,
|
|
30
30
|
].join('|');
|
|
31
|
-
const datePattern =
|
|
32
|
-
const datedDirectivesPattern = `${datePattern} +(
|
|
33
|
-
const pattern = `^(
|
|
31
|
+
const datePattern = `(?<date>\\d{4}-\\d{2}-\\d{2})`;
|
|
32
|
+
const datedDirectivesPattern = `${datePattern} +(?<dated_directive>${datedDirectivesTypePattern})`;
|
|
33
|
+
const pattern = `^(?<non_dated_directive>${nonDatedDirectivesPattern})|(?:^${datedDirectivesPattern}) `;
|
|
34
34
|
return new RegExp(pattern);
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
37
|
-
* Regex pattern to identify Beancount directives
|
|
37
|
+
* Regex pattern to identify Beancount directives
|
|
38
38
|
* Generated from {@link NON_DATED_DIRECTIVE_TYPES} and {@link DATED_DIRECTIVE_TYPES} to ensure validation of directive types.
|
|
39
39
|
*/
|
|
40
40
|
export const beanCountDirectiveRegex = compileDirectivePattern();
|
|
@@ -48,26 +48,27 @@ export const beanCountDirectiveRegex = compileDirectivePattern();
|
|
|
48
48
|
* - Handles transaction-specific parsing (flags, body lines)
|
|
49
49
|
* - Parses metadata for dated directives
|
|
50
50
|
*
|
|
51
|
-
* @param sourceFragment -
|
|
51
|
+
* @param sourceFragment - A single source fragment
|
|
52
52
|
* @returns A generic parse result object appropriate for the node type
|
|
53
53
|
*/
|
|
54
54
|
export const genericParse = (sourceFragment) => {
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
55
|
+
const { fragment, directiveInfo } = sourceFragment;
|
|
56
|
+
const [firstLine, ...rest] = fragment;
|
|
57
|
+
if (!directiveInfo) {
|
|
58
|
+
// not a valid beancount directive, return it as a comment or a newline
|
|
59
|
+
if (firstLine.trim() === '') {
|
|
60
|
+
return { type: 'blankline', header: '', props: {}, synthetic: true };
|
|
61
|
+
}
|
|
61
62
|
return {
|
|
62
63
|
type: 'comment',
|
|
63
|
-
header:
|
|
64
|
+
header: fragment.join('\n'),
|
|
64
65
|
props: {},
|
|
65
66
|
synthetic: true,
|
|
66
67
|
};
|
|
67
68
|
}
|
|
68
69
|
const splitFirstLine = firstLine.split(' ');
|
|
69
|
-
if (
|
|
70
|
-
let type =
|
|
70
|
+
if (directiveInfo.date) {
|
|
71
|
+
let type = directiveInfo.directive;
|
|
71
72
|
let flag;
|
|
72
73
|
if (type.length === 1) {
|
|
73
74
|
flag = type;
|
|
@@ -79,27 +80,25 @@ export const genericParse = (sourceFragment) => {
|
|
|
79
80
|
type = 'transaction';
|
|
80
81
|
}
|
|
81
82
|
if (type === 'transaction') {
|
|
82
|
-
const date = splitFirstLine[0].trim();
|
|
83
83
|
const [header, ...comment] = splitFirstLine.slice(2).join(' ').split(';');
|
|
84
84
|
return {
|
|
85
85
|
type,
|
|
86
86
|
header: header.trim(),
|
|
87
87
|
body: rest.map((r) => r.trim()),
|
|
88
88
|
props: {
|
|
89
|
-
date,
|
|
89
|
+
date: directiveInfo.date,
|
|
90
90
|
flag,
|
|
91
91
|
comment: comment.length > 0 ? comment.join(';').trim() : undefined,
|
|
92
92
|
},
|
|
93
93
|
};
|
|
94
94
|
}
|
|
95
|
-
const date = splitFirstLine[0].trim();
|
|
96
95
|
const metadata = parseMetadata(rest);
|
|
97
96
|
const [header, ...comment] = splitFirstLine.slice(2).join(' ').split(';');
|
|
98
97
|
return {
|
|
99
98
|
type,
|
|
100
99
|
header: header.trim(),
|
|
101
100
|
props: {
|
|
102
|
-
date,
|
|
101
|
+
date: directiveInfo.date,
|
|
103
102
|
metadata,
|
|
104
103
|
comment: comment.length > 0 ? comment.join(';').trim() : undefined,
|
|
105
104
|
},
|
|
@@ -107,7 +106,7 @@ export const genericParse = (sourceFragment) => {
|
|
|
107
106
|
}
|
|
108
107
|
const [header, ...comment] = splitFirstLine.slice(1).join(' ').split(';');
|
|
109
108
|
return {
|
|
110
|
-
type:
|
|
109
|
+
type: directiveInfo.directive,
|
|
111
110
|
header: header.trim(),
|
|
112
111
|
props: {
|
|
113
112
|
metadata: parseMetadata(rest),
|
package/build/src/main.d.mts
CHANGED
|
@@ -27,7 +27,7 @@ export { deserializeNode, deserializeNodeFromString, deserializeNodes, deseriali
|
|
|
27
27
|
export { parseFile, type ParseFileOptions, type FileSystemHelpers, } from './parseFile.mjs';
|
|
28
28
|
export type { GenericParseResult, GenericParseResultWithDate, GenericParseResultTransaction, } from './genericParse.mjs';
|
|
29
29
|
export type { Metadata } from './utils/parseMetadata.mjs';
|
|
30
|
-
export { BeancountParseError, type SourceLocation, type SourceFragmentWithLocation, } from './utils/SourceLocation.mjs';
|
|
30
|
+
export { BeancountParseError, type DirectiveInfo, type SourceLocation, type SourceFragmentWithLocation, type SourceFragmentWithLocationDirective, type SourceFragmentWithLocationNonDirective, } from './utils/SourceLocation.mjs';
|
|
31
31
|
export { ParseResult, type ParseResultObj, type FormatOptions, type CalculateCurrencyColumnOptions, } from './classes/ParseResult.mjs';
|
|
32
32
|
export { Node, assertNodeConstructor } from './classes/Node.mjs';
|
|
33
33
|
export { DatedNode } from './classes/DatedNode.mjs';
|
package/build/src/parse.d.mts
CHANGED
|
@@ -12,7 +12,7 @@ import { type SourceFragmentWithLocation } from './utils/SourceLocation.mjs';
|
|
|
12
12
|
* @param fragmentWithLocation - Source fragment with location metadata
|
|
13
13
|
* @returns A Node instance
|
|
14
14
|
*/
|
|
15
|
-
export declare const parseSourceFragment: (fragmentWithLocation: SourceFragmentWithLocation) =>
|
|
15
|
+
export declare const parseSourceFragment: (fragmentWithLocation: SourceFragmentWithLocation) => import("./classes/nodes/index.mjs").Transaction | import("./classes/nodes/Balance.mjs").Balance | Blankline | import("./classes/nodes/Close.mjs").Close | Comment | import("./classes/nodes/Commodity.mjs").Commodity | import("./classes/nodes/Custom.mjs").Custom | import("./classes/nodes/Document.mjs").Document | import("./classes/nodes/Event.mjs").Event | import("./classes/nodes/Include.mjs").Include | import("./classes/nodes/Note.mjs").Note | import("./classes/nodes/Open.mjs").Open | import("./classes/nodes/Option.mjs").Option | import("./classes/nodes/Pad.mjs").Pad | import("./classes/nodes/Plugin.mjs").Plugin | import("./classes/nodes/Price.mjs").Price | import("./classes/nodes/Poptag.mjs").Poptag | import("./classes/nodes/Pushtag.mjs").Pushtag | import("./classes/nodes/Query.mjs").Query;
|
|
16
16
|
/**
|
|
17
17
|
* Parses a complete Beancount file string into a ParseResult containing Node objects.
|
|
18
18
|
*
|
package/build/src/parse.mjs
CHANGED
|
@@ -19,7 +19,7 @@ export const parseSourceFragment = (fragmentWithLocation) => {
|
|
|
19
19
|
const { fragment, location } = fragmentWithLocation;
|
|
20
20
|
let nodeType;
|
|
21
21
|
try {
|
|
22
|
-
const genericParseResult = genericParse(
|
|
22
|
+
const genericParseResult = genericParse(fragmentWithLocation);
|
|
23
23
|
const { type } = genericParseResult;
|
|
24
24
|
nodeType = type;
|
|
25
25
|
if (genericParseResult.synthetic) {
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Information about a parsed directive
|
|
3
|
+
*/
|
|
4
|
+
export interface DirectiveInfo {
|
|
5
|
+
date?: string;
|
|
6
|
+
directive: string;
|
|
7
|
+
}
|
|
1
8
|
/**
|
|
2
9
|
* Location information for a fragment of source code
|
|
3
10
|
*/
|
|
@@ -9,15 +16,30 @@ export interface SourceLocation {
|
|
|
9
16
|
/** Optional file path */
|
|
10
17
|
filePath?: string;
|
|
11
18
|
}
|
|
12
|
-
|
|
13
|
-
* A source fragment with associated location metadata
|
|
14
|
-
*/
|
|
15
|
-
export interface SourceFragmentWithLocation {
|
|
19
|
+
interface SourceFragmentWithLocationBase {
|
|
16
20
|
/** The lines of source code */
|
|
17
21
|
fragment: string[];
|
|
18
22
|
/** Location information */
|
|
19
23
|
location: SourceLocation;
|
|
20
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* A source fragment identified as a directive
|
|
27
|
+
*/
|
|
28
|
+
export interface SourceFragmentWithLocationDirective extends SourceFragmentWithLocationBase {
|
|
29
|
+
isDirective: true;
|
|
30
|
+
directiveInfo: DirectiveInfo;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A source fragment that is not a directive (e.g. a comment)
|
|
34
|
+
*/
|
|
35
|
+
export interface SourceFragmentWithLocationNonDirective extends SourceFragmentWithLocationBase {
|
|
36
|
+
isDirective: false;
|
|
37
|
+
directiveInfo: undefined;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* A source fragment with associated location metadata
|
|
41
|
+
*/
|
|
42
|
+
export type SourceFragmentWithLocation = SourceFragmentWithLocationDirective | SourceFragmentWithLocationNonDirective;
|
|
21
43
|
/**
|
|
22
44
|
* Custom error class for beancount parsing errors with location context
|
|
23
45
|
*/
|
|
@@ -70,3 +92,4 @@ export declare class BeancountParseError extends Error {
|
|
|
70
92
|
*/
|
|
71
93
|
toString(): string;
|
|
72
94
|
}
|
|
95
|
+
export {};
|
|
@@ -21,7 +21,6 @@ export const splitStringIntoSourceFragments = (source) => {
|
|
|
21
21
|
// split up the file into source fragments with line tracking
|
|
22
22
|
let inFragment = false;
|
|
23
23
|
let inString = false;
|
|
24
|
-
let isDirectiveFragment = false;
|
|
25
24
|
const fragmentsWithLines = lines.reduce((acc, line, index) => {
|
|
26
25
|
const lineNumber = index + 1; // 1-based line numbers
|
|
27
26
|
if (!inString) {
|
|
@@ -34,34 +33,55 @@ export const splitStringIntoSourceFragments = (source) => {
|
|
|
34
33
|
inFragment = false;
|
|
35
34
|
}
|
|
36
35
|
if (!inFragment) {
|
|
37
|
-
acc.push({ lines: [], startLine: lineNumber });
|
|
38
36
|
inFragment = true;
|
|
39
|
-
|
|
37
|
+
const fragmentInfo = beanCountDirectiveRegex.exec(line);
|
|
38
|
+
if (!fragmentInfo) {
|
|
39
|
+
acc.push({
|
|
40
|
+
lines: [],
|
|
41
|
+
startLine: lineNumber,
|
|
42
|
+
isDirective: false,
|
|
43
|
+
directiveInfo: undefined,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
acc.push({
|
|
48
|
+
lines: [],
|
|
49
|
+
startLine: lineNumber,
|
|
50
|
+
isDirective: true,
|
|
51
|
+
directiveInfo: {
|
|
52
|
+
date: fragmentInfo.groups.date,
|
|
53
|
+
directive: fragmentInfo.groups.dated_directive ??
|
|
54
|
+
fragmentInfo.groups.non_dated_directive,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
}
|
|
40
58
|
}
|
|
41
59
|
}
|
|
42
|
-
acc[acc.length - 1]
|
|
60
|
+
const currentFragment = acc[acc.length - 1];
|
|
61
|
+
currentFragment.lines.push(line);
|
|
43
62
|
// After a blank line, ensure next line starts a new fragment
|
|
44
63
|
if (!inString && line.trim() === '') {
|
|
45
64
|
inFragment = false;
|
|
46
65
|
}
|
|
47
66
|
// odd number of ", we're in an unclosed string
|
|
48
|
-
if (
|
|
67
|
+
if (currentFragment.isDirective && countChar(line, '"') % 2 === 1) {
|
|
49
68
|
inString = !inString;
|
|
50
69
|
}
|
|
51
70
|
return acc;
|
|
52
71
|
}, []);
|
|
53
|
-
return fragmentsWithLines.map(({ lines, startLine }) => {
|
|
72
|
+
return fragmentsWithLines.map(({ lines, startLine, isDirective, directiveInfo }) => {
|
|
54
73
|
const location = {
|
|
55
74
|
startLine,
|
|
56
75
|
endLine: startLine + lines.length - 1,
|
|
57
76
|
};
|
|
58
77
|
// Comment fragments (non-directives) may contain unbalanced quotes,
|
|
59
78
|
// so skip string-aware splitting for them.
|
|
60
|
-
|
|
61
|
-
if (!beanCountDirectiveRegex.test(firstLine)) {
|
|
79
|
+
if (!isDirective) {
|
|
62
80
|
return {
|
|
63
81
|
fragment: lines,
|
|
64
82
|
location,
|
|
83
|
+
isDirective: false,
|
|
84
|
+
directiveInfo: undefined,
|
|
65
85
|
};
|
|
66
86
|
}
|
|
67
87
|
try {
|
|
@@ -69,6 +89,8 @@ export const splitStringIntoSourceFragments = (source) => {
|
|
|
69
89
|
return {
|
|
70
90
|
fragment: splitLines,
|
|
71
91
|
location,
|
|
92
|
+
isDirective: true,
|
|
93
|
+
directiveInfo,
|
|
72
94
|
};
|
|
73
95
|
}
|
|
74
96
|
catch (error) {
|