提交 2317de3f 编写于 作者: M Martin Aeschlimann

strict null checks for json utils (adopt latest jsonc-parser code)

上级 f5bfeb73
......@@ -43,6 +43,9 @@
"./vs/base/browser/ui/splitview/splitview.ts",
"./vs/base/browser/ui/tree/tree.ts",
"./vs/base/browser/ui/widget.ts",
"./vs/base/common/json.ts",
"./vs/base/common/jsonEdit.ts",
"./vs/base/common/jsonFormatter.ts",
"./vs/base/node/console.ts",
"./vs/base/node/crypto.ts",
"./vs/base/node/decoder.ts",
......@@ -62,6 +65,9 @@
"./vs/base/parts/ipc/node/ipc.ts",
"./vs/base/parts/ipc/test/node/testService.ts",
"./vs/base/parts/quickopen/common/quickOpen.ts",
"./vs/base/test/common/json.test.ts",
"./vs/base/test/common/jsonEdit.test.ts",
"./vs/base/test/common/jsonFormatter.test.ts",
"./vs/base/test/common/utils.ts",
"./vs/base/test/node/processes/fixtures/fork.ts",
"./vs/base/test/node/processes/fixtures/fork_large.ts",
......
此差异已折叠。
......@@ -2,15 +2,18 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { ParseError, Node, JSONPath, Segment, parseTree, findNodeAtLocation } from './json';
import { Edit, format, isEOL, FormattingOptions } from './jsonFormatter';
import { ParseError, Node, parseTree, findNodeAtLocation, JSONPath, Segment } from 'vs/base/common/json';
import { Edit, FormattingOptions, format, applyEdit } from 'vs/base/common/jsonFormatter';
export function removeProperty(text: string, path: JSONPath, formattingOptions: FormattingOptions): Edit[] {
return setProperty(text, path, void 0, formattingOptions);
}
export function setProperty(text: string, path: JSONPath, value: any, formattingOptions: FormattingOptions, getInsertionIndex?: (properties: string[]) => number): Edit[] {
export function setProperty(text: string, originalPath: JSONPath, value: any, formattingOptions: FormattingOptions, getInsertionIndex?: (properties: string[]) => number): Edit[] {
let path = originalPath.slice();
let errors: ParseError[] = [];
let root = parseTree(text, errors);
let parent: Node | undefined = void 0;
......@@ -36,20 +39,23 @@ export function setProperty(text: string, path: JSONPath, value: any, formatting
throw new Error('Can not delete in empty document');
}
return withFormatting(text, { offset: root ? root.offset : 0, length: root ? root.length : 0, content: JSON.stringify(value) }, formattingOptions);
} else if (parent.type === 'object' && typeof lastSegment === 'string') {
} else if (parent.type === 'object' && typeof lastSegment === 'string' && Array.isArray(parent.children)) {
let existing = findNodeAtLocation(parent, [lastSegment]);
if (existing !== void 0) {
if (value === void 0) { // delete
let propertyIndex = parent.children && existing.parent ? parent.children.indexOf(existing.parent) : -1;
if (!existing.parent) {
throw new Error('Malformed AST');
}
let propertyIndex = parent.children.indexOf(existing.parent);
let removeBegin: number;
let removeEnd = existing.parent!.offset + existing.parent!.length;
let removeEnd = existing.parent.offset + existing.parent.length;
if (propertyIndex > 0) {
// remove the comma of the previous node
let previous = parent.children![propertyIndex - 1];
let previous = parent.children[propertyIndex - 1];
removeBegin = previous.offset + previous.length;
} else {
removeBegin = parent.offset + 1;
if (parent.children && parent.children.length > 1) {
if (parent.children.length > 1) {
// remove the comma of the next node
let next = parent.children[1];
removeEnd = next.offset;
......@@ -65,25 +71,25 @@ export function setProperty(text: string, path: JSONPath, value: any, formatting
return []; // property does not exist, nothing to do
}
let newProperty = `${JSON.stringify(lastSegment)}: ${JSON.stringify(value)}`;
let index = getInsertionIndex ? getInsertionIndex(parent.children!.map(p => p.children![0].value)) : parent.children!.length;
let index = getInsertionIndex ? getInsertionIndex(parent.children.map(p => p.children![0].value)) : parent.children.length;
let edit: Edit;
if (index > 0) {
let previous = parent.children![index - 1];
let previous = parent.children[index - 1];
edit = { offset: previous.offset + previous.length, length: 0, content: ',' + newProperty };
} else if (parent.children!.length === 0) {
} else if (parent.children.length === 0) {
edit = { offset: parent.offset + 1, length: 0, content: newProperty };
} else {
edit = { offset: parent.offset + 1, length: 0, content: newProperty + ',' };
}
return withFormatting(text, edit, formattingOptions);
}
} else if (parent.type === 'array' && typeof lastSegment === 'number') {
} else if (parent.type === 'array' && typeof lastSegment === 'number' && Array.isArray(parent.children)) {
let insertIndex = lastSegment;
if (insertIndex === -1) {
// Insert
let newProperty = `${JSON.stringify(value)}`;
let edit: Edit;
if (!parent.children || parent.children.length === 0) {
if (parent.children.length === 0) {
edit = { offset: parent.offset + 1, length: 0, content: newProperty };
} else {
let previous = parent.children[parent.children.length - 1];
......@@ -91,7 +97,7 @@ export function setProperty(text: string, path: JSONPath, value: any, formatting
}
return withFormatting(text, edit, formattingOptions);
} else {
if (value === void 0 && parent.children && parent.children.length >= 0) {
if (value === void 0 && parent.children.length >= 0) {
//Removal
let removalIndex = lastSegment;
let toRemove = parent.children[removalIndex];
......@@ -125,6 +131,15 @@ function withFormatting(text: string, edit: Edit, formattingOptions: FormattingO
// format the new text
let begin = edit.offset;
let end = edit.offset + edit.content.length;
if (edit.length === 0 || edit.content.length === 0) { // insert or remove
while (begin > 0 && !isEOL(newText, begin - 1)) {
begin--;
}
while (end < newText.length && !isEOL(newText, end)) {
end++;
}
}
let edits = format(newText, { offset: begin, length: end - begin }, formattingOptions);
// apply the formatting edits and track the begin and end offsets of the changes
......@@ -138,4 +153,12 @@ function withFormatting(text: string, edit: Edit, formattingOptions: FormattingO
// create a single edit with all changes
let editLength = text.length - (newText.length - end) - begin;
return [{ offset: begin, length: editLength, content: newText.substring(begin, end) }];
}
export function applyEdit(text: string, edit: Edit): string {
return text.substring(0, edit.offset) + edit.content + text.substring(edit.offset + edit.length);
}
export function isWS(text: string, offset: number) {
return '\r\n \t'.indexOf(text.charAt(offset)) !== -1;
}
\ No newline at end of file
......@@ -2,64 +2,84 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as Json from './json';
import { createScanner, SyntaxKind, ScanError } from './json';
export interface FormattingOptions {
/**
* If indentation is based on spaces (`insertSpaces` = true), then what is the number of spaces that make an indent?
*/
tabSize: number;
tabSize?: number;
/**
* Is indentation based on spaces?
*/
insertSpaces: boolean;
insertSpaces?: boolean;
/**
* The default end of line line character
* The default 'end of line' character. If not set, '\n' is used as default.
*/
eol: string;
eol?: string;
}
/**
* Represents a text modification
*/
export interface Edit {
/**
* The start offset of the modification.
*/
offset: number;
/**
* The length of the modification. Must not be negative. Empty length represents an *insert*.
*/
length: number;
/**
* The new content. Empty content represents a *remove*.
*/
content: string;
}
export function applyEdit(text: string, edit: Edit): string {
return text.substring(0, edit.offset) + edit.content + text.substring(edit.offset + edit.length);
/**
* A text range in the document
*/
export interface Range {
/**
* The start offset of the range.
*/
offset: number;
/**
* The length of the range. Must not be negative.
*/
length: number;
}
export function applyEdits(text: string, edits: Edit[]): string {
for (let i = edits.length - 1; i >= 0; i--) {
text = applyEdit(text, edits[i]);
}
return text;
}
export function format(documentText: string, range: { offset: number, length: number }, options: FormattingOptions): Edit[] {
export function format(documentText: string, range: Range | undefined, options: FormattingOptions): Edit[] {
let initialIndentLevel: number;
let value: string;
let formatText: string;
let formatTextStart: number;
let rangeStart: number;
let rangeEnd: number;
if (range) {
rangeStart = range.offset;
rangeEnd = rangeStart + range.length;
while (rangeStart > 0 && !isEOL(documentText, rangeStart - 1)) {
rangeStart--;
}
let scanner = Json.createScanner(documentText, true);
scanner.setPosition(rangeEnd);
scanner.scan();
rangeEnd = scanner.getPosition();
value = documentText.substring(rangeStart, rangeEnd);
initialIndentLevel = computeIndentLevel(value, 0, options);
formatTextStart = rangeStart;
while (formatTextStart > 0 && !isEOL(documentText, formatTextStart - 1)) {
formatTextStart--;
}
let endOffset = rangeEnd;
while (endOffset < documentText.length && !isEOL(documentText, endOffset)) {
endOffset++;
}
formatText = documentText.substring(formatTextStart, endOffset);
initialIndentLevel = computeIndentLevel(formatText, options);
} else {
value = documentText;
formatText = documentText;
initialIndentLevel = 0;
formatTextStart = 0;
rangeStart = 0;
rangeEnd = documentText.length;
initialIndentLevel = 0;
}
let eol = getEOL(options, documentText);
......@@ -67,75 +87,78 @@ export function format(documentText: string, range: { offset: number, length: nu
let indentLevel = 0;
let indentValue: string;
if (options.insertSpaces) {
indentValue = repeat(' ', options.tabSize);
indentValue = repeat(' ', options.tabSize || 4);
} else {
indentValue = '\t';
}
let scanner = Json.createScanner(value, false);
let scanner = createScanner(formatText, false);
let hasError = false;
function newLineAndIndent(): string {
return eol + repeat(indentValue, initialIndentLevel + indentLevel);
}
function scanNext(): Json.SyntaxKind {
function scanNext(): SyntaxKind {
let token = scanner.scan();
lineBreak = false;
while (token === Json.SyntaxKind.Trivia || token === Json.SyntaxKind.LineBreakTrivia) {
lineBreak = lineBreak || (token === Json.SyntaxKind.LineBreakTrivia);
while (token === SyntaxKind.Trivia || token === SyntaxKind.LineBreakTrivia) {
lineBreak = lineBreak || (token === SyntaxKind.LineBreakTrivia);
token = scanner.scan();
}
hasError = token === SyntaxKind.Unknown || scanner.getTokenError() !== ScanError.None;
return token;
}
let editOperations: Edit[] = [];
function addEdit(text: string, startOffset: number, endOffset: number) {
if (documentText.substring(startOffset, endOffset) !== text) {
if (!hasError && startOffset < rangeEnd && endOffset > rangeStart && documentText.substring(startOffset, endOffset) !== text) {
editOperations.push({ offset: startOffset, length: endOffset - startOffset, content: text });
}
}
let firstToken = scanNext();
if (firstToken !== Json.SyntaxKind.EOF) {
let firstTokenStart = scanner.getTokenOffset() + rangeStart;
if (firstToken !== SyntaxKind.EOF) {
let firstTokenStart = scanner.getTokenOffset() + formatTextStart;
let initialIndent = repeat(indentValue, initialIndentLevel);
addEdit(initialIndent, rangeStart, firstTokenStart);
addEdit(initialIndent, formatTextStart, firstTokenStart);
}
while (firstToken !== Json.SyntaxKind.EOF) {
let firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + rangeStart;
while (firstToken !== SyntaxKind.EOF) {
let firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;
let secondToken = scanNext();
let replaceContent = '';
while (!lineBreak && (secondToken === Json.SyntaxKind.LineCommentTrivia || secondToken === Json.SyntaxKind.BlockCommentTrivia)) {
while (!lineBreak && (secondToken === SyntaxKind.LineCommentTrivia || secondToken === SyntaxKind.BlockCommentTrivia)) {
// comments on the same line: keep them on the same line, but ignore them otherwise
let commentTokenStart = scanner.getTokenOffset() + rangeStart;
let commentTokenStart = scanner.getTokenOffset() + formatTextStart;
addEdit(' ', firstTokenEnd, commentTokenStart);
firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + rangeStart;
replaceContent = secondToken === Json.SyntaxKind.LineCommentTrivia ? newLineAndIndent() : '';
firstTokenEnd = scanner.getTokenOffset() + scanner.getTokenLength() + formatTextStart;
replaceContent = secondToken === SyntaxKind.LineCommentTrivia ? newLineAndIndent() : '';
secondToken = scanNext();
}
if (secondToken === Json.SyntaxKind.CloseBraceToken) {
if (firstToken !== Json.SyntaxKind.OpenBraceToken) {
if (secondToken === SyntaxKind.CloseBraceToken) {
if (firstToken !== SyntaxKind.OpenBraceToken) {
indentLevel--;
replaceContent = newLineAndIndent();
}
} else if (secondToken === Json.SyntaxKind.CloseBracketToken) {
if (firstToken !== Json.SyntaxKind.OpenBracketToken) {
} else if (secondToken === SyntaxKind.CloseBracketToken) {
if (firstToken !== SyntaxKind.OpenBracketToken) {
indentLevel--;
replaceContent = newLineAndIndent();
}
} else if (secondToken !== Json.SyntaxKind.EOF) {
} else {
switch (firstToken) {
case Json.SyntaxKind.OpenBracketToken:
case Json.SyntaxKind.OpenBraceToken:
case SyntaxKind.OpenBracketToken:
case SyntaxKind.OpenBraceToken:
indentLevel++;
replaceContent = newLineAndIndent();
break;
case Json.SyntaxKind.CommaToken:
case Json.SyntaxKind.LineCommentTrivia:
case SyntaxKind.CommaToken:
case SyntaxKind.LineCommentTrivia:
replaceContent = newLineAndIndent();
break;
case Json.SyntaxKind.BlockCommentTrivia:
case SyntaxKind.BlockCommentTrivia:
if (lineBreak) {
replaceContent = newLineAndIndent();
} else {
......@@ -143,24 +166,37 @@ export function format(documentText: string, range: { offset: number, length: nu
replaceContent = ' ';
}
break;
case Json.SyntaxKind.ColonToken:
case SyntaxKind.ColonToken:
replaceContent = ' ';
break;
case Json.SyntaxKind.NullKeyword:
case Json.SyntaxKind.TrueKeyword:
case Json.SyntaxKind.FalseKeyword:
case Json.SyntaxKind.NumericLiteral:
if (secondToken === Json.SyntaxKind.NullKeyword || secondToken === Json.SyntaxKind.FalseKeyword || secondToken === Json.SyntaxKind.NumericLiteral) {
case SyntaxKind.StringLiteral:
if (secondToken === SyntaxKind.ColonToken) {
replaceContent = '';
break;
}
// fall through
case SyntaxKind.NullKeyword:
case SyntaxKind.TrueKeyword:
case SyntaxKind.FalseKeyword:
case SyntaxKind.NumericLiteral:
case SyntaxKind.CloseBraceToken:
case SyntaxKind.CloseBracketToken:
if (secondToken === SyntaxKind.LineCommentTrivia || secondToken === SyntaxKind.BlockCommentTrivia) {
replaceContent = ' ';
} else if (secondToken !== SyntaxKind.CommaToken && secondToken !== SyntaxKind.EOF) {
hasError = true;
}
break;
case SyntaxKind.Unknown:
hasError = true;
break;
}
if (lineBreak && (secondToken === Json.SyntaxKind.LineCommentTrivia || secondToken === Json.SyntaxKind.BlockCommentTrivia)) {
if (lineBreak && (secondToken === SyntaxKind.LineCommentTrivia || secondToken === SyntaxKind.BlockCommentTrivia)) {
replaceContent = newLineAndIndent();
}
}
let secondTokenStart = scanner.getTokenOffset() + rangeStart;
let secondTokenStart = scanner.getTokenOffset() + formatTextStart;
addEdit(replaceContent, firstTokenEnd, secondTokenStart);
firstToken = secondToken;
}
......@@ -175,7 +211,7 @@ function repeat(s: string, count: number): string {
return result;
}
function computeIndentLevel(content: string, offset: number, options: FormattingOptions): number {
function computeIndentLevel(content: string, options: FormattingOptions): number {
let i = 0;
let nChars = 0;
let tabSize = options.tabSize || 4;
......@@ -208,6 +244,6 @@ function getEOL(options: FormattingOptions, text: string): string {
return (options && options.eol) || '\n';
}
function isEOL(text: string, offset: number) {
export function isEOL(text: string, offset: number) {
return '\r\n'.indexOf(text.charAt(offset)) !== -1;
}
\ No newline at end of file
......@@ -23,8 +23,8 @@ function assertScanError(text: string, expectedKind: SyntaxKind, scanError: Scan
assert.equal(scanner.getTokenError(), scanError);
}
function assertValidParse(input: string, expected: any, options?: ParseOptions): void {
var errors: { error: ParseErrorCode }[] = [];
function assertValidParse(input: string, expected: any, options: ParseOptions = { allowTrailingComma: true }): void {
var errors: ParseError[] = [];
var actual = parse(input, errors, options);
if (errors.length !== 0) {
......@@ -33,15 +33,15 @@ function assertValidParse(input: string, expected: any, options?: ParseOptions):
assert.deepEqual(actual, expected);
}
function assertInvalidParse(input: string, expected: any, options?: ParseOptions): void {
var errors: { error: ParseErrorCode }[] = [];
function assertInvalidParse(input: string, expected: any, options: ParseOptions = { allowTrailingComma: true }): void {
var errors: ParseError[] = [];
var actual = parse(input, errors, options);
assert(errors.length > 0);
assert.deepEqual(actual, expected);
}
function assertTree(input: string, expected: any, expectedErrors: number[] = [], options?: ParseOptions): void {
function assertTree(input: string, expected: any, expectedErrors: number[] = [], options: ParseOptions = { allowTrailingComma: true }): void {
var errors: ParseError[] = [];
var actual = parseTree(input, errors, options);
......@@ -50,7 +50,7 @@ function assertTree(input: string, expected: any, expectedErrors: number[] = [],
if (node.children) {
for (let child of node.children) {
assert.equal(node, child.parent);
delete child.parent; // delete to avoid recursion in deep equal
delete (<any>child).parent; // delete to avoid recursion in deep equal
checkParent(child);
}
}
......@@ -201,7 +201,7 @@ suite('JSON', () => {
test('parse: objects with errors', () => {
assertInvalidParse('{,}', {});
assertInvalidParse('{ "foo": true, }', { foo: true }, { disallowTrailingComma: true });
assertInvalidParse('{ "foo": true, }', { foo: true }, { allowTrailingComma: false });
assertInvalidParse('{ "bar": 8 "xoo": "foo" }', { bar: 8, xoo: 'foo' });
assertInvalidParse('{ ,"bar": 8 }', { bar: 8 });
assertInvalidParse('{ ,"bar": 8, "foo" }', { bar: 8 });
......@@ -211,10 +211,10 @@ suite('JSON', () => {
test('parse: array with errors', () => {
assertInvalidParse('[,]', []);
assertInvalidParse('[ 1, 2, ]', [1, 2], { disallowTrailingComma: true });
assertInvalidParse('[ 1, 2, ]', [1, 2], { allowTrailingComma: false });
assertInvalidParse('[ 1 2, 3 ]', [1, 2, 3]);
assertInvalidParse('[ ,1, 2, 3 ]', [1, 2, 3]);
assertInvalidParse('[ ,1, 2, 3, ]', [1, 2, 3], { disallowTrailingComma: true });
assertInvalidParse('[ ,1, 2, 3, ]', [1, 2, 3], { allowTrailingComma: false });
});
test('parse: disallow commments', () => {
......@@ -230,14 +230,14 @@ suite('JSON', () => {
// default is allow
assertValidParse('{ "hello": [], }', { hello: [] });
let options = { disallowTrailingComma: false };
let options = { allowTrailingComma: true };
assertValidParse('{ "hello": [], }', { hello: [] }, options);
assertValidParse('{ "hello": [] }', { hello: [] }, options);
assertValidParse('{ "hello": [], "world": {}, }', { hello: [], world: {} }, options);
assertValidParse('{ "hello": [], "world": {} }', { hello: [], world: {} }, options);
assertValidParse('{ "hello": [1,] }', { hello: [1] }, options);
options = { disallowTrailingComma: true };
options = { allowTrailingComma: false };
assertInvalidParse('{ "hello": [], }', { hello: [] }, options);
assertInvalidParse('{ "hello": [], "world": {}, }', { hello: [], world: {} }, options);
});
......@@ -272,7 +272,7 @@ suite('JSON', () => {
assertTree('{ "val": 1 }', {
type: 'object', offset: 0, length: 12, children: [
{
type: 'property', offset: 2, length: 8, columnOffset: 7, children: [
type: 'property', offset: 2, length: 8, colonOffset: 7, children: [
{ type: 'string', offset: 2, length: 5, value: 'val' },
{ type: 'number', offset: 9, length: 1, value: 1 }
]
......@@ -283,13 +283,13 @@ suite('JSON', () => {
{
type: 'object', offset: 0, length: 32, children: [
{
type: 'property', offset: 1, length: 9, columnOffset: 5, children: [
type: 'property', offset: 1, length: 9, colonOffset: 5, children: [
{ type: 'string', offset: 1, length: 4, value: 'id' },
{ type: 'string', offset: 7, length: 3, value: '$' }
]
},
{
type: 'property', offset: 12, length: 18, columnOffset: 15, children: [
type: 'property', offset: 12, length: 18, colonOffset: 15, children: [
{ type: 'string', offset: 12, length: 3, value: 'v' },
{
type: 'array', offset: 17, length: 13, children: [
......@@ -306,12 +306,12 @@ suite('JSON', () => {
{
type: 'object', offset: 0, length: 27, children: [
{
type: 'property', offset: 3, length: 20, columnOffset: 7, children: [
type: 'property', offset: 3, length: 20, colonOffset: 7, children: [
{ type: 'string', offset: 3, length: 4, value: 'id' },
{
type: 'object', offset: 9, length: 14, children: [
{
type: 'property', offset: 11, length: 10, columnOffset: 16, children: [
type: 'property', offset: 11, length: 10, colonOffset: 16, children: [
{ type: 'string', offset: 11, length: 5, value: 'foo' },
{ type: 'object', offset: 18, length: 3, children: [] }
]
......@@ -322,6 +322,6 @@ suite('JSON', () => {
}
]
}
, [ParseErrorCode.PropertyNameExpected, ParseErrorCode.ValueExpected], { disallowTrailingComma: true });
, [ParseErrorCode.PropertyNameExpected, ParseErrorCode.ValueExpected], { allowTrailingComma: false });
});
});
......@@ -101,13 +101,13 @@ suite('JSON - edits', () => {
content = '//comment';
edits = setProperty(content, ['foo', 0], 'bar', formatterOptions);
assertEdit(content, edits, '{\n "foo": [\n "bar"\n ]\n} //comment\n');
assertEdit(content, edits, '{\n "foo": [\n "bar"\n ]\n} //comment');
});
test('remove property', () => {
let content = '{\n "x": "y"\n}';
let edits = removeProperty(content, ['x'], formatterOptions);
assertEdit(content, edits, '{}');
assertEdit(content, edits, '{\n}');
content = '{\n "x": "y", "a": []\n}';
edits = removeProperty(content, ['x'], formatterOptions);
......
......@@ -8,7 +8,7 @@ import * as assert from 'assert';
suite('JSON - formatter', () => {
function format(content: string, expected: string, insertSpaces = true) {
let range = void 0;
let range: Formatter.Range | undefined = void 0;
var rangeStart = content.indexOf('|');
var rangeEnd = content.lastIndexOf('|');
if (rangeStart !== -1 && rangeEnd !== -1) {
......@@ -344,12 +344,12 @@ suite('JSON - formatter', () => {
'{ "a": {},',
' |"b": [null],',
'"c": {}',
'} |'
'}|'
].join('\n');
var expected = [
'{ "a": {},',
' "b": [',
' "b": [',
' null',
' ],',
' "c": {}',
......
......@@ -249,8 +249,8 @@ export class ConfigurationModelParser {
currentParent = previousParents.pop();
},
onLiteralValue: onValue,
onError: (error: json.ParseErrorCode) => {
parseErrors.push({ error: error });
onError: (error: json.ParseErrorCode, offset: number, length: number) => {
parseErrors.push({ error, offset, length });
}
};
if (content) {
......
......@@ -19,7 +19,6 @@ import { coalesce } from 'vs/base/common/arrays';
import { createHash } from 'crypto';
import * as json from 'vs/base/common/json';
import * as jsonEdit from 'vs/base/common/jsonEdit';
import { applyEdit } from 'vs/base/common/jsonFormatter';
import { massageFolderPathForWorkspace } from 'vs/platform/workspaces/node/workspaces';
import { toWorkspaceFolders } from 'vs/platform/workspace/common/workspace';
import { URI } from 'vs/base/common/uri';
......@@ -231,7 +230,7 @@ export class WorkspacesMainService implements IWorkspacesMainService {
let newRawWorkspaceContents = rawWorkspaceContents;
const edits = jsonEdit.setProperty(rawWorkspaceContents, ['folders'], storedWorkspace.folders, { insertSpaces: false, tabSize: 4, eol: (isLinux || isMacintosh) ? '\n' : '\r\n' });
edits.forEach(edit => {
newRawWorkspaceContents = applyEdit(rawWorkspaceContents, edit);
newRawWorkspaceContents = jsonEdit.applyEdit(rawWorkspaceContents, edit);
});
return writeFile(targetConfigPath, newRawWorkspaceContents).then(() => {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册