Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
de6dd9bc
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,发现更多精彩内容 >>
未验证
提交
de6dd9bc
编写于
6月 04, 2018
作者:
J
Johannes Rieken
提交者:
GitHub
6月 04, 2018
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #50940 from Microsoft/joh/uri-perf
faster toString, toJSON method
上级
8d400db3
88738c39
变更
5
展开全部
隐藏空白更改
内联
并排
Showing
5 changed file
with
3315 addition
and
85 deletion
+3315
-85
src/vs/base/common/uri.ts
src/vs/base/common/uri.ts
+173
-80
src/vs/base/node/encoding.ts
src/vs/base/node/encoding.ts
+1
-0
src/vs/base/test/node/uri.test.data.txt
src/vs/base/test/node/uri.test.data.txt
+3061
-0
src/vs/base/test/node/uri.test.perf.ts
src/vs/base/test/node/uri.test.perf.ts
+61
-0
src/vs/workbench/test/electron-browser/api/extHostTypes.test.ts
.../workbench/test/electron-browser/api/extHostTypes.test.ts
+19
-5
未找到文件。
src/vs/base/common/uri.ts
浏览文件 @
de6dd9bc
...
...
@@ -5,21 +5,7 @@
'
use strict
'
;
import
*
as
platform
from
'
vs/base/common/platform
'
;
function
_encode
(
ch
:
string
):
string
{
return
'
%
'
+
ch
.
charCodeAt
(
0
).
toString
(
16
).
toUpperCase
();
}
// see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
function
encodeURIComponent2
(
str
:
string
):
string
{
return
encodeURIComponent
(
str
).
replace
(
/
[
!'()*
]
/g
,
_encode
);
}
function
encodeNoop
(
str
:
string
):
string
{
return
str
.
replace
(
/
[
#?
]
/
,
_encode
);
}
import
{
CharCode
}
from
'
vs/base/common/charCode
'
;
const
_schemePattern
=
/^
\w[\w\d
+.-
]
*$/
;
const
_singleSlashStart
=
/^
\/
/
;
...
...
@@ -74,8 +60,6 @@ function _referenceResolution(scheme: string, path: string): string {
const
_empty
=
''
;
const
_slash
=
'
/
'
;
const
_regexp
=
/^
(([^
:
/
?#
]
+
?)
:
)?(\/\/([^/
?#
]
*
))?([^
?#
]
*
)(\?([^
#
]
*
))?(
#
(
.*
))?
/
;
const
_driveLetterPath
=
/^
\/[
a-zA-Z
]
:/
;
const
_upperCaseDrive
=
/^
(\/)?([
A-Z
]
:
)
/
;
/**
* Uniform Resource Identifier (URI) http://tools.ietf.org/html/rfc3986.
...
...
@@ -294,33 +278,7 @@ export default class URI implements UriComponents {
}
public
toJSON
():
object
{
const
res
=
<
UriState
>
{
$mid
:
1
,
fsPath
:
this
.
fsPath
,
external
:
this
.
toString
(),
};
if
(
this
.
path
)
{
res
.
path
=
this
.
path
;
}
if
(
this
.
scheme
)
{
res
.
scheme
=
this
.
scheme
;
}
if
(
this
.
authority
)
{
res
.
authority
=
this
.
authority
;
}
if
(
this
.
query
)
{
res
.
query
=
this
.
query
;
}
if
(
this
.
fragment
)
{
res
.
fragment
=
this
.
fragment
;
}
return
res
;
return
this
;
}
static
revive
(
data
:
UriComponents
|
any
):
URI
{
...
...
@@ -376,8 +334,141 @@ class _URI extends URI {
return
_asFormatted
(
this
,
true
);
}
}
toJSON
():
object
{
const
res
=
<
UriState
>
{
$mid
:
1
};
// cached state
if
(
this
.
_fsPath
)
{
res
.
fsPath
=
this
.
_fsPath
;
}
if
(
this
.
_formatted
)
{
res
.
external
=
this
.
_formatted
;
}
// uri components
if
(
this
.
path
)
{
res
.
path
=
this
.
path
;
}
if
(
this
.
scheme
)
{
res
.
scheme
=
this
.
scheme
;
}
if
(
this
.
authority
)
{
res
.
authority
=
this
.
authority
;
}
if
(
this
.
query
)
{
res
.
query
=
this
.
query
;
}
if
(
this
.
fragment
)
{
res
.
fragment
=
this
.
fragment
;
}
return
res
;
}
}
// reserved characters: https://tools.ietf.org/html/rfc3986#section-2.2
const
encodeTable
=
{
[
CharCode
.
Colon
]:
'
%3A
'
,
// gen-delims
[
CharCode
.
Slash
]:
'
%2F
'
,
[
CharCode
.
QuestionMark
]:
'
%3F
'
,
[
CharCode
.
Hash
]:
'
%23
'
,
[
CharCode
.
OpenSquareBracket
]:
'
%5B
'
,
[
CharCode
.
CloseSquareBracket
]:
'
%5D
'
,
[
CharCode
.
AtSign
]:
'
%40
'
,
[
CharCode
.
ExclamationMark
]:
'
%21
'
,
// sub-delims
[
CharCode
.
DollarSign
]:
'
%24
'
,
[
CharCode
.
Ampersand
]:
'
%26
'
,
[
CharCode
.
SingleQuote
]:
'
%27
'
,
[
CharCode
.
OpenParen
]:
'
%28
'
,
[
CharCode
.
CloseParen
]:
'
%29
'
,
[
CharCode
.
Asterisk
]:
'
%2A
'
,
[
CharCode
.
Plus
]:
'
%2B
'
,
[
CharCode
.
Comma
]:
'
%2C
'
,
[
CharCode
.
Semicolon
]:
'
%3B
'
,
[
CharCode
.
Equals
]:
'
%3D
'
,
[
CharCode
.
Space
]:
'
%20
'
,
};
function
encodeURIComponentFast
(
uriComponent
:
string
,
allowSlash
:
boolean
):
string
{
let
res
:
string
=
undefined
;
let
nativeEncodePos
=
-
1
;
for
(
let
pos
=
0
;
pos
<
uriComponent
.
length
;
pos
++
)
{
let
code
=
uriComponent
.
charCodeAt
(
pos
);
// unreserved characters: https://tools.ietf.org/html/rfc3986#section-2.3
if
(
(
code
>=
CharCode
.
a
&&
code
<=
CharCode
.
z
)
||
(
code
>=
CharCode
.
A
&&
code
<=
CharCode
.
Z
)
||
(
code
>=
CharCode
.
Digit0
&&
code
<=
CharCode
.
Digit9
)
||
code
===
CharCode
.
Dash
||
code
===
CharCode
.
Period
||
code
===
CharCode
.
Underline
||
code
===
CharCode
.
Tilde
||
(
allowSlash
&&
code
===
CharCode
.
Slash
)
)
{
// check if we are delaying native encode
if
(
nativeEncodePos
!==
-
1
)
{
res
+=
encodeURIComponent
(
uriComponent
.
substring
(
nativeEncodePos
,
pos
));
nativeEncodePos
=
-
1
;
}
// check if we write into a new string (by default we try to return the param)
if
(
res
!==
undefined
)
{
res
+=
uriComponent
.
charAt
(
pos
);
}
}
else
{
// encoding needed, we need to allocate a new string
if
(
res
===
undefined
)
{
res
=
uriComponent
.
substr
(
0
,
pos
);
}
// check with default table first
let
escaped
=
encodeTable
[
code
];
if
(
escaped
!==
undefined
)
{
// check if we are delaying native encode
if
(
nativeEncodePos
!==
-
1
)
{
res
+=
encodeURIComponent
(
uriComponent
.
substring
(
nativeEncodePos
,
pos
));
nativeEncodePos
=
-
1
;
}
// append escaped variant to result
res
+=
escaped
;
}
else
if
(
nativeEncodePos
===
-
1
)
{
// use native encode only when needed
nativeEncodePos
=
pos
;
}
}
}
if
(
nativeEncodePos
!==
-
1
)
{
res
+=
encodeURIComponent
(
uriComponent
.
substring
(
nativeEncodePos
));
}
return
res
!==
undefined
?
res
:
uriComponent
;
}
function
encodeURIComponentMinimal
(
path
:
string
):
string
{
let
res
:
string
=
undefined
;
for
(
let
pos
=
0
;
pos
<
path
.
length
;
pos
++
)
{
let
code
=
path
.
charCodeAt
(
pos
);
if
(
code
===
CharCode
.
Hash
||
code
===
CharCode
.
QuestionMark
)
{
if
(
res
===
undefined
)
{
res
=
path
.
substr
(
0
,
pos
);
}
res
+=
encodeTable
[
code
];
}
else
{
if
(
res
!==
undefined
)
{
res
+=
path
[
pos
];
}
}
}
return
res
!==
undefined
?
res
:
path
;
}
/**
* Compute `fsPath` for the given uri
...
...
@@ -389,7 +480,11 @@ function _makeFsPath(uri: URI): string {
if
(
uri
.
authority
&&
uri
.
path
.
length
>
1
&&
uri
.
scheme
===
'
file
'
)
{
// unc path: file://shares/c$/far/boo
value
=
`//
${
uri
.
authority
}${
uri
.
path
}
`
;
}
else
if
(
_driveLetterPath
.
test
(
uri
.
path
))
{
}
else
if
(
uri
.
path
.
charCodeAt
(
0
)
===
CharCode
.
Slash
&&
(
uri
.
path
.
charCodeAt
(
1
)
>=
CharCode
.
A
&&
uri
.
path
.
charCodeAt
(
1
)
<=
CharCode
.
Z
||
uri
.
path
.
charCodeAt
(
1
)
>=
CharCode
.
a
&&
uri
.
path
.
charCodeAt
(
1
)
<=
CharCode
.
z
)
&&
uri
.
path
.
charCodeAt
(
2
)
===
CharCode
.
Colon
)
{
// windows drive letter: file:///c:/far/boo
value
=
uri
.
path
[
1
].
toLowerCase
()
+
uri
.
path
.
substr
(
2
);
}
else
{
...
...
@@ -408,71 +503,69 @@ function _makeFsPath(uri: URI): string {
function
_asFormatted
(
uri
:
URI
,
skipEncoding
:
boolean
):
string
{
const
encoder
=
!
skipEncoding
?
encodeURIComponent2
:
encodeNoop
;
const
parts
:
string
[]
=
[];
?
encodeURIComponentFast
:
encodeURIComponentMinimal
;
let
res
=
''
;
let
{
scheme
,
authority
,
path
,
query
,
fragment
}
=
uri
;
if
(
scheme
)
{
parts
.
push
(
scheme
,
'
:
'
);
res
+=
scheme
;
res
+=
'
:
'
;
}
if
(
authority
||
scheme
===
'
file
'
)
{
parts
.
push
(
'
//
'
);
res
+=
_slash
;
res
+=
_slash
;
}
if
(
authority
)
{
let
idx
=
authority
.
indexOf
(
'
@
'
);
if
(
idx
!==
-
1
)
{
// <user>@<auth>
const
userinfo
=
authority
.
substr
(
0
,
idx
);
authority
=
authority
.
substr
(
idx
+
1
);
idx
=
userinfo
.
indexOf
(
'
:
'
);
if
(
idx
===
-
1
)
{
parts
.
push
(
encoder
(
userinfo
)
);
res
+=
encoder
(
userinfo
,
false
);
}
else
{
parts
.
push
(
encoder
(
userinfo
.
substr
(
0
,
idx
)),
'
:
'
,
encoder
(
userinfo
.
substr
(
idx
+
1
)));
// <user>:<pass>@<auth>
res
+=
encoder
(
userinfo
.
substr
(
0
,
idx
),
false
);
res
+=
'
:
'
;
res
+=
encoder
(
userinfo
.
substr
(
idx
+
1
),
false
);
}
parts
.
push
(
'
@
'
)
;
res
+=
'
@
'
;
}
authority
=
authority
.
toLowerCase
();
idx
=
authority
.
indexOf
(
'
:
'
);
if
(
idx
===
-
1
)
{
parts
.
push
(
encoder
(
authority
)
);
res
+=
encoder
(
authority
,
false
);
}
else
{
parts
.
push
(
encoder
(
authority
.
substr
(
0
,
idx
)),
authority
.
substr
(
idx
));
// <auth>:<port>
res
+=
encoder
(
authority
.
substr
(
0
,
idx
),
false
);
res
+=
authority
.
substr
(
idx
);
}
}
if
(
path
)
{
// lower-case windows drive letters in /C:/fff or C:/fff
const
m
=
_upperCaseDrive
.
exec
(
path
);
if
(
m
)
{
if
(
m
[
1
])
{
path
=
'
/
'
+
m
[
2
].
toLowerCase
()
+
path
.
substr
(
3
);
// "/c:".length === 3
}
else
{
path
=
m
[
2
].
toLowerCase
()
+
path
.
substr
(
2
);
// // "c:".length === 2
if
(
path
.
length
>=
3
&&
path
.
charCodeAt
(
0
)
===
CharCode
.
Slash
&&
path
.
charCodeAt
(
2
)
===
CharCode
.
Colon
)
{
let
code
=
path
.
charCodeAt
(
1
);
if
(
code
>=
CharCode
.
A
&&
code
<=
CharCode
.
Z
)
{
path
=
`/
${
String
.
fromCharCode
(
code
+
32
)}
:
${
path
.
substr
(
3
)}
`
;
// "/c:".length === 3
}
}
// encode every segement but not slashes
// make sure that # and ? are always encoded
// when occurring in paths - otherwise the result
// cannot be parsed back again
let
lastIdx
=
0
;
while
(
true
)
{
let
idx
=
path
.
indexOf
(
_slash
,
lastIdx
);
if
(
idx
===
-
1
)
{
parts
.
push
(
encoder
(
path
.
substring
(
lastIdx
)));
break
;
}
else
if
(
path
.
length
>=
2
&&
path
.
charCodeAt
(
1
)
===
CharCode
.
Colon
)
{
let
code
=
path
.
charCodeAt
(
0
);
if
(
code
>=
CharCode
.
A
&&
code
<=
CharCode
.
Z
)
{
path
=
`
${
String
.
fromCharCode
(
code
+
32
)}
:
${
path
.
substr
(
2
)}
`
;
// "/c:".length === 3
}
parts
.
push
(
encoder
(
path
.
substring
(
lastIdx
,
idx
)),
_slash
);
lastIdx
=
idx
+
1
;
}
// encode the rest of the path
res
+=
encoder
(
path
,
true
);
}
if
(
query
)
{
parts
.
push
(
'
?
'
,
encoder
(
query
));
res
+=
'
?
'
;
res
+=
encoder
(
query
,
false
);
}
if
(
fragment
)
{
parts
.
push
(
'
#
'
,
encoder
(
fragment
));
res
+=
'
#
'
;
res
+=
encoder
(
fragment
,
false
);
}
return
parts
.
join
(
_empty
);
return
res
;
}
src/vs/base/node/encoding.ts
浏览文件 @
de6dd9bc
...
...
@@ -89,6 +89,7 @@ export function toDecodeStream(readable: Readable, options: IDecodeStreamOptions
resolve
({
detected
,
stream
:
this
.
_decodeStream
});
},
err
=>
{
this
.
emit
(
'
error
'
,
err
);
callback
(
err
);
});
}
...
...
src/vs/base/test/node/uri.test.data.txt
0 → 100644
浏览文件 @
de6dd9bc
此差异已折叠。
点击以展开。
src/vs/base/test/node/uri.test.perf.ts
0 → 100644
浏览文件 @
de6dd9bc
/*---------------------------------------------------------------------------------------------
* 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
assert
from
'
assert
'
;
import
URI
from
'
vs/base/common/uri
'
;
import
{
readFileSync
}
from
'
fs
'
;
suite
(
'
URI - perf
'
,
function
()
{
let
manyFileUris
:
URI
[];
setup
(
function
()
{
manyFileUris
=
[];
let
data
=
readFileSync
(
URI
.
parse
(
require
.
toUrl
(
'
./uri.test.data.txt
'
)).
fsPath
).
toString
();
let
lines
=
data
.
split
(
'
\n
'
);
for
(
let
line
of
lines
)
{
manyFileUris
.
push
(
URI
.
file
(
line
));
}
});
function
perfTest
(
name
:
string
,
callback
:
Function
)
{
test
(
name
,
_done
=>
{
let
t1
=
Date
.
now
();
callback
();
let
d
=
Date
.
now
()
-
t1
;
console
.
log
(
`
${
name
}
took
${
d
}
ms (
${(
d
/
manyFileUris
.
length
).
toPrecision
(
3
)}
ms/uri)`
);
_done
();
});
}
perfTest
(
'
toString
'
,
function
()
{
for
(
const
uri
of
manyFileUris
)
{
let
data
=
uri
.
toString
();
assert
.
ok
(
data
);
}
});
perfTest
(
'
toString(skipEncoding)
'
,
function
()
{
for
(
const
uri
of
manyFileUris
)
{
let
data
=
uri
.
toString
(
true
);
assert
.
ok
(
data
);
}
});
perfTest
(
'
fsPath
'
,
function
()
{
for
(
const
uri
of
manyFileUris
)
{
let
data
=
uri
.
fsPath
;
assert
.
ok
(
data
);
}
});
perfTest
(
'
toJSON
'
,
function
()
{
for
(
const
uri
of
manyFileUris
)
{
let
data
=
uri
.
toJSON
();
assert
.
ok
(
data
);
}
});
});
src/vs/workbench/test/electron-browser/api/extHostTypes.test.ts
浏览文件 @
de6dd9bc
...
...
@@ -21,8 +21,22 @@ suite('ExtHostTypes', function () {
test
(
'
URI, toJSON
'
,
function
()
{
let
uri
=
URI
.
parse
(
'
file:///path/test.file
'
);
let
data
=
uri
.
toJSON
();
assert
.
deepEqual
(
data
,
{
assert
.
deepEqual
(
uri
.
toJSON
(),
{
$mid
:
1
,
scheme
:
'
file
'
,
path
:
'
/path/test.file
'
});
assert
.
ok
(
uri
.
fsPath
);
assert
.
deepEqual
(
uri
.
toJSON
(),
{
$mid
:
1
,
scheme
:
'
file
'
,
path
:
'
/path/test.file
'
,
fsPath
:
'
/path/test.file
'
.
replace
(
/
\/
/g
,
isWindows
?
'
\\
'
:
'
/
'
),
});
assert
.
ok
(
uri
.
toString
());
assert
.
deepEqual
(
uri
.
toJSON
(),
{
$mid
:
1
,
scheme
:
'
file
'
,
path
:
'
/path/test.file
'
,
...
...
@@ -342,15 +356,15 @@ suite('ExtHostTypes', function () {
edit
.
set
(
a
,
[
types
.
TextEdit
.
insert
(
new
types
.
Position
(
0
,
0
),
'
fff
'
)]);
assert
.
ok
(
edit
.
has
(
a
));
assert
.
equal
(
edit
.
size
,
1
);
assertToJSON
(
edit
,
[[
URI
.
parse
(
'
file:///a.ts
'
)
.
toJSON
(),
[{
range
:
[{
line
:
0
,
character
:
0
},
{
line
:
0
,
character
:
0
}],
newText
:
'
fff
'
}]]]);
assertToJSON
(
edit
,
[[
a
.
toJSON
(),
[{
range
:
[{
line
:
0
,
character
:
0
},
{
line
:
0
,
character
:
0
}],
newText
:
'
fff
'
}]]]);
edit
.
insert
(
b
,
new
types
.
Position
(
1
,
1
),
'
fff
'
);
edit
.
delete
(
b
,
new
types
.
Range
(
0
,
0
,
0
,
0
));
assert
.
ok
(
edit
.
has
(
b
));
assert
.
equal
(
edit
.
size
,
2
);
assertToJSON
(
edit
,
[
[
URI
.
parse
(
'
file:///a.ts
'
)
.
toJSON
(),
[{
range
:
[{
line
:
0
,
character
:
0
},
{
line
:
0
,
character
:
0
}],
newText
:
'
fff
'
}]],
[
URI
.
parse
(
'
file:///b.ts
'
)
.
toJSON
(),
[{
range
:
[{
line
:
1
,
character
:
1
},
{
line
:
1
,
character
:
1
}],
newText
:
'
fff
'
},
{
range
:
[{
line
:
0
,
character
:
0
},
{
line
:
0
,
character
:
0
}],
newText
:
''
}]]
[
a
.
toJSON
(),
[{
range
:
[{
line
:
0
,
character
:
0
},
{
line
:
0
,
character
:
0
}],
newText
:
'
fff
'
}]],
[
b
.
toJSON
(),
[{
range
:
[{
line
:
1
,
character
:
1
},
{
line
:
1
,
character
:
1
}],
newText
:
'
fff
'
},
{
range
:
[{
line
:
0
,
character
:
0
},
{
line
:
0
,
character
:
0
}],
newText
:
''
}]]
]);
edit
.
set
(
b
,
undefined
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录