Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
809386b6
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,体验更适合开发者的 AI 搜索 >>
提交
809386b6
编写于
6月 03, 2019
作者:
M
Matt Bierner
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Working on getting ts server class in a testable state
上级
0b4d3cd6
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
174 addition
and
37 deletion
+174
-37
extensions/typescript-language-features/src/test/server.test.ts
...ions/typescript-language-features/src/test/server.test.ts
+76
-0
extensions/typescript-language-features/src/tsServer/server.ts
...sions/typescript-language-features/src/tsServer/server.ts
+82
-27
extensions/typescript-language-features/src/typescriptServiceClient.ts
...pescript-language-features/src/typescriptServiceClient.ts
+2
-2
extensions/typescript-language-features/src/utils/telemetry.ts
...sions/typescript-language-features/src/utils/telemetry.ts
+14
-8
未找到文件。
extensions/typescript-language-features/src/test/server.test.ts
0 → 100644
浏览文件 @
809386b6
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
*
as
assert
from
'
assert
'
;
import
'
mocha
'
;
import
*
as
stream
from
'
stream
'
;
import
{
PipeRequestCanceller
,
ServerProcess
,
TypeScriptServer
}
from
'
../tsServer/server
'
;
import
{
nulToken
}
from
'
../utils/cancellation
'
;
import
Logger
from
'
../utils/logger
'
;
import
TelemetryReporter
from
'
../utils/telemetry
'
;
import
Tracer
from
'
../utils/tracer
'
;
import
*
as
Proto
from
'
../protocol
'
;
const
NoopTelemetryReporter
=
new
class
implements
TelemetryReporter
{
logTelemetry
():
void
{
/* noop */
}
dispose
():
void
{
/* noop */
}
};
class
FakeServerProcess
implements
ServerProcess
{
private
readonly
_out
:
stream
.
PassThrough
;
private
readonly
writeListeners
=
new
Set
<
(
data
:
Buffer
)
=>
void
>
();
public
stdout
:
stream
.
PassThrough
;
constructor
()
{
this
.
_out
=
new
stream
.
PassThrough
();
this
.
stdout
=
this
.
_out
;
}
public
write
(
data
:
Proto
.
Request
)
{
const
listeners
=
Array
.
from
(
this
.
writeListeners
);
this
.
writeListeners
.
clear
();
setImmediate
(()
=>
{
for
(
const
listener
of
listeners
)
{
listener
(
Buffer
.
from
(
JSON
.
stringify
(
data
),
'
utf8
'
));
}
const
body
=
Buffer
.
from
(
JSON
.
stringify
({
'
seq
'
:
data
.
seq
,
'
type
'
:
'
response
'
,
'
command
'
:
data
.
command
,
'
request_seq
'
:
data
.
seq
,
'
success
'
:
true
}),
'
utf8
'
);
this
.
_out
.
write
(
Buffer
.
from
(
`Content-Length:
${
body
.
length
}
\r\n\r\n
${
body
}
`
,
'
utf8
'
));
});
}
on
(
_name
:
any
,
_handler
:
any
)
{
/* noop */
}
kill
():
void
{
/* noop */
}
public
onWrite
():
Promise
<
any
>
{
return
new
Promise
<
string
>
((
resolve
)
=>
{
this
.
writeListeners
.
add
((
data
)
=>
{
resolve
(
JSON
.
parse
(
data
.
toString
()));
});
});
}
}
suite
(
'
Server
'
,
()
=>
{
const
tracer
=
new
Tracer
(
new
Logger
());
test
(
'
should send requests with increasing sequence numbers
'
,
async
()
=>
{
const
process
=
new
FakeServerProcess
();
const
server
=
new
TypeScriptServer
(
process
,
undefined
,
new
PipeRequestCanceller
(
undefined
,
tracer
),
undefined
!
,
NoopTelemetryReporter
,
tracer
);
const
onWrite1
=
process
.
onWrite
();
server
.
executeImpl
(
'
geterr
'
,
{},
{
isAsync
:
false
,
token
:
nulToken
,
expectsResult
:
true
});
assert
.
strictEqual
((
await
onWrite1
).
seq
,
0
);
const
onWrite2
=
process
.
onWrite
();
server
.
executeImpl
(
'
geterr
'
,
{},
{
isAsync
:
false
,
token
:
nulToken
,
expectsResult
:
true
});
assert
.
strictEqual
((
await
onWrite2
).
seq
,
1
);
});
});
extensions/typescript-language-features/src/tsServer/server.ts
浏览文件 @
809386b6
...
...
@@ -3,9 +3,10 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
*
as
c
p
from
'
child_process
'
;
import
*
as
c
hild_process
from
'
child_process
'
;
import
*
as
fs
from
'
fs
'
;
import
*
as
path
from
'
path
'
;
import
*
as
stream
from
'
stream
'
;
import
*
as
vscode
from
'
vscode
'
;
import
*
as
Proto
from
'
../protocol
'
;
import
{
ServerResponse
}
from
'
../typescriptService
'
;
...
...
@@ -125,7 +126,13 @@ export class TypeScriptServerSpawner {
const
childProcess
=
electron
.
fork
(
version
.
tsServerPath
,
args
,
this
.
getForkOptions
());
this
.
_logger
.
info
(
'
Started TSServer
'
);
return
new
TypeScriptServer
(
childProcess
,
tsServerLogFile
,
cancellationPipeName
,
version
,
this
.
_telemetryReporter
,
this
.
_tracer
);
return
new
TypeScriptServer
(
new
ChildServerProcess
(
childProcess
),
tsServerLogFile
,
new
PipeRequestCanceller
(
cancellationPipeName
,
this
.
_tracer
),
version
,
this
.
_telemetryReporter
,
this
.
_tracer
);
}
private
getForkOptions
()
{
...
...
@@ -239,6 +246,63 @@ export class TypeScriptServerSpawner {
}
}
export
interface
OngoingRequestCanceller
{
tryCancelOngoingRequest
(
seq
:
number
):
boolean
;
}
export
class
PipeRequestCanceller
implements
OngoingRequestCanceller
{
public
constructor
(
private
readonly
_cancellationPipeName
:
string
|
undefined
,
private
readonly
_tracer
:
Tracer
,
)
{
}
public
tryCancelOngoingRequest
(
seq
:
number
):
boolean
{
if
(
!
this
.
_cancellationPipeName
)
{
return
false
;
}
this
.
_tracer
.
logTrace
(
`TypeScript Server: trying to cancel ongoing request with sequence number
${
seq
}
`
);
try
{
fs
.
writeFileSync
(
this
.
_cancellationPipeName
+
seq
,
''
);
}
catch
{
// noop
}
return
true
;
}
}
export
interface
ServerProcess
{
readonly
stdout
:
stream
.
Readable
;
write
(
serverRequest
:
Proto
.
Request
):
void
;
on
(
name
:
'
exit
'
,
handler
:
(
code
:
number
|
null
)
=>
void
):
void
;
on
(
name
:
'
error
'
,
handler
:
(
error
:
Error
)
=>
void
):
void
;
kill
():
void
;
}
class
ChildServerProcess
implements
ServerProcess
{
public
constructor
(
private
readonly
_process
:
child_process
.
ChildProcess
,
)
{
}
get
stdout
():
stream
.
Readable
{
return
this
.
_process
.
stdout
!
;
}
write
(
serverRequest
:
Proto
.
Request
):
void
{
this
.
_process
.
stdin
!
.
write
(
JSON
.
stringify
(
serverRequest
)
+
'
\r\n
'
,
'
utf8
'
);
}
on
(
name
:
'
exit
'
,
handler
:
(
code
:
number
|
null
)
=>
void
):
void
;
on
(
name
:
'
error
'
,
handler
:
(
error
:
Error
)
=>
void
):
void
;
on
(
name
:
any
,
handler
:
any
)
{
this
.
_process
.
on
(
name
,
handler
);
}
kill
():
void
{
this
.
_process
.
kill
();
}
}
export
class
TypeScriptServer
extends
Disposable
{
private
readonly
_reader
:
Reader
<
Proto
.
Response
>
;
private
readonly
_requestQueue
=
new
RequestQueue
();
...
...
@@ -246,18 +310,25 @@ export class TypeScriptServer extends Disposable {
private
readonly
_pendingResponses
=
new
Set
<
number
>
();
constructor
(
private
readonly
_
childProcess
:
cp
.
Child
Process
,
private
readonly
_
process
:
Server
Process
,
private
readonly
_tsServerLogFile
:
string
|
undefined
,
private
readonly
_
cancellationPipeName
:
string
|
undefined
,
private
readonly
_
requestCanceller
:
OngoingRequestCanceller
,
private
readonly
_version
:
TypeScriptVersion
,
private
readonly
_telemetryReporter
:
TelemetryReporter
,
private
readonly
_tracer
:
Tracer
,
)
{
super
();
this
.
_reader
=
this
.
_register
(
new
Reader
<
Proto
.
Response
>
(
this
.
_
childP
rocess
.
stdout
!
));
this
.
_reader
=
this
.
_register
(
new
Reader
<
Proto
.
Response
>
(
this
.
_
p
rocess
.
stdout
!
));
this
.
_reader
.
onData
(
msg
=>
this
.
dispatchMessage
(
msg
));
this
.
_childProcess
.
on
(
'
exit
'
,
code
=>
this
.
handleExit
(
code
));
this
.
_childProcess
.
on
(
'
error
'
,
error
=>
this
.
handleError
(
error
));
this
.
_process
.
on
(
'
exit
'
,
code
=>
{
this
.
_onExit
.
fire
(
code
);
this
.
_callbacks
.
destroy
(
'
server exited
'
);
});
this
.
_process
.
on
(
'
error
'
,
error
=>
{
this
.
_onError
.
fire
(
error
);
this
.
_callbacks
.
destroy
(
'
server errored
'
);
});
}
private
readonly
_onEvent
=
this
.
_register
(
new
vscode
.
EventEmitter
<
Proto
.
Event
>
());
...
...
@@ -273,8 +344,8 @@ export class TypeScriptServer extends Disposable {
public
get
tsServerLogFile
()
{
return
this
.
_tsServerLogFile
;
}
p
ublic
write
(
serverRequest
:
Proto
.
Request
)
{
this
.
_
childProcess
.
stdin
!
.
write
(
JSON
.
stringify
(
serverRequest
)
+
'
\r\n
'
,
'
utf8
'
);
p
rivate
write
(
serverRequest
:
Proto
.
Request
)
{
this
.
_
process
.
write
(
serverRequest
);
}
public
dispose
()
{
...
...
@@ -284,17 +355,7 @@ export class TypeScriptServer extends Disposable {
}
public
kill
()
{
this
.
_childProcess
.
kill
();
}
private
handleExit
(
error
:
any
)
{
this
.
_onExit
.
fire
(
error
);
this
.
_callbacks
.
destroy
(
'
server exited
'
);
}
private
handleError
(
error
:
any
)
{
this
.
_onError
.
fire
(
error
);
this
.
_callbacks
.
destroy
(
'
server errored
'
);
this
.
_process
.
kill
();
}
private
dispatchMessage
(
message
:
Proto
.
Message
)
{
...
...
@@ -334,13 +395,7 @@ export class TypeScriptServer extends Disposable {
return
true
;
}
if
(
this
.
_cancellationPipeName
)
{
this
.
_tracer
.
logTrace
(
`TypeScript Server: trying to cancel ongoing request with sequence number
${
seq
}
`
);
try
{
fs
.
writeFileSync
(
this
.
_cancellationPipeName
+
seq
,
''
);
}
catch
{
// noop
}
if
(
this
.
_requestCanceller
.
tryCancelOngoingRequest
(
seq
))
{
return
true
;
}
...
...
extensions/typescript-language-features/src/typescriptServiceClient.ts
浏览文件 @
809386b6
...
...
@@ -20,7 +20,7 @@ import LogDirectoryProvider from './utils/logDirectoryProvider';
import
Logger
from
'
./utils/logger
'
;
import
{
TypeScriptPluginPathsProvider
}
from
'
./utils/pluginPathsProvider
'
;
import
{
PluginManager
}
from
'
./utils/plugins
'
;
import
TelemetryReporter
from
'
./utils/telemetry
'
;
import
TelemetryReporter
,
{
VSCodeTelemetryReporter
}
from
'
./utils/telemetry
'
;
import
Tracer
from
'
./utils/tracer
'
;
import
{
inferredProjectConfig
}
from
'
./utils/tsconfig
'
;
import
{
TypeScriptVersionPicker
}
from
'
./utils/versionPicker
'
;
...
...
@@ -152,7 +152,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType
}
},
this
,
this
.
_disposables
);
this
.
telemetryReporter
=
this
.
_register
(
new
TelemetryReporter
(()
=>
{
this
.
telemetryReporter
=
this
.
_register
(
new
VSCode
TelemetryReporter
(()
=>
{
if
(
this
.
serverState
.
type
===
ServerState
.
Type
.
Running
)
{
if
(
this
.
serverState
.
tsserverVersion
)
{
return
this
.
serverState
.
tsserverVersion
;
...
...
extensions/typescript-language-features/src/utils/telemetry.ts
浏览文件 @
809386b6
...
...
@@ -13,15 +13,14 @@ interface PackageInfo {
readonly
aiKey
:
string
;
}
export
default
class
TelemetryReporter
{
private
_reporter
:
VsCodeTelemetryReporter
|
null
=
null
;
export
default
interface
TelemetryReporter
{
logTelemetry
(
eventName
:
string
,
properties
?:
{
[
prop
:
string
]:
string
}):
void
;
dispose
()
{
if
(
this
.
_reporter
)
{
this
.
_reporter
.
dispose
();
this
.
_reporter
=
null
;
}
}
dispose
():
void
;
}
export
class
VSCodeTelemetryReporter
implements
TelemetryReporter
{
private
_reporter
:
VsCodeTelemetryReporter
|
null
=
null
;
constructor
(
private
readonly
clientVersionDelegate
:
()
=>
string
...
...
@@ -45,6 +44,13 @@ export default class TelemetryReporter {
}
}
public
dispose
()
{
if
(
this
.
_reporter
)
{
this
.
_reporter
.
dispose
();
this
.
_reporter
=
null
;
}
}
@
memoize
private
get
reporter
():
VsCodeTelemetryReporter
|
null
{
if
(
this
.
packageInfo
&&
this
.
packageInfo
.
aiKey
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录