Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
2317de3f
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
2317de3f
编写于
10月 18, 2018
作者:
M
Martin Aeschlimann
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
strict null checks for json utils (adopt latest jsonc-parser code)
上级
f5bfeb73
变更
9
展开全部
隐藏空白更改
内联
并排
Showing
9 changed file
with
590 addition
and
246 deletion
+590
-246
src/tsconfig.strictNullChecks.json
src/tsconfig.strictNullChecks.json
+6
-0
src/vs/base/common/json.ts
src/vs/base/common/json.ts
+425
-145
src/vs/base/common/jsonEdit.ts
src/vs/base/common/jsonEdit.ts
+37
-14
src/vs/base/common/jsonFormatter.ts
src/vs/base/common/jsonFormatter.ts
+97
-61
src/vs/base/test/common/json.test.ts
src/vs/base/test/common/json.test.ts
+17
-17
src/vs/base/test/common/jsonEdit.test.ts
src/vs/base/test/common/jsonEdit.test.ts
+2
-2
src/vs/base/test/common/jsonFormatter.test.ts
src/vs/base/test/common/jsonFormatter.test.ts
+3
-3
src/vs/platform/configuration/common/configurationModels.ts
src/vs/platform/configuration/common/configurationModels.ts
+2
-2
src/vs/platform/workspaces/electron-main/workspacesMainService.ts
...latform/workspaces/electron-main/workspacesMainService.ts
+1
-2
未找到文件。
src/tsconfig.strictNullChecks.json
浏览文件 @
2317de3f
...
...
@@ -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"
,
...
...
src/vs/base/common/json.ts
浏览文件 @
2317de3f
此差异已折叠。
点击以展开。
src/vs/base/common/jsonEdit.ts
浏览文件 @
2317de3f
...
...
@@ -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
src/vs/base/common/jsonFormatter.ts
浏览文件 @
2317de3f
...
...
@@ -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
,
range
Start
,
firstTokenStart
);
addEdit
(
initialIndent
,
formatText
Start
,
firstTokenStart
);
}
while
(
firstToken
!==
Json
.
SyntaxKind
.
EOF
)
{
let
firstTokenEnd
=
scanner
.
getTokenOffset
()
+
scanner
.
getTokenLength
()
+
range
Start
;
while
(
firstToken
!==
SyntaxKind
.
EOF
)
{
let
firstTokenEnd
=
scanner
.
getTokenOffset
()
+
scanner
.
getTokenLength
()
+
formatText
Start
;
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
()
+
range
Start
;
let
commentTokenStart
=
scanner
.
getTokenOffset
()
+
formatText
Start
;
addEdit
(
'
'
,
firstTokenEnd
,
commentTokenStart
);
firstTokenEnd
=
scanner
.
getTokenOffset
()
+
scanner
.
getTokenLength
()
+
range
Start
;
replaceContent
=
secondToken
===
Json
.
SyntaxKind
.
LineCommentTrivia
?
newLineAndIndent
()
:
''
;
firstTokenEnd
=
scanner
.
getTokenOffset
()
+
scanner
.
getTokenLength
()
+
formatText
Start
;
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
()
+
range
Start
;
let
secondTokenStart
=
scanner
.
getTokenOffset
()
+
formatText
Start
;
addEdit
(
replaceContent
,
firstTokenEnd
,
secondTokenStart
);
firstToken
=
secondToken
;
}
...
...
@@ -175,7 +211,7 @@ function repeat(s: string, count: number): string {
return
result
;
}
function
computeIndentLevel
(
content
:
string
,
o
ffset
:
number
,
o
ptions
:
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
src/vs/base/test/common/json.test.ts
浏览文件 @
2317de3f
...
...
@@ -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
:
tru
e
});
assertInvalidParse
(
'
{ "foo": true, }
'
,
{
foo
:
true
},
{
allowTrailingComma
:
fals
e
});
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
:
tru
e
});
assertInvalidParse
(
'
[ 1, 2, ]
'
,
[
1
,
2
],
{
allowTrailingComma
:
fals
e
});
assertInvalidParse
(
'
[ 1 2, 3 ]
'
,
[
1
,
2
,
3
]);
assertInvalidParse
(
'
[ ,1, 2, 3 ]
'
,
[
1
,
2
,
3
]);
assertInvalidParse
(
'
[ ,1, 2, 3, ]
'
,
[
1
,
2
,
3
],
{
disallowTrailingComma
:
tru
e
});
assertInvalidParse
(
'
[ ,1, 2, 3, ]
'
,
[
1
,
2
,
3
],
{
allowTrailingComma
:
fals
e
});
});
test
(
'
parse: disallow commments
'
,
()
=>
{
...
...
@@ -230,14 +230,14 @@ suite('JSON', () => {
// default is allow
assertValidParse
(
'
{ "hello": [], }
'
,
{
hello
:
[]
});
let
options
=
{
disallowTrailingComma
:
fals
e
};
let
options
=
{
allowTrailingComma
:
tru
e
};
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
:
tru
e
};
options
=
{
allowTrailingComma
:
fals
e
};
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
,
col
um
nOffset
:
7
,
children
:
[
type
:
'
property
'
,
offset
:
2
,
length
:
8
,
col
o
nOffset
:
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
,
col
um
nOffset
:
5
,
children
:
[
type
:
'
property
'
,
offset
:
1
,
length
:
9
,
col
o
nOffset
:
5
,
children
:
[
{
type
:
'
string
'
,
offset
:
1
,
length
:
4
,
value
:
'
id
'
},
{
type
:
'
string
'
,
offset
:
7
,
length
:
3
,
value
:
'
$
'
}
]
},
{
type
:
'
property
'
,
offset
:
12
,
length
:
18
,
col
um
nOffset
:
15
,
children
:
[
type
:
'
property
'
,
offset
:
12
,
length
:
18
,
col
o
nOffset
:
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
,
col
um
nOffset
:
7
,
children
:
[
type
:
'
property
'
,
offset
:
3
,
length
:
20
,
col
o
nOffset
:
7
,
children
:
[
{
type
:
'
string
'
,
offset
:
3
,
length
:
4
,
value
:
'
id
'
},
{
type
:
'
object
'
,
offset
:
9
,
length
:
14
,
children
:
[
{
type
:
'
property
'
,
offset
:
11
,
length
:
10
,
col
um
nOffset
:
16
,
children
:
[
type
:
'
property
'
,
offset
:
11
,
length
:
10
,
col
o
nOffset
:
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
:
tru
e
});
,
[
ParseErrorCode
.
PropertyNameExpected
,
ParseErrorCode
.
ValueExpected
],
{
allowTrailingComma
:
fals
e
});
});
});
src/vs/base/test/common/jsonEdit.test.ts
浏览文件 @
2317de3f
...
...
@@ -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
);
...
...
src/vs/base/test/common/jsonFormatter.test.ts
浏览文件 @
2317de3f
...
...
@@ -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": {}
'
,
...
...
src/vs/platform/configuration/common/configurationModels.ts
浏览文件 @
2317de3f
...
...
@@ -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
)
{
...
...
src/vs/platform/workspaces/electron-main/workspacesMainService.ts
浏览文件 @
2317de3f
...
...
@@ -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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录