yaml-eslint-parser
Advanced tools
Comparing version 0.5.0 to 1.0.0-beta.0
@@ -45,7 +45,21 @@ export declare type Range = [number, number]; | ||
} | ||
export interface YAMLDirective extends BaseYAMLNode { | ||
interface BaseYAMLDirective extends BaseYAMLNode { | ||
type: "YAMLDirective"; | ||
value: string; | ||
kind: "YAML" | "TAG" | null; | ||
parent: YAMLDocument; | ||
} | ||
export interface YAMLDirectiveForYAML extends BaseYAMLDirective { | ||
kind: "YAML"; | ||
version: string; | ||
} | ||
export interface YAMLDirectiveForTAG extends BaseYAMLDirective { | ||
kind: "TAG"; | ||
handle: string; | ||
prefix: string; | ||
} | ||
export interface YAMLDirectiveForUnknown extends BaseYAMLDirective { | ||
kind: null; | ||
} | ||
export declare type YAMLDirective = YAMLDirectiveForYAML | YAMLDirectiveForTAG | YAMLDirectiveForUnknown; | ||
export interface YAMLWithMeta extends BaseYAMLNode { | ||
@@ -66,2 +80,3 @@ type: "YAMLWithMeta"; | ||
tag: string; | ||
raw: string; | ||
parent: YAMLWithMeta; | ||
@@ -68,0 +83,0 @@ } |
@@ -1,7 +0,4 @@ | ||
import type { Comment, Locations, Range, Token, YAMLProgram } from "./ast"; | ||
import type { ASTNode } from "./yaml"; | ||
declare type CSTRangeData = { | ||
start: number; | ||
end: number; | ||
}; | ||
import type { Comment, Locations, Range, Token } from "./ast"; | ||
import type { CST } from "yaml"; | ||
import { ParseError } from "."; | ||
export declare class Context { | ||
@@ -11,8 +8,5 @@ readonly code: string; | ||
readonly comments: Comment[]; | ||
hasCR: boolean; | ||
private readonly locs; | ||
private readonly locsMap; | ||
private readonly crs; | ||
constructor(origCode: string); | ||
remapCR(ast: YAMLProgram): void; | ||
getLocFromIndex(index: number): { | ||
@@ -23,13 +17,5 @@ line: number; | ||
/** | ||
* Get the location information of the given node. | ||
* @param node The node. | ||
* Get the location information of the given range. | ||
*/ | ||
getConvertLocation(node: { | ||
range: Range; | ||
} | ASTNode): Locations; | ||
/** | ||
* Get the location information of the given CSTRange. | ||
* @param node The node. | ||
*/ | ||
getConvertLocationFromCSTRange(range: CSTRangeData | undefined | null): Locations; | ||
getConvertLocation(start: number, end: number): Locations; | ||
addComment(comment: Comment): void; | ||
@@ -39,4 +25,9 @@ /** | ||
*/ | ||
addToken(type: Token["type"], range: Range): Token; | ||
addToken(type: Token["type"], range: Readonly<Range>): Token; | ||
throwUnexpectedTokenError(cst: CST.Token | Token): ParseError; | ||
throwError(message: string, cst: CST.Token | Token | number): ParseError; | ||
/** | ||
* Gets the last index with whitespace skipped. | ||
*/ | ||
lastSkipSpaces(startIndex: number, endIndex: number): number; | ||
} | ||
export {}; |
@@ -8,3 +8,3 @@ "use strict"; | ||
const lodash_1 = __importDefault(require("lodash")); | ||
const traverse_1 = require("./traverse"); | ||
const _1 = require("."); | ||
class Context { | ||
@@ -14,70 +14,21 @@ constructor(origCode) { | ||
this.comments = []; | ||
this.hasCR = false; | ||
this.locsMap = new Map(); | ||
const len = origCode.length; | ||
const lineStartIndices = [0]; | ||
const crs = []; | ||
let code = ""; | ||
for (let index = 0; index < len;) { | ||
const c = origCode[index++]; | ||
if (c === "\r") { | ||
const next = origCode[index++] || ""; | ||
const next = origCode[index]; | ||
if (next === "\n") { | ||
code += next; | ||
crs.push(index - 2); | ||
index++; | ||
} | ||
else { | ||
code += `\n${next}`; | ||
} | ||
lineStartIndices.push(code.length); | ||
lineStartIndices.push(index); | ||
} | ||
else { | ||
code += c; | ||
if (c === "\n") { | ||
lineStartIndices.push(code.length); | ||
} | ||
else if (c === "\n") { | ||
lineStartIndices.push(index); | ||
} | ||
} | ||
this.code = code; | ||
this.code = origCode; | ||
this.locs = new LinesAndColumns(lineStartIndices); | ||
this.hasCR = Boolean(crs.length); | ||
this.crs = crs; | ||
} | ||
remapCR(ast) { | ||
const cache = {}; | ||
const remapIndex = (index) => { | ||
let result = cache[index]; | ||
if (result != null) { | ||
return result; | ||
} | ||
result = index; | ||
for (const cr of this.crs) { | ||
if (cr < result) { | ||
result++; | ||
} | ||
else { | ||
break; | ||
} | ||
} | ||
return (cache[index] = result); | ||
}; | ||
// eslint-disable-next-line func-style -- ignore | ||
const remapRange = (range) => { | ||
return [remapIndex(range[0]), remapIndex(range[1])]; | ||
}; | ||
(0, traverse_1.traverseNodes)(ast, { | ||
enterNode(node) { | ||
node.range = remapRange(node.range); | ||
}, | ||
leaveNode() { | ||
// ignore | ||
}, | ||
}); | ||
for (const token of ast.tokens) { | ||
token.range = remapRange(token.range); | ||
} | ||
for (const comment of ast.comments) { | ||
comment.range = remapRange(comment.range); | ||
} | ||
} | ||
getLocFromIndex(index) { | ||
@@ -95,7 +46,5 @@ let loc = this.locsMap.get(index); | ||
/** | ||
* Get the location information of the given node. | ||
* @param node The node. | ||
* Get the location information of the given range. | ||
*/ | ||
getConvertLocation(node) { | ||
const [start, end] = node.range; | ||
getConvertLocation(start, end) { | ||
return { | ||
@@ -109,9 +58,2 @@ range: [start, end], | ||
} | ||
/** | ||
* Get the location information of the given CSTRange. | ||
* @param node The node. | ||
*/ | ||
getConvertLocationFromCSTRange(range) { | ||
return this.getConvertLocation({ range: [range.start, range.end] }); | ||
} | ||
addComment(comment) { | ||
@@ -124,6 +66,32 @@ this.comments.push(comment); | ||
addToken(type, range) { | ||
const token = Object.assign({ type, value: this.code.slice(...range) }, this.getConvertLocation({ range })); | ||
const token = Object.assign({ type, value: this.code.slice(...range) }, this.getConvertLocation(...range)); | ||
this.tokens.push(token); | ||
return token; | ||
} | ||
/* istanbul ignore next */ | ||
throwUnexpectedTokenError(cst) { | ||
const token = "source" in cst ? `'${cst.source}'` : cst.type; | ||
throw this.throwError(`Unexpected token: ${token}`, cst); | ||
} | ||
throwError(message, cst) { | ||
const offset = typeof cst === "number" | ||
? cst | ||
: "offset" in cst | ||
? cst.offset | ||
: cst.range[0]; | ||
const loc = this.getLocFromIndex(offset); | ||
throw new _1.ParseError(message, offset, loc.line, loc.column); | ||
} | ||
/** | ||
* Gets the last index with whitespace skipped. | ||
*/ | ||
lastSkipSpaces(startIndex, endIndex) { | ||
const str = this.code; | ||
for (let index = endIndex - 1; index >= startIndex; index--) { | ||
if (str[index].trim()) { | ||
return index + 1; | ||
} | ||
} | ||
return startIndex; | ||
} | ||
} | ||
@@ -130,0 +98,0 @@ exports.Context = Context; |
import type { YAMLProgram } from "./ast"; | ||
import type { ASTDocument } from "./yaml"; | ||
import type { Context } from "./context"; | ||
import type { CST, Document } from "yaml"; | ||
/** | ||
* Convert yaml root to YAMLProgram | ||
*/ | ||
export declare function convertRoot(documents: ASTDocument[], ctx: Context): YAMLProgram; | ||
export declare function convertRoot(cstNodes: CST.Token[], nodes: Document.Parsed[], ctx: Context): YAMLProgram; |
1356
lib/convert.js
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.convertRoot = void 0; | ||
const yaml_1 = require("./yaml"); | ||
const errors_1 = require("./errors"); | ||
const tags_1 = require("./tags"); | ||
const utils_1 = require("./utils"); | ||
const CHOMPING_MAP = { | ||
CLIP: "clip", | ||
STRIP: "strip", | ||
KEEP: "keep", | ||
}; | ||
const yaml_1 = require("yaml"); | ||
const isPair = yaml_1.isPair; | ||
class PreTokens { | ||
constructor(array, ctx) { | ||
this.index = 0; | ||
this.array = array; | ||
this.ctx = ctx; | ||
} | ||
first() { | ||
let cst; | ||
while ((cst = this.array[this.index])) { | ||
if (processCommentOrSpace(cst, this.ctx)) { | ||
this.index++; | ||
continue; | ||
} | ||
return cst; | ||
} | ||
return null; | ||
} | ||
consume() { | ||
const cst = this.first(); | ||
if (cst) { | ||
this.index++; | ||
} | ||
return cst; | ||
} | ||
back() { | ||
this.index--; | ||
} | ||
each(callback) { | ||
let cst; | ||
while ((cst = this.consume())) { | ||
callback(cst); | ||
} | ||
} | ||
} | ||
/** Checks whether the give cst node is plain scaler */ | ||
function isPlainScalarCST(cst) { | ||
return cst.type === "scalar"; | ||
} | ||
/** Checks whether the give cst node is double-quoted-scalar */ | ||
function isDoubleQuotedScalarCST(cst) { | ||
return cst.type === "double-quoted-scalar"; | ||
} | ||
/** Checks whether the give cst node is single-quoted-scalar */ | ||
function isSingleQuotedScalarCST(cst) { | ||
return cst.type === "single-quoted-scalar"; | ||
} | ||
/** Checks whether the give cst node is alias scalar */ | ||
function isAliasScalarCST(cst) { | ||
return cst.type === "alias"; | ||
} | ||
/** Checks whether the give cst node is anchor */ | ||
function isAnchorCST(cst) { | ||
return cst.type === "anchor"; | ||
} | ||
/** Checks whether the give cst node is tag */ | ||
function isTagCST(cst) { | ||
return cst.type === "tag"; | ||
} | ||
/** Get node type name */ | ||
function getNodeType(node) { | ||
/* istanbul ignore next */ | ||
return (0, yaml_1.isMap)(node) | ||
? "MAP" | ||
: (0, yaml_1.isSeq)(node) | ||
? "SEQ" | ||
: (0, yaml_1.isScalar)(node) | ||
? "SCALAR" | ||
: (0, yaml_1.isAlias)(node) | ||
? "ALIAS" | ||
: isPair(node) | ||
? "PAIR" | ||
: (0, yaml_1.isDocument)(node) | ||
? "DOCUMENT" | ||
: "unknown"; | ||
} | ||
/** | ||
* Convert yaml root to YAMLProgram | ||
*/ | ||
function convertRoot(documents, ctx) { | ||
const ast = Object.assign({ type: "Program", body: [], comments: ctx.comments, sourceType: "module", tokens: ctx.tokens, parent: null }, ctx.getConvertLocation({ range: [0, ctx.code.length] })); | ||
let startIndex = 0; | ||
for (const n of documents) { | ||
const doc = convertDocument(n, ctx, ast, startIndex); | ||
ast.body.push(doc); | ||
startIndex = doc.range[1]; | ||
} | ||
const useRanges = sort([...ctx.tokens, ...ctx.comments]).map((t) => t.range); | ||
let range = useRanges.shift(); | ||
for (let index = 0; index < ctx.code.length; index++) { | ||
while (range && range[1] <= index) { | ||
range = useRanges.shift(); | ||
function convertRoot(cstNodes, nodes, ctx) { | ||
var _a; | ||
const ast = Object.assign({ type: "Program", body: [], comments: ctx.comments, sourceType: "module", tokens: ctx.tokens, parent: null }, ctx.getConvertLocation(0, ctx.code.length)); | ||
let directives = []; | ||
let bufferDoc = null; | ||
const cstDocs = []; | ||
for (const n of cstNodes) { | ||
if (processCommentOrSpace(n, ctx)) { | ||
continue; | ||
} | ||
if (range && range[0] <= index) { | ||
index = range[1] - 1; | ||
if (n.type === "doc-end") { | ||
/* istanbul ignore if */ | ||
if (!bufferDoc) { | ||
throw ctx.throwUnexpectedTokenError(n); | ||
} | ||
bufferDoc.docEnd = n; | ||
cstDocs.push(bufferDoc); | ||
bufferDoc = null; | ||
(_a = n.end) === null || _a === void 0 ? void 0 : _a.forEach((t) => processAnyToken(t, ctx)); | ||
continue; | ||
} | ||
const c = ctx.code[index]; | ||
if (isPunctuator(c)) { | ||
// console.log("*** REM TOKEN ***") | ||
ctx.addToken("Punctuator", [index, index + 1]); | ||
if (bufferDoc) { | ||
cstDocs.push(bufferDoc); | ||
bufferDoc = null; | ||
} | ||
else if (c.trim()) { | ||
// console.log("*** REM TOKEN ***") | ||
// unknown | ||
ctx.addToken("Identifier", [index, index + 1]); | ||
if (n.type === "directive") { | ||
directives.push(n); | ||
continue; | ||
} | ||
if (n.type === "document") { | ||
bufferDoc = { | ||
doc: n, | ||
directives, | ||
}; | ||
directives = []; | ||
continue; | ||
} | ||
/* istanbul ignore next */ | ||
throw ctx.throwUnexpectedTokenError(n); | ||
} | ||
if (bufferDoc) { | ||
cstDocs.push(bufferDoc); | ||
bufferDoc = null; | ||
} | ||
if (cstDocs.length > 0) { | ||
let startIndex = 0; | ||
ast.body = cstDocs.map((doc, index) => { | ||
const result = convertDocument(doc, nodes[index], ctx, ast, startIndex); | ||
startIndex = result.range[1]; | ||
return result; | ||
}); | ||
} | ||
else { | ||
const index = skipSpaces(ctx.code, 0); | ||
ast.body.push(Object.assign({ type: "YAMLDocument", directives: [], content: null, parent: ast, anchors: {} }, ctx.getConvertLocation(index, index))); | ||
} | ||
sort(ctx.comments); | ||
sort(ctx.tokens); | ||
const lastBody = ast.body[ast.body.length - 1]; | ||
if (lastBody) { | ||
adjustEndLoc(lastBody, ctx.comments[ctx.comments.length - 1]); | ||
} | ||
return ast; | ||
/** | ||
* Checks if the given char is punctuator | ||
*/ | ||
function isPunctuator(c) { | ||
return (c === ":" || | ||
c === "-" || | ||
c === "," || | ||
c === "{" || | ||
c === "}" || | ||
c === "[" || | ||
c === "]" || | ||
// | ||
c === "?"); | ||
} | ||
} | ||
@@ -67,37 +154,27 @@ exports.convertRoot = convertRoot; | ||
*/ | ||
function convertDocument(node, ctx, parent, startIndex) { | ||
const cst = node.cstNode; | ||
if (cst.error) { | ||
const range = cst.range || cst.valueRange; | ||
const loc = ctx.getLocFromIndex(range.start); | ||
throw new errors_1.ParseError(cst.error.message, range.start, loc.line, loc.column); | ||
function convertDocument({ directives, doc, docEnd }, node, ctx, parent, startIndex) { | ||
const loc = ctx.getConvertLocation(skipSpaces(ctx.code, startIndex), node.range[1]); | ||
const ast = Object.assign({ type: "YAMLDocument", directives: [], content: null, parent, anchors: {} }, loc); | ||
ast.directives.push(...convertDocumentHead(node.directives, directives, ctx, ast)); | ||
let last = ast.directives[ast.directives.length - 1]; | ||
const startTokens = new PreTokens(doc.start, ctx); | ||
let t; | ||
while ((t = startTokens.consume())) { | ||
if (t.type === "doc-start") { | ||
last = ctx.addToken("Marker", toRange(t)); | ||
continue; | ||
} | ||
startTokens.back(); | ||
break; | ||
} | ||
for (const error of node.errors) { | ||
throw error; | ||
ast.content = convertDocumentBody(startTokens, doc.value || null, node.contents, ctx, ast); | ||
last = ast.content || last; | ||
if (doc.end) { | ||
doc.end.forEach((token) => processAnyToken(token, ctx)); | ||
} | ||
const loc = ctx.getConvertLocation({ | ||
range: [skipSpaces(ctx.code, startIndex), node.range[1]], | ||
}); | ||
const ast = Object.assign({ type: "YAMLDocument", directives: [], content: null, parent, anchors: {} }, loc); | ||
ast.directives.push(...convertDocumentHead(node, ctx, ast)); | ||
// Marker | ||
// @ts-expect-error -- missing types? | ||
const directivesEndMarker = cst.directivesEndMarker; | ||
if (directivesEndMarker) { | ||
const range = [ | ||
directivesEndMarker.start, | ||
directivesEndMarker.end, | ||
]; | ||
ctx.addToken("Marker", range); | ||
if (docEnd) { | ||
last = ctx.addToken("Marker", toRange(docEnd)); | ||
} | ||
ast.content = convertDocumentBody(node, ctx, ast); | ||
// Marker | ||
// @ts-expect-error -- missing types? | ||
const documentEndMarker = cst.documentEndMarker; | ||
if (documentEndMarker) { | ||
const range = [documentEndMarker.start, documentEndMarker.end]; | ||
const markerToken = ctx.addToken("Marker", range); | ||
ast.range[1] = markerToken.range[1]; | ||
ast.loc.end = clone(markerToken.loc.end); | ||
} | ||
adjustEndLoc(ast, last); | ||
return ast; | ||
@@ -108,8 +185,5 @@ } | ||
*/ | ||
function* convertDocumentHead(node, ctx, parent) { | ||
const cst = node.cstNode; | ||
for (const n of cst.directives) { | ||
if (processComment(n, ctx)) { | ||
yield convertDirective(n, ctx, parent); | ||
} | ||
function* convertDocumentHead(node, directives, ctx, parent) { | ||
for (const n of directives) { | ||
yield convertDirective(node, n, ctx, parent); | ||
} | ||
@@ -120,13 +194,20 @@ } | ||
*/ | ||
function convertDirective(node, ctx, parent) { | ||
extractComment(node, ctx); | ||
const loc = ctx.getConvertLocation({ | ||
range: [ | ||
node.range.start, | ||
lastSkipSpaces(ctx.code, node.range.start, node.valueRange.end), | ||
], | ||
}); | ||
function convertDirective(node, cst, ctx, parent) { | ||
const loc = ctx.getConvertLocation(...toRange(cst)); | ||
const value = ctx.code.slice(...loc.range); | ||
const ast = Object.assign({ type: "YAMLDirective", value, | ||
parent }, loc); | ||
const parts = cst.source.trim().split(/[\t ]+/); | ||
const name = parts.shift(); | ||
let ast; | ||
if (name === "%YAML") { | ||
ast = Object.assign({ type: "YAMLDirective", value, kind: "YAML", version: node.yaml.version, parent }, loc); | ||
} | ||
else if (name === "%TAG") { | ||
const [handle, prefix] = parts; | ||
ast = Object.assign({ type: "YAMLDirective", value, kind: "TAG", handle, | ||
prefix, | ||
parent }, loc); | ||
} | ||
else { | ||
ast = Object.assign({ type: "YAMLDirective", value, kind: null, parent }, loc); | ||
} | ||
ctx.addToken("Directive", loc.range); | ||
@@ -138,112 +219,352 @@ return ast; | ||
*/ | ||
function convertDocumentBody(node, ctx, parent) { | ||
let ast = null; | ||
for (const content of node.cstNode.contents) { | ||
if (processComment(content, ctx) && !ast) { | ||
ast = convertContentNode(node.contents, ctx, parent, parent); | ||
} | ||
function convertDocumentBody(preTokens, cst, node, ctx, parent) { | ||
if (cst) { | ||
return convertContentNode(preTokens, cst, node, ctx, parent, parent); | ||
} | ||
return ast; | ||
const token = preTokens.first(); | ||
/* istanbul ignore if */ | ||
if (token) { | ||
throw ctx.throwUnexpectedTokenError(token); | ||
} | ||
return null; | ||
} | ||
/* eslint-disable complexity -- X */ | ||
/** | ||
* Convert ContentNode to YAMLContent | ||
*/ | ||
function convertContentNode(node, ctx, parent, doc) { | ||
if (node.type === yaml_1.Type.MAP) { | ||
return convertMapping(node, ctx, parent, doc); | ||
function convertContentNode( | ||
/* eslint-enable complexity -- X */ | ||
preTokens, cst, node, ctx, parent, doc) { | ||
var _a; | ||
/* istanbul ignore if */ | ||
if (!node) { | ||
throw ctx.throwError(`unknown error: AST is null. Unable to process content CST (${cst.type}).`, cst); | ||
} | ||
if (node.type === yaml_1.Type.FLOW_MAP) { | ||
return convertFlowMapping(node, ctx, parent, doc); | ||
/* istanbul ignore if */ | ||
if (node.srcToken !== cst) { | ||
throw ctx.throwError(`unknown error: CST is mismatched. Unable to process content CST (${cst.type}: ${(_a = node.srcToken) === null || _a === void 0 ? void 0 : _a.type}).`, cst); | ||
} | ||
if (node.type === yaml_1.Type.SEQ) { | ||
return convertSequence(node, ctx, parent, doc); | ||
if (cst.type === "block-scalar") { | ||
/* istanbul ignore if */ | ||
if (!(0, yaml_1.isScalar)(node)) { | ||
throw ctx.throwError(`unknown error: AST is not Scalar (${getNodeType(node)}). Unable to process Scalar CST.`, cst); | ||
} | ||
return convertBlockScalar(preTokens, cst, node, ctx, parent, doc); | ||
} | ||
if (node.type === yaml_1.Type.FLOW_SEQ) { | ||
return convertFlowSequence(node, ctx, parent, doc); | ||
if (cst.type === "block-seq") { | ||
/* istanbul ignore if */ | ||
if (!(0, yaml_1.isSeq)(node)) { | ||
throw ctx.throwError(`unknown error: AST is not Seq (${getNodeType(node)}). Unable to process Seq CST.`, cst); | ||
} | ||
return convertSequence(preTokens, cst, node, ctx, parent, doc); | ||
} | ||
if (node.type === yaml_1.Type.PLAIN) { | ||
return convertPlain(node, ctx, parent, doc); | ||
if (cst.type === "block-map") { | ||
/* istanbul ignore if */ | ||
if (!(0, yaml_1.isMap)(node)) { | ||
throw ctx.throwError(`unknown error: AST is not Map and Pair (${getNodeType(node)}). Unable to process Map CST.`, cst); | ||
} | ||
return convertMapping(preTokens, cst, node, ctx, parent, doc); | ||
} | ||
if (node.type === yaml_1.Type.QUOTE_DOUBLE) { | ||
return convertQuoteDouble(node, ctx, parent, doc); | ||
if (cst.type === "flow-collection") { | ||
return convertFlowCollection(preTokens, cst, node, ctx, parent, doc); | ||
} | ||
if (node.type === yaml_1.Type.QUOTE_SINGLE) { | ||
return convertQuoteSingle(node, ctx, parent, doc); | ||
if (isPlainScalarCST(cst)) { | ||
/* istanbul ignore if */ | ||
if (!(0, yaml_1.isScalar)(node)) { | ||
throw ctx.throwError(`unknown error: AST is not Scalar (${getNodeType(node)}). Unable to process Scalar CST.`, cst); | ||
} | ||
return convertPlain(preTokens, cst, node, ctx, parent, doc); | ||
} | ||
if (node.type === yaml_1.Type.BLOCK_LITERAL) { | ||
return convertBlockLiteral(node, ctx, parent, doc); | ||
if (isDoubleQuotedScalarCST(cst)) { | ||
/* istanbul ignore if */ | ||
if (!(0, yaml_1.isScalar)(node)) { | ||
throw ctx.throwError(`unknown error: AST is not Scalar (${getNodeType(node)}). Unable to process Scalar CST.`, cst); | ||
} | ||
return convertQuoteDouble(preTokens, cst, node, ctx, parent, doc); | ||
} | ||
if (node.type === yaml_1.Type.BLOCK_FOLDED) { | ||
return convertBlockFolded(node, ctx, parent, doc); | ||
if (isSingleQuotedScalarCST(cst)) { | ||
/* istanbul ignore if */ | ||
if (!(0, yaml_1.isScalar)(node)) { | ||
throw ctx.throwError(`unknown error: AST is not Scalar (${getNodeType(node)}). Unable to process Scalar CST.`, cst); | ||
} | ||
return convertQuoteSingle(preTokens, cst, node, ctx, parent, doc); | ||
} | ||
if (node.type === yaml_1.Type.ALIAS) { | ||
return convertAlias(node, ctx, parent, doc); | ||
if (isAliasScalarCST(cst)) { | ||
/* istanbul ignore if */ | ||
if (!(0, yaml_1.isAlias)(node)) { | ||
throw ctx.throwError(`unknown error: AST is not Alias (${getNodeType(node)}). Unable to process Alias CST.`, cst); | ||
} | ||
return convertAlias(preTokens, cst, node, ctx, parent, doc); | ||
} | ||
throw new Error(`Unsupported node: ${node.type}`); | ||
/* istanbul ignore next */ | ||
throw new Error(`Unsupported node: ${cst.type}`); | ||
} | ||
/* eslint-disable complexity -- X */ | ||
/** | ||
* Convert Map to YAMLBlockMapping | ||
*/ | ||
function convertMapping(node, ctx, parent, doc) { | ||
const loc = ctx.getConvertLocationFromCSTRange(node.cstNode.valueRange); | ||
function convertMapping( | ||
/* eslint-enable complexity -- X */ | ||
preTokens, cst, node, ctx, parent, doc) { | ||
var _a, _b; | ||
if (isPair(node)) { | ||
/* istanbul ignore if */ | ||
if (node.srcToken !== cst.items[0]) { | ||
throw ctx.throwError(`unknown error: CST is mismatched. Unable to process mapping CST (${cst.type}: "CollectionItem").`, cst); | ||
} | ||
} | ||
else { | ||
/* istanbul ignore if */ | ||
if (node.srcToken !== cst) { | ||
throw ctx.throwError(`unknown error: CST is mismatched. Unable to process mapping CST (${cst.type}: ${(_a = node.srcToken) === null || _a === void 0 ? void 0 : _a.type}).`, cst); | ||
} | ||
} | ||
const loc = ctx.getConvertLocation(cst.offset, cst.offset); | ||
const ast = Object.assign({ type: "YAMLMapping", style: "block", pairs: [], parent }, loc); | ||
const cstPairRanges = processCSTItems(node, ctx); | ||
node.items.forEach((n, index) => { | ||
ast.pairs.push(convertMappingItem(n, cstPairRanges[index], ctx, ast, doc)); | ||
}); | ||
const first = ast.pairs[0]; | ||
if (first && ast.range[0] !== first.range[0]) { | ||
// adjust location | ||
ast.range[0] = first.range[0]; | ||
ast.loc.start = clone(first.loc.start); | ||
const items = getPairs(node); | ||
let firstKeyInd; | ||
let lastKeyInd; | ||
for (const item of cst.items) { | ||
const startTokens = new PreTokens(item.start, ctx); | ||
let token; | ||
let keyInd = null; | ||
while ((token = startTokens.consume())) { | ||
if (token.type === "explicit-key-ind") { | ||
/* istanbul ignore if */ | ||
if (keyInd) { | ||
throw ctx.throwUnexpectedTokenError(token); | ||
} | ||
lastKeyInd = keyInd = ctx.addToken("Punctuator", toRange(token)); | ||
firstKeyInd !== null && firstKeyInd !== void 0 ? firstKeyInd : (firstKeyInd = keyInd); | ||
continue; | ||
} | ||
startTokens.back(); | ||
break; | ||
} | ||
const pair = items.shift(); | ||
if (!pair) { | ||
const t = startTokens.first() || | ||
keyInd || | ||
item.key || | ||
((_b = item.sep) === null || _b === void 0 ? void 0 : _b[0]) || | ||
item.value; | ||
if (!t) { | ||
// trailing spaces | ||
break; | ||
} | ||
/* istanbul ignore next */ | ||
throw ctx.throwUnexpectedTokenError(t); | ||
} | ||
ast.pairs.push(convertMappingItem(keyInd, startTokens, item, pair, ctx, ast, doc)); | ||
} | ||
const last = ast.pairs[ast.pairs.length - 1]; | ||
if (last && ast.range[1] !== last.range[1]) { | ||
// adjust location | ||
ast.range[1] = last.range[1]; | ||
ast.loc.end = clone(last.loc.end); | ||
adjustStartLoc(ast, firstKeyInd); | ||
adjustStartLoc(ast, ast.pairs[0]); | ||
adjustEndLoc(ast, ast.pairs[ast.pairs.length - 1] || lastKeyInd); | ||
if (!(0, yaml_1.isMap)(node)) { | ||
return ast; | ||
} | ||
return convertAnchorAndTag(node, ctx, parent, ast, doc, ast); | ||
return convertAnchorAndTag(preTokens, node, ctx, parent, ast, doc, ast); | ||
} | ||
/** | ||
* Convert FlowCollection to YAMLFlowMapping | ||
*/ | ||
function convertFlowCollection(preTokens, cst, node, ctx, parent, doc) { | ||
if (cst.start.type === "flow-map-start") { | ||
const startToken = ctx.addToken("Punctuator", toRange(cst.start)); | ||
/* istanbul ignore if */ | ||
if (!(0, yaml_1.isMap)(node)) { | ||
throw ctx.throwError(`unknown error: AST is not Map and Pair (${getNodeType(node)}). Unable to process flow map CST.`, cst); | ||
} | ||
return convertFlowMapping(preTokens, startToken, cst, node, ctx, parent, doc); | ||
} | ||
if (cst.start.type === "flow-seq-start") { | ||
const startToken = ctx.addToken("Punctuator", toRange(cst.start)); | ||
/* istanbul ignore if */ | ||
if (!(0, yaml_1.isSeq)(node) || !node.flow) { | ||
throw ctx.throwError(`unknown error: AST is not flow Seq (${getNodeType(node)}). Unable to process flow seq CST.`, cst); | ||
} | ||
return convertFlowSequence(preTokens, startToken, cst, node, ctx, parent, doc); | ||
} | ||
/* istanbul ignore next */ | ||
throw ctx.throwUnexpectedTokenError(cst.start); | ||
} | ||
/* eslint-disable complexity -- X */ | ||
/** | ||
* Convert FlowMap to YAMLFlowMapping | ||
*/ | ||
function convertFlowMapping(node, ctx, parent, doc) { | ||
const loc = ctx.getConvertLocationFromCSTRange(node.cstNode.valueRange); | ||
function convertFlowMapping( | ||
/* eslint-enable complexity -- X */ | ||
preTokens, startToken, cst, node, ctx, parent, doc) { | ||
var _a; | ||
const loc = ctx.getConvertLocation(startToken.range[0], cst.offset); | ||
const ast = Object.assign({ type: "YAMLMapping", style: "flow", pairs: [], parent }, loc); | ||
const cstPairRanges = processCSTItems(node, ctx); | ||
node.items.forEach((n, index) => { | ||
ast.pairs.push(convertMappingItem(n, cstPairRanges[index], ctx, ast, doc)); | ||
}); | ||
return convertAnchorAndTag(node, ctx, parent, ast, doc, ast); | ||
const items = [...node.items]; | ||
let lastToken; | ||
for (const item of cst.items) { | ||
const startTokens = new PreTokens(item.start, ctx); | ||
let token; | ||
let keyInd = null; | ||
while ((token = startTokens.consume())) { | ||
if (token.type === "comma") { | ||
lastToken = ctx.addToken("Punctuator", toRange(token)); | ||
continue; | ||
} | ||
if (token.type === "explicit-key-ind") { | ||
/* istanbul ignore if */ | ||
if (keyInd) { | ||
throw ctx.throwUnexpectedTokenError(token); | ||
} | ||
lastToken = keyInd = ctx.addToken("Punctuator", toRange(token)); | ||
continue; | ||
} | ||
startTokens.back(); | ||
break; | ||
} | ||
const pair = items.shift(); | ||
if (!pair) { | ||
const t = startTokens.first() || | ||
keyInd || | ||
item.key || | ||
((_a = item.sep) === null || _a === void 0 ? void 0 : _a[0]) || | ||
item.value; | ||
if (!t) { | ||
// trailing spaces | ||
break; | ||
} | ||
/* istanbul ignore next */ | ||
throw ctx.throwUnexpectedTokenError(t); | ||
} | ||
ast.pairs.push(convertMappingItem(keyInd, startTokens, item, pair, ctx, ast, doc)); | ||
} | ||
let mapEnd; | ||
for (const token of cst.end) { | ||
if (processCommentOrSpace(token, ctx)) { | ||
continue; | ||
} | ||
if (token.type === "flow-map-end") { | ||
mapEnd = ctx.addToken("Punctuator", toRange(token)); | ||
continue; | ||
} | ||
/* istanbul ignore next */ | ||
throw ctx.throwUnexpectedTokenError(token); | ||
} | ||
adjustEndLoc(ast, mapEnd || ast.pairs[ast.pairs.length - 1] || lastToken); | ||
if (!(0, yaml_1.isMap)(node)) { | ||
return ast; | ||
} | ||
return convertAnchorAndTag(preTokens, node, ctx, parent, ast, doc, ast); | ||
} | ||
/* eslint-disable complexity -- X */ | ||
/** | ||
* Convert Pair to YAMLPair | ||
* Convert FlowSeq to YAMLFlowSequence | ||
*/ | ||
function convertMappingItem(node, cstPairRanges, ctx, parent, doc) { | ||
const loc = ctx.getConvertLocation({ range: cstPairRanges.range }); | ||
const ast = Object.assign({ type: "YAMLPair", key: null, value: null, parent }, loc); | ||
ast.key = convertMappingKey(node.key, ctx, ast, doc); | ||
ast.value = convertMappingValue(node.value, ctx, ast, doc); | ||
if (ast.value) { | ||
if (ast.range[1] !== ast.value.range[1]) { | ||
// adjust location | ||
ast.range[1] = ast.value.range[1]; | ||
ast.loc.end = clone(ast.value.loc.end); | ||
function convertFlowSequence( | ||
/* eslint-enable complexity -- X */ | ||
preTokens, startToken, cst, node, ctx, parent, doc) { | ||
var _a; | ||
const loc = ctx.getConvertLocation(startToken.range[0], cst.offset); | ||
const ast = Object.assign({ type: "YAMLSequence", style: "flow", entries: [], parent }, loc); | ||
let lastToken; | ||
const items = [...node.items]; | ||
for (const item of cst.items) { | ||
const startTokens = new PreTokens(item.start, ctx); | ||
let token; | ||
while ((token = startTokens.consume())) { | ||
if (token.type === "comma") { | ||
lastToken = ctx.addToken("Punctuator", toRange(token)); | ||
continue; | ||
} | ||
startTokens.back(); | ||
break; | ||
} | ||
if (items.length === 0) { | ||
const t = startTokens.first() || item.key || ((_a = item.sep) === null || _a === void 0 ? void 0 : _a[0]) || item.value; | ||
if (!t) { | ||
// trailing spaces or comma | ||
break; | ||
} | ||
/* istanbul ignore next */ | ||
throw ctx.throwUnexpectedTokenError(t); | ||
} | ||
const entry = items.shift(); | ||
if (isPair(entry) || ((item.key || item.sep) && (0, yaml_1.isMap)(entry))) { | ||
ast.entries.push(convertMap(startTokens, item, entry)); | ||
} | ||
else { | ||
ast.entries.push(convertFlowSequenceItem(startTokens, item.value || null, entry || null, ctx, ast, doc, (ast.entries[ast.entries.length - 1] || | ||
lastToken || | ||
startToken).range[1])); | ||
} | ||
} | ||
else if (ast.key) { | ||
if (cstPairRanges.value == null && ast.range[1] !== ast.key.range[1]) { | ||
// adjust location | ||
ast.range[1] = ast.key.range[1]; | ||
ast.loc.end = clone(ast.key.loc.end); | ||
let seqEnd; | ||
for (const token of cst.end) { | ||
if (processCommentOrSpace(token, ctx)) { | ||
continue; | ||
} | ||
if (token.type === "flow-seq-end") { | ||
seqEnd = ctx.addToken("Punctuator", toRange(token)); | ||
continue; | ||
} | ||
/* istanbul ignore next */ | ||
throw ctx.throwUnexpectedTokenError(token); | ||
} | ||
if (ast.key) { | ||
if (ast.key.range[0] < ast.range[0]) { | ||
// adjust location | ||
ast.range[0] = ast.key.range[0]; | ||
ast.loc.start = clone(ast.key.loc.start); | ||
adjustEndLoc(ast, seqEnd || ast.entries[ast.entries.length - 1] || lastToken); | ||
return convertAnchorAndTag(preTokens, node, ctx, parent, ast, doc, ast); | ||
/** Convert CollectionItem to YAMLBlockMapping */ | ||
function convertMap(pairPreTokens, pairCst, entry) { | ||
var _a, _b, _c; | ||
const startTokens = pairPreTokens; | ||
let keyInd = null; | ||
let token; | ||
while ((token = startTokens.consume())) { | ||
if (token.type === "comma") { | ||
ctx.addToken("Punctuator", toRange(token)); | ||
continue; | ||
} | ||
if (token.type === "explicit-key-ind") { | ||
/* istanbul ignore if */ | ||
if (keyInd) { | ||
throw ctx.throwUnexpectedTokenError(token); | ||
} | ||
keyInd = ctx.addToken("Punctuator", toRange(token)); | ||
continue; | ||
} | ||
startTokens.back(); | ||
break; | ||
} | ||
const pairStartToken = (_a = pairCst.key) !== null && _a !== void 0 ? _a : pairCst.sep[0]; | ||
const mapAst = Object.assign({ type: "YAMLMapping", style: "block", pairs: [], parent: ast }, ctx.getConvertLocation((_b = keyInd === null || keyInd === void 0 ? void 0 : keyInd.range[0]) !== null && _b !== void 0 ? _b : pairStartToken.offset, (_c = keyInd === null || keyInd === void 0 ? void 0 : keyInd.range[1]) !== null && _c !== void 0 ? _c : pairStartToken.offset)); | ||
const pair = convertMappingItem(keyInd, startTokens, pairCst, getPairs(entry)[0], ctx, mapAst, doc); | ||
mapAst.pairs.push(pair); | ||
adjustStartLoc(mapAst, keyInd || pair); | ||
adjustEndLoc(mapAst, pair || keyInd); | ||
return mapAst; | ||
} | ||
} | ||
/** | ||
* Convert Pair to YAMLPair | ||
*/ | ||
function convertMappingItem(keyInd, preTokens, cst, node, ctx, parent, doc) { | ||
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; | ||
const start = (_k = (_h = (_e = (_c = (_a = keyInd === null || keyInd === void 0 ? void 0 : keyInd.range[0]) !== null && _a !== void 0 ? _a : (_b = preTokens.first()) === null || _b === void 0 ? void 0 : _b.offset) !== null && _c !== void 0 ? _c : (_d = cst.key) === null || _d === void 0 ? void 0 : _d.offset) !== null && _e !== void 0 ? _e : (_g = (_f = cst.sep) === null || _f === void 0 ? void 0 : _f[0]) === null || _g === void 0 ? void 0 : _g.offset) !== null && _h !== void 0 ? _h : (_j = cst.value) === null || _j === void 0 ? void 0 : _j.offset) !== null && _k !== void 0 ? _k : -1; | ||
const loc = ctx.getConvertLocation(start, start); | ||
const ast = Object.assign({ type: "YAMLPair", key: null, value: null, parent }, loc); | ||
ast.key = convertMappingKey(preTokens, cst.key || null, node.key, ctx, ast, doc, start); | ||
const valueStartTokens = new PreTokens(cst.sep || [], ctx); | ||
let valueInd; | ||
let token; | ||
while ((token = valueStartTokens.consume())) { | ||
if (token.type === "map-value-ind") { | ||
/* istanbul ignore if */ | ||
if (valueInd) { | ||
throw ctx.throwUnexpectedTokenError(token); | ||
} | ||
valueInd = ctx.addToken("Punctuator", toRange(token)); | ||
continue; | ||
} | ||
valueStartTokens.back(); | ||
break; | ||
} | ||
ast.value = convertMappingValue(valueStartTokens, cst.value || null, node.value, ctx, ast, doc, start); | ||
adjustEndLoc(ast, ast.value || valueInd || ast.key || keyInd); | ||
return ast; | ||
@@ -254,7 +575,12 @@ } | ||
*/ | ||
function convertMappingKey(node, ctx, parent, doc) { | ||
if (node && node.type) { | ||
return convertContentNode(node, ctx, parent, doc); | ||
function convertMappingKey(preTokens, cst, node, ctx, parent, doc, indexForError) { | ||
var _a; | ||
if (cst) { | ||
return convertContentNode(preTokens, cst, node, ctx, parent, doc); | ||
} | ||
return null; | ||
/* istanbul ignore if */ | ||
if (!isScalarOrNull(node)) { | ||
throw ctx.throwError(`unknown error: AST is not Scalar and null (${getNodeType(node)}). Unable to process empty map key CST.`, (_a = preTokens.first()) !== null && _a !== void 0 ? _a : indexForError); | ||
} | ||
return convertAnchorAndTag(preTokens, node, ctx, parent, null, doc, null); | ||
} | ||
@@ -264,7 +590,12 @@ /** | ||
*/ | ||
function convertMappingValue(node, ctx, parent, doc) { | ||
if (node) { | ||
return convertContentNode(node, ctx, parent, doc); | ||
function convertMappingValue(preTokens, cst, node, ctx, parent, doc, indexForError) { | ||
var _a; | ||
if (cst) { | ||
return convertContentNode(preTokens, cst, node, ctx, parent, doc); | ||
} | ||
return null; | ||
/* istanbul ignore if */ | ||
if (!isScalarOrNull(node)) { | ||
throw ctx.throwError(`unknown error: AST is not Scalar and null (${getNodeType(node)}). Unable to process empty map value CST.`, (_a = preTokens.first()) !== null && _a !== void 0 ? _a : indexForError); | ||
} | ||
return convertAnchorAndTag(preTokens, node, ctx, parent, null, doc, null); | ||
} | ||
@@ -274,52 +605,37 @@ /** | ||
*/ | ||
function convertSequence(node, ctx, parent, doc) { | ||
const loc = ctx.getConvertLocationFromCSTRange(node.cstNode.valueRange); | ||
function convertSequence(preTokens, cst, node, ctx, parent, doc) { | ||
var _a; | ||
const loc = ctx.getConvertLocation(cst.offset, cst.offset); | ||
const ast = Object.assign({ type: "YAMLSequence", style: "block", entries: [], parent }, loc); | ||
const cstSeqItems = []; | ||
for (const n of node.cstNode.items) { | ||
if (n.type === yaml_1.Type.SEQ_ITEM) { | ||
ctx.addToken("Punctuator", [n.range.start, n.range.start + 1]); | ||
extractComment(n, ctx); | ||
cstSeqItems.push(n); | ||
continue; | ||
const items = [...node.items]; | ||
let lastSeqInd; | ||
for (const item of cst.items) { | ||
const startTokens = new PreTokens(item.start, ctx); | ||
let seqInd; | ||
let token; | ||
while ((token = startTokens.consume())) { | ||
if (token.type === "seq-item-ind") { | ||
/* istanbul ignore if */ | ||
if (seqInd) { | ||
throw ctx.throwUnexpectedTokenError(token); | ||
} | ||
lastSeqInd = seqInd = ctx.addToken("Punctuator", toRange(token)); | ||
continue; | ||
} | ||
startTokens.back(); | ||
break; | ||
} | ||
processComment(n, ctx); | ||
} | ||
node.items.forEach((n, index) => { | ||
ast.entries.push(...convertSequenceItem(n, cstSeqItems[index], ctx, ast, doc)); | ||
}); | ||
const last = ast.entries[ast.entries.length - 1]; | ||
if (last && ast.range[1] !== last.range[1]) { | ||
// adjust location | ||
ast.range[1] = last.range[1]; | ||
ast.loc.end = clone(last.loc.end); | ||
} | ||
return convertAnchorAndTag(node, ctx, parent, ast, doc, ast); | ||
} | ||
/** | ||
* Convert FlowSeq to YAMLFlowSequence | ||
*/ | ||
function convertFlowSequence(node, ctx, parent, doc) { | ||
const loc = ctx.getConvertLocationFromCSTRange(node.cstNode.valueRange); | ||
const ast = Object.assign({ type: "YAMLSequence", style: "flow", entries: [], parent }, loc); | ||
const cstPairRanges = processCSTItems(node, ctx); | ||
node.items.forEach((n, index) => { | ||
if (n.type === yaml_1.PairType.PAIR || n.type === yaml_1.PairType.MERGE_PAIR) { | ||
const p = n; | ||
const cstPairRange = cstPairRanges[index]; | ||
const map = Object.assign({ type: "YAMLMapping", style: "block", pairs: [], parent }, ctx.getConvertLocation({ range: cstPairRange.range })); | ||
const pair = convertMappingItem(p, cstPairRange, ctx, map, doc); | ||
map.pairs.push(pair); | ||
if (pair && map.range[1] !== pair.range[1]) { | ||
// adjust location | ||
map.range[1] = pair.range[1]; | ||
map.loc.end = clone(pair.loc.end); | ||
if (items.length === 0) { | ||
const t = startTokens.first() || item.key || ((_a = item.sep) === null || _a === void 0 ? void 0 : _a[0]) || item.value; | ||
if (!t) { | ||
// trailing spaces or comma | ||
break; | ||
} | ||
ast.entries.push(map); | ||
/* istanbul ignore next */ | ||
throw ctx.throwUnexpectedTokenError(t); | ||
} | ||
else { | ||
ast.entries.push(...convertFlowSequenceItem(n, ctx, ast, doc)); | ||
} | ||
}); | ||
return convertAnchorAndTag(node, ctx, parent, ast, doc, ast); | ||
ast.entries.push(convertSequenceItem(startTokens, item, items.shift() || null, ctx, ast, doc, (ast.entries[ast.entries.length - 1] || ast).range[1])); | ||
} | ||
adjustEndLoc(ast, ast.entries[ast.entries.length - 1] || lastSeqInd); | ||
return convertAnchorAndTag(preTokens, node, ctx, parent, ast, doc, ast); | ||
} | ||
@@ -329,25 +645,26 @@ /** | ||
*/ | ||
function* convertSequenceItem(node, cst, ctx, parent, doc) { | ||
if (node) { | ||
if (node.type === yaml_1.PairType.PAIR || node.type === yaml_1.PairType.MERGE_PAIR) { | ||
const cstRange = cst.node.range; | ||
const range = [cstRange.start, cstRange.end]; | ||
const map = Object.assign({ type: "YAMLMapping", style: "block", pairs: [], parent }, ctx.getConvertLocation({ range })); | ||
// TODO collect : token | ||
const pair = convertMappingItem(node, { range }, ctx, map, doc); | ||
map.pairs.push(pair); | ||
if (pair && map.range[1] !== pair.range[1]) { | ||
// adjust location | ||
map.range[1] = pair.range[1]; | ||
map.loc.end = clone(pair.loc.end); | ||
function convertSequenceItem(preTokens, cst, node, ctx, parent, doc, indexForError) { | ||
var _a; | ||
/* istanbul ignore if */ | ||
if (cst.key) { | ||
throw ctx.throwUnexpectedTokenError(cst.key); | ||
} | ||
/* istanbul ignore if */ | ||
if (cst.sep) { | ||
throw ctx.throwUnexpectedTokenError(cst.sep); | ||
} | ||
if (cst.value) { | ||
if (isPair(node)) { | ||
if (cst.value.type !== "block-map") { | ||
throw ctx.throwError(`unknown error: CST is not block map (${cst.value.type}). Unable to process Pair AST.`, cst.value); | ||
} | ||
yield map; | ||
return convertMapping(preTokens, cst.value, node, ctx, parent, doc); | ||
} | ||
else { | ||
yield convertContentNode(node, ctx, parent, doc); | ||
} | ||
return convertContentNode(preTokens, cst.value, node, ctx, parent, doc); | ||
} | ||
else { | ||
yield null; | ||
/* istanbul ignore if */ | ||
if (!isScalarOrNull(node)) { | ||
throw ctx.throwError(`unknown error: AST is not Scalar and null (${getNodeType(node)}). Unable to process empty seq item CST.`, (_a = preTokens.first()) !== null && _a !== void 0 ? _a : indexForError); | ||
} | ||
return convertAnchorAndTag(preTokens, node, ctx, parent, null, doc, null); | ||
} | ||
@@ -357,6 +674,12 @@ /** | ||
*/ | ||
function* convertFlowSequenceItem(node, ctx, parent, doc) { | ||
if (node) { | ||
yield convertContentNode(node, ctx, parent, doc); | ||
function convertFlowSequenceItem(preTokens, cst, node, ctx, parent, doc, indexForError) { | ||
var _a; | ||
if (cst) { | ||
return convertContentNode(preTokens, cst, node, ctx, parent, doc); | ||
} | ||
/* istanbul ignore if */ | ||
if (!isScalarOrNull(node)) { | ||
throw ctx.throwError(`unknown error: AST is not Scalar and null (${getNodeType(node)}). Unable to process empty seq item CST.`, (_a = preTokens.first()) !== null && _a !== void 0 ? _a : indexForError); | ||
} | ||
return convertAnchorAndTag(preTokens, node, ctx, parent, null, doc, null); | ||
} | ||
@@ -366,14 +689,10 @@ /** | ||
*/ | ||
function convertPlain(node, ctx, parent, doc) { | ||
const valueRange = node.cstNode.valueRange; | ||
const loc = ctx.getConvertLocation({ | ||
range: [ | ||
valueRange.start, | ||
lastSkipSpaces(ctx.code, valueRange.start, valueRange.end), | ||
], | ||
}); | ||
function convertPlain(preTokens, cst, node, ctx, parent, doc) { | ||
var _a; | ||
const loc = ctx.getConvertLocation(...toRange(cst)); | ||
let ast; | ||
if (loc.range[0] < loc.range[1]) { | ||
const strValue = node.cstNode.strValue; | ||
const strValue = node.source || cst.source; | ||
const value = parseValueFromText(strValue, (0, utils_1.getYAMLVersion)(doc)); | ||
const ast = Object.assign({ type: "YAMLScalar", style: "plain", strValue, | ||
ast = Object.assign({ type: "YAMLScalar", style: "plain", strValue, | ||
value, raw: ctx.code.slice(...loc.range), parent }, loc); | ||
@@ -393,5 +712,9 @@ const type = typeof value; | ||
} | ||
return convertAnchorAndTag(node, ctx, parent, ast, doc, loc); | ||
ast = convertAnchorAndTag(preTokens, node, ctx, parent, ast, doc, loc); | ||
} | ||
return convertAnchorAndTag(node, ctx, parent, null, doc, loc); | ||
else { | ||
ast = convertAnchorAndTag(preTokens, node, ctx, parent, null, doc, loc); | ||
} | ||
(_a = cst.end) === null || _a === void 0 ? void 0 : _a.forEach((t) => processAnyToken(t, ctx)); | ||
return ast; | ||
/** | ||
@@ -412,11 +735,10 @@ * Parse value from text | ||
*/ | ||
function convertQuoteDouble(node, ctx, parent, doc) { | ||
const loc = ctx.getConvertLocationFromCSTRange(node.cstNode.valueRange); | ||
const cst = node.cstNode; | ||
const strValue = typeof cst.strValue === "object" && cst.strValue | ||
? cst.strValue.str | ||
: cst.strValue || ""; | ||
function convertQuoteDouble(preTokens, cst, node, ctx, parent, doc) { | ||
var _a; | ||
const loc = ctx.getConvertLocation(...toRange(cst)); | ||
const strValue = node.source; | ||
const ast = Object.assign({ type: "YAMLScalar", style: "double-quoted", strValue, value: strValue, raw: ctx.code.slice(...loc.range), parent }, loc); | ||
ctx.addToken("String", loc.range); | ||
return convertAnchorAndTag(node, ctx, parent, ast, doc, ast); | ||
(_a = cst.end) === null || _a === void 0 ? void 0 : _a.forEach((t) => processAnyToken(t, ctx)); | ||
return convertAnchorAndTag(preTokens, node, ctx, parent, ast, doc, ast); | ||
} | ||
@@ -426,11 +748,10 @@ /** | ||
*/ | ||
function convertQuoteSingle(node, ctx, parent, doc) { | ||
const loc = ctx.getConvertLocationFromCSTRange(node.cstNode.valueRange); | ||
const cst = node.cstNode; | ||
const strValue = typeof cst.strValue === "object" && cst.strValue | ||
? cst.strValue.str | ||
: cst.strValue || ""; | ||
function convertQuoteSingle(preTokens, cst, node, ctx, parent, doc) { | ||
var _a; | ||
const loc = ctx.getConvertLocation(...toRange(cst)); | ||
const strValue = node.source; | ||
const ast = Object.assign({ type: "YAMLScalar", style: "single-quoted", strValue, value: strValue, raw: ctx.code.slice(...loc.range), parent }, loc); | ||
ctx.addToken("String", loc.range); | ||
return convertAnchorAndTag(node, ctx, parent, ast, doc, ast); | ||
(_a = cst.end) === null || _a === void 0 ? void 0 : _a.forEach((t) => processAnyToken(t, ctx)); | ||
return convertAnchorAndTag(preTokens, node, ctx, parent, ast, doc, ast); | ||
} | ||
@@ -440,48 +761,68 @@ /** | ||
*/ | ||
function convertBlockLiteral(node, ctx, parent, doc) { | ||
const cst = node.cstNode; | ||
const end = getBlockEnd(cst, ctx); | ||
const loc = ctx.getConvertLocation({ | ||
range: [cst.header.start, end], | ||
}); | ||
const value = cst.strValue || ""; | ||
const ast = Object.assign({ type: "YAMLScalar", style: "literal", chomping: CHOMPING_MAP[cst.chomping], indent: getBlockIndent(node), value, | ||
parent }, loc); | ||
const punctuatorRange = [cst.header.start, cst.header.end]; | ||
ctx.addToken("Punctuator", punctuatorRange); | ||
const text = ctx.code.slice(cst.valueRange.start, end); | ||
const offset = /^[^\S\n\r]*/.exec(text)[0].length; | ||
const tokenRange = [cst.valueRange.start + offset, end]; | ||
if (tokenRange[0] < tokenRange[1]) { | ||
ctx.addToken("BlockLiteral", tokenRange); | ||
function convertBlockScalar(preTokens, cst, node, ctx, parent, doc) { | ||
let headerToken, ast; | ||
let blockStart = cst.offset; | ||
for (const token of cst.props) { | ||
if (processCommentOrSpace(token, ctx)) { | ||
blockStart = token.offset + token.source.length; | ||
continue; | ||
} | ||
if (token.type === "block-scalar-header") { | ||
headerToken = ctx.addToken("Punctuator", toRange(token)); | ||
blockStart = headerToken.range[0]; | ||
continue; | ||
} | ||
/* istanbul ignore next */ | ||
throw ctx.throwUnexpectedTokenError(token); | ||
} | ||
return convertAnchorAndTag(node, ctx, parent, ast, doc, ast); | ||
} | ||
/** | ||
* Convert BlockFolded to YAMLBlockFolded | ||
*/ | ||
function convertBlockFolded(node, ctx, parent, doc) { | ||
const cst = node.cstNode; | ||
const end = getBlockEnd(cst, ctx); | ||
const loc = ctx.getConvertLocation({ | ||
range: [cst.header.start, end], | ||
}); | ||
const value = cst.strValue || ""; | ||
const ast = Object.assign({ type: "YAMLScalar", style: "folded", chomping: CHOMPING_MAP[cst.chomping], indent: getBlockIndent(node), value, | ||
parent }, loc); | ||
const punctuatorRange = [cst.header.start, cst.header.end]; | ||
ctx.addToken("Punctuator", punctuatorRange); | ||
const text = ctx.code.slice(cst.valueRange.start, end); | ||
const offset = /^[^\S\n\r]*/.exec(text)[0].length; | ||
const tokenRange = [cst.valueRange.start + offset, end]; | ||
if (tokenRange[0] < tokenRange[1]) { | ||
ctx.addToken("BlockFolded", tokenRange); | ||
const headerValue = headerToken.value; | ||
const end = node.source | ||
? getBlockEnd(blockStart + cst.source.length, ctx) | ||
: ctx.lastSkipSpaces(cst.offset, blockStart + cst.source.length); | ||
const loc = ctx.getConvertLocation(headerToken.range[0], end); | ||
if (headerValue.startsWith(">")) { | ||
ast = Object.assign(Object.assign(Object.assign({ type: "YAMLScalar", style: "folded" }, parseHeader(headerValue)), { value: node.source, parent }), loc); | ||
const text = ctx.code.slice(blockStart, end); | ||
const offset = /^[^\S\n\r]*/.exec(text)[0].length; | ||
const tokenRange = [blockStart + offset, end]; | ||
if (tokenRange[0] < tokenRange[1]) { | ||
ctx.addToken("BlockFolded", tokenRange); | ||
} | ||
} | ||
return convertAnchorAndTag(node, ctx, parent, ast, doc, ast); | ||
else { | ||
ast = Object.assign(Object.assign(Object.assign({ type: "YAMLScalar", style: "literal" }, parseHeader(headerValue)), { value: node.source, parent }), loc); | ||
const text = ctx.code.slice(blockStart, end); | ||
const offset = /^[^\S\n\r]*/.exec(text)[0].length; | ||
const tokenRange = [blockStart + offset, end]; | ||
if (tokenRange[0] < tokenRange[1]) { | ||
ctx.addToken("BlockLiteral", tokenRange); | ||
} | ||
} | ||
return convertAnchorAndTag(preTokens, node, ctx, parent, ast, doc, ast); | ||
/** Get chomping kind */ | ||
function parseHeader(header) { | ||
const parsed = /([+-]?)(\d*)([+-]?)$/u.exec(header); | ||
let indent = null; | ||
let chomping = "clip"; | ||
if (parsed) { | ||
indent = parsed[2] ? Number(parsed[2]) : null; | ||
const chompingStr = parsed[3] || parsed[1]; | ||
chomping = | ||
chompingStr === "+" | ||
? "keep" | ||
: chompingStr === "-" | ||
? "strip" | ||
: "clip"; | ||
} | ||
return { | ||
chomping, | ||
indent, | ||
}; | ||
} | ||
} | ||
/** | ||
* Get the end index from give block node | ||
* Get the end index from give block end | ||
*/ | ||
function getBlockEnd(cst, ctx) { | ||
let index = cst.valueRange.end; | ||
function getBlockEnd(end, ctx) { | ||
let index = end; | ||
if (ctx.code[index - 1] === "\n" && index > 1) { | ||
@@ -496,34 +837,17 @@ index--; | ||
/** | ||
* Get block indent from given block | ||
*/ | ||
function getBlockIndent(node) { | ||
const cst = node.cstNode; | ||
const numLength = cst.header.end - cst.header.start - 1; | ||
return numLength - (cst.chomping === "CLIP" ? 0 : 1) | ||
? cst.blockIndent | ||
: null; | ||
} | ||
/** | ||
* Convert Alias to YAMLAlias | ||
*/ | ||
function convertAlias(node, ctx, parent, doc) { | ||
const cst = node.cstNode; | ||
const range = cst.range; | ||
const valueRange = cst.valueRange; | ||
const nodeRange = [range.start, valueRange.end]; | ||
if (range.start === valueRange.start) { | ||
// adjust | ||
nodeRange[0]--; | ||
} | ||
const loc = ctx.getConvertLocation({ | ||
range: nodeRange, | ||
}); | ||
const ast = Object.assign({ type: "YAMLAlias", name: cst.rawValue, parent }, loc); | ||
const starIndex = nodeRange[0]; | ||
ctx.addToken("Punctuator", [starIndex, starIndex + 1]); | ||
const tokenRange = [valueRange.start, valueRange.end]; | ||
function convertAlias(preTokens, cst, node, ctx, parent, doc) { | ||
var _a; | ||
const [start, end] = toRange(cst); | ||
const loc = ctx.getConvertLocation(start, ctx.lastSkipSpaces(start, end)); | ||
let ast = Object.assign({ type: "YAMLAlias", name: cst.source.slice(1), parent }, loc); | ||
ctx.addToken("Punctuator", [loc.range[0], loc.range[0] + 1]); | ||
const tokenRange = [loc.range[0] + 1, loc.range[1]]; | ||
if (tokenRange[0] < tokenRange[1]) { | ||
ctx.addToken("Identifier", tokenRange); | ||
} | ||
return convertAnchorAndTag(node, ctx, parent, ast, doc, ast); | ||
ast = convertAnchorAndTag(preTokens, node, ctx, parent, ast, doc, ast); | ||
(_a = cst.end) === null || _a === void 0 ? void 0 : _a.forEach((t) => processAnyToken(t, ctx)); | ||
return ast; | ||
} | ||
@@ -533,4 +857,3 @@ /** | ||
*/ | ||
function convertAnchorAndTag(node, ctx, parent, value, doc, valueLoc) { | ||
const cst = node.cstNode; | ||
function convertAnchorAndTag(preTokens, node, ctx, parent, value, doc, valueLoc) { | ||
let meta = null; | ||
@@ -540,15 +863,13 @@ /** | ||
*/ | ||
function getMetaAst() { | ||
function getMetaAst(cst) { | ||
if (meta) { | ||
return meta; | ||
} | ||
meta = { | ||
type: "YAMLWithMeta", | ||
anchor: null, | ||
tag: null, | ||
value, | ||
parent, | ||
range: clone(valueLoc.range), | ||
loc: clone(valueLoc.loc), | ||
}; | ||
meta = Object.assign({ type: "YAMLWithMeta", anchor: null, tag: null, value, | ||
parent }, (valueLoc | ||
? { | ||
range: [...valueLoc.range], | ||
loc: cloneLoc(valueLoc.loc), | ||
} | ||
: ctx.getConvertLocation(...toRange(cst)))); | ||
if (value) { | ||
@@ -559,27 +880,23 @@ value.parent = meta; | ||
} | ||
for (const range of cst.props) { | ||
const startChar = ctx.code[range.start]; | ||
if (startChar === "&") { | ||
const ast = getMetaAst(); | ||
const anchor = convertAnchor([range.start, range.end], cst.anchor, ctx, ast, doc); | ||
preTokens.each((cst) => { | ||
var _a; | ||
if (isAnchorCST(cst)) { | ||
const ast = getMetaAst(cst); | ||
const anchor = convertAnchor(cst, ctx, ast, doc); | ||
ast.anchor = anchor; | ||
if (anchor.range[0] < ast.range[0]) { | ||
ast.range[0] = anchor.range[0]; | ||
ast.loc.start = clone(anchor.loc.start); | ||
} | ||
adjustStartLoc(ast, anchor); | ||
adjustEndLoc(ast, anchor); | ||
} | ||
else if (startChar === "!") { | ||
const ast = getMetaAst(); | ||
const tag = convertTag([range.start, range.end], node.tag, ctx, ast); | ||
else if (isTagCST(cst)) { | ||
const ast = getMetaAst(cst); | ||
const tag = convertTag(cst, (_a = node === null || node === void 0 ? void 0 : node.tag) !== null && _a !== void 0 ? _a : null, ctx, ast); | ||
ast.tag = tag; | ||
if (tag.range[0] < ast.range[0]) { | ||
ast.range[0] = tag.range[0]; | ||
ast.loc.start = clone(tag.loc.start); | ||
} | ||
adjustStartLoc(ast, tag); | ||
adjustEndLoc(ast, tag); | ||
} | ||
else if (startChar === "#") { | ||
const comment = Object.assign({ type: "Block", value: ctx.code.slice(range.start + 1, range.end) }, ctx.getConvertLocationFromCSTRange(range)); | ||
ctx.addComment(comment); | ||
else { | ||
/* istanbul ignore next */ | ||
throw ctx.throwUnexpectedTokenError(cst); | ||
} | ||
} | ||
}); | ||
return meta || value; | ||
@@ -590,4 +907,5 @@ } | ||
*/ | ||
function convertAnchor(range, name, ctx, parent, doc) { | ||
const loc = ctx.getConvertLocation({ range }); | ||
function convertAnchor(cst, ctx, parent, doc) { | ||
const name = cst.source.slice(1); | ||
const loc = ctx.getConvertLocation(...toRange(cst)); | ||
const ast = Object.assign({ type: "YAMLAnchor", name, | ||
@@ -608,8 +926,10 @@ parent }, loc); | ||
*/ | ||
function convertTag(range, tag, ctx, parent) { | ||
const loc = ctx.getConvertLocation({ range }); | ||
const ast = Object.assign({ type: "YAMLTag", tag, | ||
parent }, loc); | ||
const text = ctx.code.slice(...loc.range); | ||
const offset = text.startsWith("!!") ? 2 : 1; | ||
function convertTag(cst, tag, ctx, parent) { | ||
const offset = cst.source.startsWith("!!") ? 2 : 1; | ||
let resolvedTag = tag !== null && tag !== void 0 ? tag : cst.source.slice(offset); | ||
if (resolvedTag === "!") { | ||
resolvedTag = "tag:yaml.org,2002:str"; | ||
} | ||
const loc = ctx.getConvertLocation(...toRange(cst)); | ||
const ast = Object.assign({ type: "YAMLTag", tag: resolvedTag, raw: cst.source, parent }, loc); | ||
const punctuatorRange = [loc.range[0], loc.range[0] + offset]; | ||
@@ -623,221 +943,38 @@ ctx.addToken("Punctuator", punctuatorRange); | ||
} | ||
/** Checks whether the give node is scaler or null */ | ||
function isScalarOrNull(node) { | ||
return (0, yaml_1.isScalar)(node) || node == null; | ||
} | ||
/** Get the pairs from the give node */ | ||
function getPairs(node) { | ||
return (0, yaml_1.isMap)(node) ? [...node.items] : [node]; | ||
} | ||
/** | ||
* Process comments | ||
* Process comments or spaces | ||
*/ | ||
function processComment(node, ctx) { | ||
if (node.type === yaml_1.Type.BLANK_LINE) { | ||
return false; | ||
function processCommentOrSpace(node, ctx) { | ||
if (node.type === "space" || node.type === "newline") { | ||
return true; | ||
} | ||
if (node.type === yaml_1.Type.COMMENT) { | ||
const comment = Object.assign({ type: "Block", value: node.comment }, ctx.getConvertLocationFromCSTRange(node.range)); | ||
/* istanbul ignore if */ | ||
if (node.type === "flow-error-end" || node.type === "error") { | ||
throw ctx.throwUnexpectedTokenError(node); | ||
} | ||
if (node.type === "comment") { | ||
const comment = Object.assign({ type: "Block", value: node.source.slice(1) }, ctx.getConvertLocation(...toRange(node))); | ||
ctx.addComment(comment); | ||
return false; | ||
return true; | ||
} | ||
return true; | ||
return false; | ||
} | ||
/** | ||
* Extract comments from props | ||
* Process any token | ||
*/ | ||
function extractComment(cst, ctx) { | ||
for (const range of cst.props) { | ||
const startChar = ctx.code[range.start]; | ||
if (startChar === "#") { | ||
const comment = Object.assign({ type: "Block", value: ctx.code.slice(range.start + 1, range.end) }, ctx.getConvertLocationFromCSTRange(range)); | ||
ctx.addComment(comment); | ||
} | ||
function processAnyToken(node, ctx) { | ||
/* istanbul ignore if */ | ||
if (!processCommentOrSpace(node, ctx)) { | ||
throw ctx.throwUnexpectedTokenError(node); | ||
} | ||
} | ||
/** | ||
* Process CST items | ||
*/ | ||
function processCSTItems(node, ctx) { | ||
const parsed = [...parseCSTItems(node.cstNode.items)]; | ||
return parsed; | ||
/* eslint-disable complexity -- ignore */ | ||
/** | ||
* Parse for cst items | ||
*/ | ||
function* parseCSTItems( | ||
/* eslint-enable complexity -- ignore */ | ||
items) { | ||
let data = { | ||
key: [], | ||
value: [], | ||
state: 0 /* empty */, | ||
}; | ||
for (const cstItem of items) { | ||
if ("char" in cstItem) { | ||
ctx.addToken("Punctuator", [cstItem.offset, cstItem.offset + 1]); | ||
if (cstItem.char === "[" || | ||
cstItem.char === "]" || | ||
cstItem.char === "{" || | ||
cstItem.char === "}") { | ||
continue; | ||
} | ||
if (cstItem.char === ",") { | ||
if (data.state !== 0 /* empty */) { | ||
yield parseGroup(data); | ||
} | ||
data = { key: [], value: [], state: 0 /* empty */ }; | ||
continue; | ||
} | ||
if (cstItem.char === "?") { | ||
if (data.state !== 0 /* empty */) { | ||
yield parseGroup(data); | ||
data = { | ||
key: [cstItem], | ||
value: [], | ||
state: 1 /* keyMark */, | ||
}; | ||
} | ||
else { | ||
data.key.push(cstItem); | ||
data.state = 1 /* keyMark */; | ||
} | ||
continue; | ||
} | ||
else if (cstItem.char === ":") { | ||
if (data.state === 0 /* empty */ || | ||
data.state === 1 /* keyMark */ || | ||
data.state === 2 /* key */) { | ||
data.value.push(cstItem); | ||
data.state = 3 /* valueMark */; | ||
} | ||
else { | ||
yield parseGroup(data); | ||
data = { | ||
key: [], | ||
value: [cstItem], | ||
state: 3 /* valueMark */, | ||
}; | ||
} | ||
continue; | ||
} | ||
} | ||
else if (!processComment(cstItem, ctx)) { | ||
continue; | ||
} | ||
else { | ||
if (cstItem.type === yaml_1.Type.MAP_VALUE) { | ||
ctx.addToken("Punctuator", [ | ||
cstItem.range.start, | ||
cstItem.range.start + 1, | ||
]); | ||
extractComment(cstItem, ctx); | ||
if (data.state === 0 /* empty */ || | ||
data.state === 1 /* keyMark */ || | ||
data.state === 2 /* key */) { | ||
data.value.push(cstItem); | ||
yield parseGroup(data); | ||
} | ||
else { | ||
yield parseGroup(data); | ||
yield parseGroup({ key: [], value: [cstItem] }); | ||
} | ||
data = { key: [], value: [], state: 0 /* empty */ }; | ||
continue; | ||
} | ||
else if (cstItem.type === yaml_1.Type.MAP_KEY) { | ||
ctx.addToken("Punctuator", [ | ||
cstItem.range.start, | ||
cstItem.range.start + 1, | ||
]); | ||
extractComment(cstItem, ctx); | ||
if (data.state !== 0 /* empty */) { | ||
yield parseGroup(data); | ||
data = { | ||
key: [cstItem], | ||
value: [], | ||
state: 2 /* key */, | ||
}; | ||
} | ||
else { | ||
data.key.push(cstItem); | ||
data.state = 2 /* key */; | ||
} | ||
continue; | ||
} | ||
else { | ||
if (data.state === 0 /* empty */ || | ||
data.state === 1 /* keyMark */) { | ||
data.key.push(cstItem); | ||
data.state = 2 /* key */; | ||
continue; | ||
} | ||
if (data.state === 2 /* key */) { | ||
yield parseGroup(data); | ||
data = { | ||
key: [cstItem], | ||
value: [], | ||
state: 2 /* key */, | ||
}; | ||
continue; | ||
} | ||
if (data.state === 3 /* valueMark */) { | ||
data.value.push(cstItem); | ||
yield parseGroup(data); | ||
data = { | ||
key: [], | ||
value: [], | ||
state: 0 /* empty */, | ||
}; | ||
continue; | ||
} | ||
} | ||
} | ||
} | ||
if (data.state !== 0 /* empty */) { | ||
yield parseGroup(data); | ||
} | ||
} | ||
/** | ||
* Parse for cst item group | ||
*/ | ||
function parseGroup(data) { | ||
if (data.key.length && data.value.length) { | ||
const key = itemsToRange(data.key); | ||
const value = itemsToRange(data.value); | ||
return { | ||
key, | ||
value, | ||
range: [key[0], value[1]], | ||
}; | ||
} | ||
if (data.key.length) { | ||
const key = itemsToRange(data.key); | ||
return { | ||
key, | ||
value: null, | ||
range: key, | ||
}; | ||
} | ||
if (data.value.length) { | ||
const value = itemsToRange(data.value); | ||
return { | ||
key: null, | ||
value, | ||
range: value, | ||
}; | ||
} | ||
throw new Error("Unexpected state"); | ||
} | ||
/** get range */ | ||
function itemsToRange(items) { | ||
const first = itemToRange(items[0]); | ||
if (items.length === 1) { | ||
return first; | ||
} | ||
const last = itemToRange(items[items.length - 1]); | ||
return [first[0], last[1]]; | ||
} | ||
/** get range */ | ||
function itemToRange(item) { | ||
if ("char" in item) { | ||
return [item.offset, item.offset + 1]; | ||
} | ||
const range = item.range || item.valueRange; | ||
return [range.start, range.end]; | ||
} | ||
} | ||
/** | ||
* Sort tokens | ||
@@ -865,16 +1002,18 @@ */ | ||
*/ | ||
function clone(loc) { | ||
if (typeof loc !== "object") { | ||
return loc; | ||
} | ||
if (Array.isArray(loc)) { | ||
return loc.map(clone); | ||
} | ||
const n = {}; | ||
for (const key in loc) { | ||
n[key] = clone(loc[key]); | ||
} | ||
return n; | ||
function clonePos(loc) { | ||
return { | ||
line: loc.line, | ||
column: loc.column, | ||
}; | ||
} | ||
/** | ||
* clone the location. | ||
*/ | ||
function cloneLoc(loc) { | ||
return { | ||
start: clonePos(loc.start), | ||
end: clonePos(loc.end), | ||
}; | ||
} | ||
/** | ||
* Gets the first index with whitespace skipped. | ||
@@ -891,12 +1030,21 @@ */ | ||
} | ||
/** | ||
* Gets the last index with whitespace skipped. | ||
*/ | ||
function lastSkipSpaces(str, startIndex, endIndex) { | ||
for (let index = endIndex - 1; index >= startIndex; index--) { | ||
if (str[index].trim()) { | ||
return index + 1; | ||
} | ||
/** SourceToken to location range */ | ||
function toRange(token) { | ||
return [token.offset, token.offset + token.source.length]; | ||
} | ||
/** Adjust start location */ | ||
function adjustStartLoc(ast, first) { | ||
if (first && first.range[0] < ast.range[0]) { | ||
// adjust location | ||
ast.range[0] = first.range[0]; | ||
ast.loc.start = clonePos(first.loc.start); | ||
} | ||
return startIndex; | ||
} | ||
/** Adjust end location */ | ||
function adjustEndLoc(ast, last) { | ||
if (last && ast.range[1] < last.range[1]) { | ||
// adjust location | ||
ast.range[1] = last.range[1]; | ||
ast.loc.end = clonePos(last.loc.end); | ||
} | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.parseForESLint = void 0; | ||
const yaml_1 = require("yaml"); | ||
const visitor_keys_1 = require("./visitor-keys"); | ||
const convert_1 = require("./convert"); | ||
const errors_1 = require("./errors"); | ||
const context_1 = require("./context"); | ||
const yaml_cst_parse_1 = require("./yaml-cst-parse"); | ||
/** | ||
@@ -13,59 +12,13 @@ * Parse source code | ||
function parseForESLint(code, _options) { | ||
try { | ||
const ctx = new context_1.Context(code); | ||
const docs = (0, yaml_1.parseAllDocuments)(ctx.code, { | ||
merge: false, | ||
keepCstNodes: true, | ||
}); | ||
const ast = (0, convert_1.convertRoot)(docs, ctx); | ||
if (ctx.hasCR) { | ||
ctx.remapCR(ast); | ||
} | ||
return { | ||
ast, | ||
visitorKeys: visitor_keys_1.KEYS, | ||
services: { | ||
isYAML: true, | ||
}, | ||
}; | ||
} | ||
catch (err) { | ||
if (isYAMLSyntaxError(err)) { | ||
let message = err.message; | ||
const atIndex = message.lastIndexOf(" at"); | ||
if (atIndex >= 0) { | ||
message = message.slice(0, atIndex); | ||
} | ||
throw new errors_1.ParseError(message, err.range.start, err.linePos.start.line, err.linePos.start.col - 1); | ||
} | ||
if (isYAMLSyntaxErrorForV1(err)) { | ||
const message = err.message; | ||
throw new errors_1.ParseError(message, err.source.range.start, err.source.rangeAsLinePos.start.line, err.source.rangeAsLinePos.start.col - 1); | ||
} | ||
throw err; | ||
} | ||
const ctx = new context_1.Context(code); | ||
const docs = (0, yaml_cst_parse_1.parseAllDocsToCST)(ctx); | ||
const ast = (0, convert_1.convertRoot)(docs.cstNodes, docs.nodes, ctx); | ||
return { | ||
ast, | ||
visitorKeys: visitor_keys_1.KEYS, | ||
services: { | ||
isYAML: true, | ||
}, | ||
}; | ||
} | ||
exports.parseForESLint = parseForESLint; | ||
/** | ||
* Type guard for YAMLSyntaxError. | ||
*/ | ||
function isYAMLSyntaxError(error) { | ||
return (error.linePos && | ||
typeof error.linePos === "object" && | ||
error.linePos.start && | ||
typeof error.linePos.start === "object" && | ||
typeof error.linePos.start.line === "number" && | ||
typeof error.linePos.start.col === "number"); | ||
} | ||
/** | ||
* Type guard for YAMLSyntaxError (yaml@1.10). | ||
*/ | ||
function isYAMLSyntaxErrorForV1(error) { | ||
return (error.source && | ||
error.source.rangeAsLinePos && | ||
typeof error.source.rangeAsLinePos === "object" && | ||
error.source.rangeAsLinePos.start && | ||
typeof error.source.rangeAsLinePos.start === "object" && | ||
typeof error.source.rangeAsLinePos.start.line === "number" && | ||
typeof error.source.rangeAsLinePos.start.col === "number"); | ||
} |
export declare const tagResolvers: { | ||
"1.3": (import("./commons").TagResolver<null> | import("./commons").TagResolver<true> | import("./commons").TagResolver<false> | import("./commons").TagResolver<number> | import("./commons").TagResolver<string>)[]; | ||
"1.2": (import("./commons").TagResolver<null> | import("./commons").TagResolver<true> | import("./commons").TagResolver<false> | import("./commons").TagResolver<number> | import("./commons").TagResolver<string>)[]; | ||
"1.1": (import("./commons").TagResolver<null> | import("./commons").TagResolver<true> | import("./commons").TagResolver<false> | import("./commons").TagResolver<number> | import("./commons").TagResolver<string>)[]; | ||
}; |
@@ -7,4 +7,5 @@ "use strict"; | ||
exports.tagResolvers = { | ||
"1.3": tags1_2_1.tagResolvers, | ||
"1.2": tags1_2_1.tagResolvers, | ||
"1.1": tags1_1_1.tagResolvers, | ||
}; |
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
@@ -101,3 +105,3 @@ if (k2 === undefined) k2 = k; | ||
resolve(str) { | ||
return resolveBase60(str.split(/:/gu), true); | ||
return resolveBase60(str.split(/:/u), true); | ||
}, | ||
@@ -126,3 +130,3 @@ }; | ||
resolve(str) { | ||
return resolveBase60(str.split(/:/gu), false); | ||
return resolveBase60(str.split(/:/u), false); | ||
}, | ||
@@ -129,0 +133,0 @@ }; |
import type { YAMLProgram, YAMLContent, YAMLDocument, YAMLMapping, YAMLSequence, YAMLScalar, YAMLAlias, YAMLPair, YAMLWithMeta } from "./ast"; | ||
export declare type YAMLVersion = "1.3" | "1.2" | "1.1"; | ||
declare type YAMLContentValue = string | number | boolean | null | YAMLContentValue[] | YAMLMappingValue; | ||
@@ -14,3 +15,3 @@ declare type YAMLMappingValue = { | ||
*/ | ||
export declare function getYAMLVersion(document: YAMLDocument): "1.2" | "1.1"; | ||
export declare function getYAMLVersion(document: YAMLDocument): YAMLVersion; | ||
export {}; |
@@ -138,12 +138,13 @@ "use strict"; | ||
function getYAMLVersion(document) { | ||
var _a; | ||
for (const dir of document.directives) { | ||
const yamlVer = (_a = /^%YAML\s+(\d\.\d)$/.exec(dir.value)) === null || _a === void 0 ? void 0 : _a[1]; | ||
if (yamlVer) { | ||
if (yamlVer === "1.1") { | ||
if (dir.kind === "YAML") { | ||
if (dir.version === "1.1") { | ||
return "1.1"; | ||
} | ||
if (yamlVer === "1.2") { | ||
if (dir.version === "1.2") { | ||
return "1.2"; | ||
} | ||
if (dir.version === "1.3") { | ||
return "1.3"; | ||
} | ||
// Other versions are not supported | ||
@@ -150,0 +151,0 @@ return "1.2"; |
{ | ||
"publishConfig": { | ||
"tag": "next" | ||
}, | ||
"name": "yaml-eslint-parser", | ||
"version": "0.5.0", | ||
"version": "1.0.0-beta.0", | ||
"description": "A YAML parser that produces output compatible with ESLint", | ||
@@ -10,3 +13,3 @@ "main": "lib/index.js", | ||
"engines": { | ||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0" | ||
"node": "^14.17.0 || >=16.0.0" | ||
}, | ||
@@ -21,5 +24,6 @@ "scripts": { | ||
"cover": "nyc --reporter=lcov npm run test", | ||
"debug": "mocha --require ts-node/register/transpile-only --inspect \"tests/src/**/*.ts\" --reporter dot", | ||
"debug": "mocha --require ts-node/register/transpile-only \"tests/src/**/*.ts\" --reporter dot", | ||
"preversion": "npm run lint && npm test", | ||
"update-fixtures": "ts-node ./tools/update-fixtures.ts" | ||
"update-fixtures": "ts-node ./tools/update-fixtures.ts", | ||
"benchmark": "ts-node --transpile-only benchmark/index.ts" | ||
}, | ||
@@ -36,2 +40,3 @@ "repository": { | ||
"author": "Yosuke Ota", | ||
"funding": "https://github.com/sponsors/ota-meshi", | ||
"license": "MIT", | ||
@@ -45,7 +50,8 @@ "bugs": { | ||
"lodash": "^4.17.21", | ||
"yaml": "^1.10.2" | ||
"yaml": "^2.0.0" | ||
}, | ||
"devDependencies": { | ||
"@ota-meshi/eslint-plugin": "^0.10.0", | ||
"@types/eslint": "^7.2.0", | ||
"@types/benchmark": "^2.1.1", | ||
"@types/eslint": "^8.0.0", | ||
"@types/eslint-visitor-keys": "^1.0.0", | ||
@@ -57,2 +63,3 @@ "@types/lodash": "^4.14.167", | ||
"@typescript-eslint/parser": "^5.0.0", | ||
"benchmark": "^2.1.4", | ||
"eslint": "^8.0.0", | ||
@@ -59,0 +66,0 @@ "eslint-config-prettier": "^8.0.0", |
81567
2149
25
+ Addedyaml@2.4.2(transitive)
- Removedyaml@1.10.2(transitive)
Updatedyaml@^2.0.0