From 6f8a8c5bbd75b4ea8f8ffa177fb788235638e0c3 Mon Sep 17 00:00:00 2001 From: Kevin Decker Date: Sun, 25 Feb 2018 22:45:59 -0600 Subject: [PATCH] Remove unused yaml parser module --- .../parser/yamlParser.ts | 326 ------------------ 1 file changed, 326 deletions(-) delete mode 100644 src/vscode-yaml-languageservice/parser/yamlParser.ts diff --git a/src/vscode-yaml-languageservice/parser/yamlParser.ts b/src/vscode-yaml-languageservice/parser/yamlParser.ts deleted file mode 100644 index 2eb73d2..0000000 --- a/src/vscode-yaml-languageservice/parser/yamlParser.ts +++ /dev/null @@ -1,326 +0,0 @@ -'use strict'; - -import { JSONDocument, ASTNode, ErrorCode, BooleanASTNode, NullASTNode, ArrayASTNode, NumberASTNode, ObjectASTNode, PropertyASTNode, StringASTNode, IError, IApplicableSchema } from 'vscode-json-languageservice/lib/parser/jsonParser'; -import { JSONSchema } from 'vscode-json-languageservice/lib/jsonSchema'; - -import * as nls from 'vscode-nls'; -const localize = nls.loadMessageBundle(); - -import * as Yaml from '../../yaml-ast-parser/index' -import { Kind } from '../../yaml-ast-parser/index' - -import { getLineStartPositions, getPosition } from '../documentPositionCalculator' - -export class SingleYAMLDocument extends JSONDocument { - private lines; - public root; - - constructor(lines: number[]) { - super({ disallowComments: false, ignoreDanglingComma: true }); - this.lines = lines; - } - - // TODO: This is complicated, messy and probably buggy - // It should be re-written. - // To get the correct behavior, it probably needs to be aware of - // the type of the nodes it is processing since there are no delimiters - // like in JSON. (ie. so it correctly returns 'object' vs 'property') - public getNodeFromOffsetEndInclusive(offset: number): ASTNode { - if (!this.root) { - return; - } - if (offset < this.root.start || offset > this.root.end) { - // We somehow are completely outside the document - // This is unexpected - console.log("Attempting to resolve node outside of document") - return null; - } - - const children = this.root.getChildNodes() - - function* sliding2(nodes: ASTNode[]) { - var i = 0; - while (i < nodes.length) { - yield [nodes[i], (i === nodes.length) ? null : nodes[i + 1]] - i++; - } - } - - const onLaterLine = (offset: number, node: ASTNode) => { - const { line: actualLine } = getPosition(offset, this.lines) - const { line: nodeEndLine } = getPosition(node.end, this.lines) - - return actualLine > nodeEndLine; - } - - let findNode = (nodes: ASTNode[]): ASTNode => { - if (nodes.length === 0) { - return null; - } - - var gen = sliding2(nodes); - - let result: IteratorResult = { done: false, value: undefined } - - for (let [first, second] of gen) { - const end = (second) ? second.start : first.parent.end - if (offset >= first.start && offset < end) { - const children = first.getChildNodes(); - - const foundChild = findNode(children) - - if (foundChild) { - if (foundChild['isKey'] && foundChild.end < offset) { - return foundChild.parent; - } - - if (foundChild.type === "null") { - return null; - } - } - - if (!foundChild && onLaterLine(offset, first)) { - return this.getNodeByIndent(this.lines, offset, this.root) - } - - return foundChild || first; - } - } - - return null; - } - - return findNode(children) || this.root; - } - - public getNodeFromOffset(offset: number): ASTNode { - return this.getNodeFromOffsetEndInclusive(offset); - } - - private getNodeByIndent = (lines: number[], offset: number, node: ASTNode) => { - - const { line, column: indent } = getPosition(offset, this.lines) - - const children = node.getChildNodes() - - function findNode(children) { - for (var idx = 0; idx < children.length; idx++) { - var child = children[idx]; - - const { line: childLine, column: childCol } = getPosition(child.start, lines); - - if (childCol > indent) { - return null; - } - - const newChildren = child.getChildNodes() - const foundNode = findNode(newChildren) - - if (foundNode) { - return foundNode; - } - - // We have the right indentation, need to return based on line - if (childLine == line) { - return child; - } - if (childLine > line) { - // Get previous - (idx - 1) >= 0 ? children[idx - 1] : child; - } - // Else continue loop to try next element - } - - // Special case, we found the correct - return children[children.length - 1] - } - - return findNode(children) || node - } -} - - -function recursivelyBuildAst(parent: ASTNode, node: Yaml.YAMLNode): ASTNode { - - if (!node) { - return; - } - - switch (node.kind) { - case Yaml.Kind.MAP: { - const instance = node; - - const result = new ObjectASTNode(parent, null, node.startPosition, node.endPosition) - result.addProperty - - for (const mapping of instance.mappings) { - result.addProperty(recursivelyBuildAst(result, mapping)) - } - - return result; - } - case Yaml.Kind.MAPPING: { - const instance = node; - const key = instance.key; - - // Technically, this is an arbitrary node in YAML - // I doubt we would get a better string representation by parsing it - const keyNode = new StringASTNode(null, null, true, key.startPosition, key.endPosition); - keyNode.value = key.value; - - const result = new PropertyASTNode(parent, keyNode) - result.end = instance.endPosition - - const valueNode = (instance.value) ? recursivelyBuildAst(result, instance.value) : new NullASTNode(parent, key.value, instance.endPosition, instance.endPosition) - valueNode.location = key.value - - result.setValue(valueNode) - - return result; - } - case Yaml.Kind.SEQ: { - const instance = node; - - const result = new ArrayASTNode(parent, null, instance.startPosition, instance.endPosition); - - let count = 0; - for (const item of instance.items) { - if (item === null && count === instance.items.length - 1) { - break; - } - - // Be aware of https://github.com/nodeca/js-yaml/issues/321 - // Cannot simply work around it here because we need to know if we are in Flow or Block - var itemNode = (item === null) ? new NullASTNode(parent, null, instance.endPosition, instance.endPosition) : recursivelyBuildAst(result, item); - - itemNode.location = count++; - result.addItem(itemNode); - } - - return result; - } - case Yaml.Kind.SCALAR: { - const instance = node; - - const type = Yaml.determineScalarType(instance) - - // The name is set either by the sequence or the mapping case. - const name = null; - const value = instance.value; - - switch (type) { - case Yaml.ScalarType.null: { - return new NullASTNode(parent, name, instance.startPosition, instance.endPosition); - } - case Yaml.ScalarType.bool: { - return new BooleanASTNode(parent, name, Yaml.parseYamlBoolean(value), node.startPosition, node.endPosition) - } - case Yaml.ScalarType.int: { - const result = new NumberASTNode(parent, name, node.startPosition, node.endPosition); - result.value = Yaml.parseYamlInteger(value); - result.isInteger = true; - return result; - } - case Yaml.ScalarType.float: { - const result = new NumberASTNode(parent, name, node.startPosition, node.endPosition); - result.value = Yaml.parseYamlFloat(value); - result.isInteger = false; - return result; - } - case Yaml.ScalarType.string: { - const result = new StringASTNode(parent, name, false, node.startPosition, node.endPosition); - result.value = node.value; - return result; - } - } - - break; - } - case Yaml.Kind.ANCHOR_REF: { - const instance = (node).value - - return recursivelyBuildAst(parent, instance) || - new NullASTNode(parent, null, node.startPosition, node.endPosition); - } - case Yaml.Kind.INCLUDE_REF: { - // Issue Warning - console.log("Unsupported feature, node kind: " + node.kind); - break; - } - } -} - -function convertError(e: Yaml.YAMLException) { - // Subtract 2 because \n\0 is added by the parser (see loader.ts/loadDocuments) - const bufferLength = e.mark.buffer.length - 2; - - // TODO determine correct positioning. - return { message: `${e.message}`, location: { start: Math.min(e.mark.position, bufferLength - 1), end: bufferLength, code: ErrorCode.Undefined } } -} - -function createJSONDocument(yamlDoc: Yaml.YAMLNode, startPositions: number[]) { - let _doc = new SingleYAMLDocument(startPositions); - _doc.root = recursivelyBuildAst(null, yamlDoc) - - if (!_doc.root) { - // TODO: When this is true, consider not pushing the other errors. - _doc.errors.push({ message: localize('Invalid symbol', 'Expected a YAML object, array or literal'), code: ErrorCode.Undefined, location: { start: yamlDoc.startPosition, end: yamlDoc.endPosition } }); - } - - const duplicateKeyReason = 'duplicate key' - - const errors = yamlDoc.errors.filter(e => e.reason !== duplicateKeyReason && !e.isWarning).map(e => convertError(e)) - const warnings = yamlDoc.errors.filter(e => e.reason === duplicateKeyReason || e.isWarning).map(e => convertError(e)) - - errors.forEach(e => _doc.errors.push(e)); - warnings.forEach(e => _doc.warnings.push(e)); - - return _doc; -} - -export class YAMLDocument { - public documents: JSONDocument[] - - constructor(documents: JSONDocument[]) { - this.documents = documents; - } - - get errors(): IError[] { - return ([]).concat(...this.documents.map(d => d.errors)) - } - - get warnings(): IError[] { - return ([]).concat(...this.documents.map(d => d.warnings)) - } - - public getNodeFromOffsetEndInclusive(offset: number): ASTNode { - return this.getNodeFromOffset(offset); - } - public getNodeFromOffset(offset: number): ASTNode { - // Depends on the documents being sorted - for (let element of this.documents) { - if (offset <= element.root.end) { - return element.getNodeFromOffset(offset) - } - } - - return undefined; - } - - public validate(schema: JSONSchema, matchingSchemas: IApplicableSchema[] = null, offset: number = -1): void { - this.documents.forEach(doc => { - doc.validate(schema, matchingSchemas, offset) - }); - } -} - -export function parse(text: string): YAMLDocument { - - const startPositions = getLineStartPositions(text) - // This is documented to return a YAMLNode even though the - // typing only returns a YAMLDocument - const yamlDocs = [] - Yaml.loadAll(text, doc => yamlDocs.push(doc), {}) - - return new YAMLDocument(yamlDocs.map(doc => createJSONDocument(doc, startPositions))); -} \ No newline at end of file