From f214c5bfd48fd699a4c14496dc79f4f0a7a43911 Mon Sep 17 00:00:00 2001 From: Adam Voss Date: Fri, 14 Jul 2017 16:33:38 -0500 Subject: [PATCH 1/4] Return to upstream source for vscode-json-languageservice --- .gitmodules | 2 +- vscode-json-languageservice | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 28cbd46..2c01be9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "vscode-json-languageservice"] path = vscode-json-languageservice - url = https://github.com/adamvoss/vscode-json-languageservice.git + url = https://github.com/Microsoft/vscode-json-languageservice.git diff --git a/vscode-json-languageservice b/vscode-json-languageservice index 18d3e6c..1a4e783 160000 --- a/vscode-json-languageservice +++ b/vscode-json-languageservice @@ -1 +1 @@ -Subproject commit 18d3e6cf65bf375668ebde57fab7df8ed962fdb8 +Subproject commit 1a4e783f899825c83fb02fe5bf57daec5ea7993c From d688236cb726b813ae9c45e0ec9fbe715c6158e3 Mon Sep 17 00:00:00 2001 From: Adam Voss Date: Fri, 14 Jul 2017 20:00:41 -0500 Subject: [PATCH 2/4] Update yaml-ast-parser --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cf23f26..3c5cc9c 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "jsonc-parser": "^1.0.0", "vscode-json-languageservice": "file:./vscode-json-languageservice", "vscode-nls": "^2.0.2", - "yaml-ast-parser": "0.0.33" + "yaml-ast-parser": "0.0.34" }, "devDependencies": { "@types/js-yaml": "^3.5.31", From a144b47350cf63137dc50d72df8f300bbb04aab5 Mon Sep 17 00:00:00 2001 From: Adam Voss Date: Fri, 14 Jul 2017 19:42:26 -0500 Subject: [PATCH 3/4] Handle warnings from yaml-ast-parser as warnings --- src/parser/yamlParser.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/parser/yamlParser.ts b/src/parser/yamlParser.ts index 7248f5a..8ed56e1 100644 --- a/src/parser/yamlParser.ts +++ b/src/parser/yamlParser.ts @@ -367,8 +367,8 @@ export function parse(text: string): JSONDocument { const duplicateKeyReason = 'duplicate key' - const errors = yamlDoc.errors.filter(e => e.reason !== duplicateKeyReason).map(e => convertError(e)) - const warnings = yamlDoc.errors.filter(e => e.reason === duplicateKeyReason).map(e => convertError(e)) + 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)); From 54c8508147ac0023053bbdc75f692cf5a2be1ed8 Mon Sep 17 00:00:00 2001 From: Adam Voss Date: Fri, 14 Jul 2017 20:08:04 -0500 Subject: [PATCH 4/4] Remove code that was upstreamed into yaml-ast-parser --- src/parser/yamlParser.ts | 112 ++----------------- src/test/determineScalarType.test.ts | 161 --------------------------- 2 files changed, 9 insertions(+), 264 deletions(-) delete mode 100644 src/test/determineScalarType.test.ts diff --git a/src/parser/yamlParser.ts b/src/parser/yamlParser.ts index 8ed56e1..38ff279 100644 --- a/src/parser/yamlParser.ts +++ b/src/parser/yamlParser.ts @@ -200,32 +200,32 @@ function recursivelyBuildAst(parent: ASTNode, node: Yaml.YAMLNode): ASTNode { case Yaml.Kind.SCALAR: { const instance = node; - const type = determineScalarType(instance) + 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 ScalarType.null: { + case Yaml.ScalarType.null: { return new NullASTNode(parent, name, instance.startPosition, instance.endPosition); } - case ScalarType.bool: { - return new BooleanASTNode(parent, name, parseYamlBoolean(value), node.startPosition, node.endPosition) + case Yaml.ScalarType.bool: { + return new BooleanASTNode(parent, name, Yaml.parseYamlBoolean(value), node.startPosition, node.endPosition) } - case ScalarType.int: { + case Yaml.ScalarType.int: { const result = new NumberASTNode(parent, name, node.startPosition, node.endPosition); - result.value = parseYamlInteger(value); + result.value = Yaml.parseYamlInteger(value); result.isInteger = true; return result; } - case ScalarType.float: { + case Yaml.ScalarType.float: { const result = new NumberASTNode(parent, name, node.startPosition, node.endPosition); - result.value = parseYamlFloat(value); + result.value = Yaml.parseYamlFloat(value); result.isInteger = false; return result; } - case ScalarType.string: { + case Yaml.ScalarType.string: { const result = new StringASTNode(parent, name, false, node.startPosition, node.endPosition); result.value = node.value; return result; @@ -248,100 +248,6 @@ function recursivelyBuildAst(parent: ASTNode, node: Yaml.YAMLNode): ASTNode { } } -export function parseYamlBoolean(input: string): boolean { - if (["true", "True", "TRUE"].lastIndexOf(input) >= 0) { - return true; - } - else if (["false", "False", "FALSE"].lastIndexOf(input) >= 0) { - return false; - } - throw `Invalid boolean "${input}"` -} - -function safeParseYamlInteger(input: string): number { - // Use startsWith when es6 methods becomes available - if (input.lastIndexOf('0o', 0) === 0) { - return parseInt(input.substring(2), 8) - } - - return parseInt(input); -} - -export function parseYamlInteger(input: string): number { - const result = safeParseYamlInteger(input) - - if (isNaN(result)) { - throw `Invalid integer "${input}"` - } - - return result; -} - -export function parseYamlFloat(input: string): number { - - if ([".nan", ".NaN", ".NAN"].lastIndexOf(input) >= 0) { - return NaN; - } - - const infinity = /^([-+])?(?:\.inf|\.Inf|\.INF)$/ - const match = infinity.exec(input) - if (match) { - return (match[1] === '-') ? -Infinity : Infinity; - } - - const result = parseFloat(input) - - if (!isNaN(result)) { - return result; - } - - throw `Invalid float "${input}"` -} - -export enum ScalarType { - null, bool, int, float, string -} - -export function determineScalarType(node: Yaml.YAMLScalar): ScalarType { - if (node === undefined) { - return ScalarType.null; - } - - if (node.doubleQuoted || !node.plainScalar || node['singleQuoted']) { - return ScalarType.string - } - - const value = node.value; - - if (["null", "Null", "NULL", "~", ''].indexOf(value) >= 0) { - return ScalarType.null; - } - - if (value === null || value === undefined) { - return ScalarType.null; - } - - if (["true", "True", "TRUE", "false", "False", "FALSE"].indexOf(value) >= 0) { - return ScalarType.bool; - } - - const base10 = /^[-+]?[0-9]+$/ - const base8 = /^0o[0-7]+$/ - const base16 = /^0x[0-9a-fA-F]+$/ - - if (base10.test(value) || base8.test(value) || base16.test(value)) { - return ScalarType.int; - } - - const float = /^[-+]?(\.[0-9]+|[0-9]+(\.[0-9]*)?)([eE][-+]?[0-9]+)?$/ - const infinity = /^[-+]?(\.inf|\.Inf|\.INF)$/ - if (float.test(value) || infinity.test(value) || [".nan", ".NaN", ".NAN"].indexOf(value) >= 0) { - return ScalarType.float; - } - - return ScalarType.string; -} - 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; diff --git a/src/test/determineScalarType.test.ts b/src/test/determineScalarType.test.ts deleted file mode 100644 index bfca33a..0000000 --- a/src/test/determineScalarType.test.ts +++ /dev/null @@ -1,161 +0,0 @@ -import assert = require('assert'); -import { determineScalarType as sut, ScalarType, parseYamlBoolean, parseYamlInteger, parseYamlFloat } from '../parser/yamlParser' - -import * as Yaml from 'yaml-ast-parser' - -suite('determineScalarType', () => { - - function determineScalarType(scalar) { - return sut(scalar) - } - - function safeLoad(input) { - return Yaml.safeLoad(input, {}) - } - - let _test = test; - - // http://www.yaml.org/spec/1.2/spec.html#id2805071 - suite('Plain Tag Resolution', () => { - - function test(name, type, acceptable) { - _test(name, function () { - for (const word of acceptable) { - assert.strictEqual(determineScalarType(safeLoad(word)), type, word) - } - }) - }; - - test('boolean', ScalarType.bool, ["true", "True", "TRUE", "false", "False", "FALSE"]) - - test("null", ScalarType.null, ["null", "Null", "NULL", "~", ""]) - _test("null as from an array", function () { - const node = Yaml.newScalar(''); - node.plainScalar = true; - assert.strictEqual(determineScalarType(node), ScalarType.null, "unquoted empty string") - }) - - test("integer", ScalarType.int, ["0", "0o7", "0x3A", "-19"]) - - test("float", ScalarType.float, ["0.", "-0.0", ".5", "+12e03", "-2E+05"]) - - test("float-infinity", ScalarType.float, [".inf", "-.Inf", "+.INF"]) - - test("float-NaN", ScalarType.float, [".nan", ".NaN", ".NAN"]) - - test("string", ScalarType.string, ["'true'", "TrUe", "nULl", "''", "'0'", '"1"', '" .5"', ".inF", ".nAn"]) - }) - - suite('Flow style', () => { - test('still recognizes types', function () { - const node = safeLoad(`[ null, - true, - 0, - 0., - .inf, - .nan, - "-123\n345" -]`) - assert.deepStrictEqual(node.items.map(n => determineScalarType(n)), [ScalarType.null, ScalarType.bool, ScalarType.int, ScalarType.float, ScalarType.float, ScalarType.float, ScalarType.string]) - }) - }) - - suite('Block styles', () => { - var variations = ['>', '|', '>8', '|+1', '>-', '>+', '|-', '|+'] - - test('are always strings', function () { - for (const variant of variations) { - assert.deepEqual(determineScalarType(safeLoad(variant + "\n 123")), ScalarType.string); - } - }) - }) -}) - -suite('parseYamlInteger', () => { - test('decimal', function () { - assert.strictEqual(parseYamlInteger("0"), 0) - assert.strictEqual(parseYamlInteger("-19"), -19) - assert.strictEqual(parseYamlInteger("+1"), 1) - }) - - test('hexadecimal', function () { - assert.strictEqual(parseYamlInteger("0x3A"), 58) - }) - - test('octal', function () { - assert.strictEqual(parseYamlInteger("0o7"), 7) - }) - - test('otherwise', function () { - let error; - try { - parseYamlInteger("'1'") - } - catch (e) { - error = e; - } - - assert(error, "should have thrown") - }) -}) - -suite('parseYamlBoolean', () => { - test('true', function () { - for (const value of ["true", "True", "TRUE"]) { - assert.strictEqual(parseYamlBoolean(value), true, value); - } - }) - - test('false', function () { - for (const value of ["false", "False", "FALSE"]) { - assert.strictEqual(parseYamlBoolean(value), false, value); - } - }) - - test('otherwise', function () { - let error; - try { - parseYamlBoolean("tRUE") - } - catch (e) { - error = e; - } - - assert(error, "should have thrown") - }) -}) - -suite('parseYamlFloat', () => { - test('float', function () { - const values = ["0.", "-0.0", ".5", "+12e03", "-2E+05"] - const expected = [0, -0, 0.5, 12000, -200000] - for (var index = 0; index < values.length; index++) { - assert.strictEqual(parseYamlFloat(values[index]), expected[index]) - } - }) - - test('NaN', function () { - for (const value of [".nan", ".NaN", ".NAN"]) { - assert(isNaN(parseYamlFloat(value)), `isNaN(${value})`) - } - }) - - test('infinity', function () { - assert.strictEqual(parseYamlFloat(".inf"), - Infinity) - assert.strictEqual(parseYamlFloat("-.Inf"), -Infinity) - assert.strictEqual(parseYamlFloat(".INF"), Infinity) - }) - - test('otherwise', function () { - let error; - try { - parseYamlFloat("text") - } - catch (e) { - error = e; - } - - assert(error, "should have thrown") - }) -}) \ No newline at end of file