Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
0e4e0d8f
V
vscode
项目概览
掘金者说
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
0e4e0d8f
编写于
9月 21, 2017
作者:
M
Matt Bierner
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Make sure we send format requests before code actions / refactor
上级
84605ab7
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
58 addition
and
97 deletion
+58
-97
extensions/typescript/src/features/codeActionProvider.ts
extensions/typescript/src/features/codeActionProvider.ts
+9
-55
extensions/typescript/src/features/formattingConfigurationManager.ts
...typescript/src/features/formattingConfigurationManager.ts
+37
-33
extensions/typescript/src/features/formattingProvider.ts
extensions/typescript/src/features/formattingProvider.ts
+1
-1
extensions/typescript/src/features/refactorProvider.ts
extensions/typescript/src/features/refactorProvider.ts
+9
-6
extensions/typescript/src/typescriptMain.ts
extensions/typescript/src/typescriptMain.ts
+2
-2
未找到文件。
extensions/typescript/src/features/codeActionProvider.ts
浏览文件 @
0e4e0d8f
...
...
@@ -3,23 +3,17 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
CodeActionProvider
,
TextDocument
,
Range
,
CancellationToken
,
CodeActionContext
,
Command
,
commands
,
Uri
,
workspace
,
WorkspaceEdit
,
TextEdit
,
FormattingOptions
,
window
}
from
'
vscode
'
;
import
{
CodeActionProvider
,
TextDocument
,
Range
,
CancellationToken
,
CodeActionContext
,
Command
,
commands
,
workspace
,
WorkspaceEdit
}
from
'
vscode
'
;
import
*
as
Proto
from
'
../protocol
'
;
import
{
ITypescriptServiceClient
}
from
'
../typescriptService
'
;
import
{
tsTextSpanToVsRange
,
vsRangeToTsFileRange
}
from
'
../utils/convert
'
;
import
FormattingConfigurationManager
from
'
./formattingConfigurationManager
'
;
interface
NumberSet
{
[
key
:
number
]:
boolean
;
}
interface
Source
{
uri
:
Uri
;
version
:
number
;
range
:
Range
;
formattingOptions
:
FormattingOptions
|
undefined
;
}
export
default
class
TypeScriptCodeActionProvider
implements
CodeActionProvider
{
private
commandId
:
string
;
...
...
@@ -27,6 +21,7 @@ export default class TypeScriptCodeActionProvider implements CodeActionProvider
constructor
(
private
readonly
client
:
ITypescriptServiceClient
,
private
readonly
formattingConfigurationManager
:
FormattingConfigurationManager
,
mode
:
string
)
{
this
.
commandId
=
`_typescript.applyCodeAction.
${
mode
}
`
;
...
...
@@ -53,26 +48,14 @@ export default class TypeScriptCodeActionProvider implements CodeActionProvider
return
[];
}
let
formattingOptions
:
FormattingOptions
|
undefined
=
undefined
;
for
(
const
editor
of
window
.
visibleTextEditors
)
{
if
(
editor
.
document
.
fileName
===
document
.
fileName
)
{
formattingOptions
=
{
tabSize
:
editor
.
options
.
tabSize
,
insertSpaces
:
editor
.
options
.
insertSpaces
}
as
FormattingOptions
;
break
;
}
}
await
this
.
formattingConfigurationManager
.
ensureFormatOptionsForDocument
(
document
,
token
);
const
source
:
Source
=
{
uri
:
document
.
uri
,
version
:
document
.
version
,
range
:
range
,
formattingOptions
:
formattingOptions
};
const
args
:
Proto
.
CodeFixRequestArgs
=
{
...
vsRangeToTsFileRange
(
file
,
range
),
errorCodes
:
Array
.
from
(
supportedActions
)
};
const
response
=
await
this
.
client
.
execute
(
'
getCodeFixes
'
,
args
,
token
);
return
(
response
.
body
||
[]).
map
(
action
=>
this
.
getCommandForAction
(
source
,
action
));
return
(
response
.
body
||
[]).
map
(
action
=>
this
.
getCommandForAction
(
action
));
}
private
get
supportedCodeActions
():
Thenable
<
NumberSet
>
{
...
...
@@ -96,15 +79,15 @@ export default class TypeScriptCodeActionProvider implements CodeActionProvider
.
filter
(
code
=>
supportedActions
[
code
])));
}
private
getCommandForAction
(
source
:
Source
,
action
:
Proto
.
CodeAction
):
Command
{
private
getCommandForAction
(
action
:
Proto
.
CodeAction
):
Command
{
return
{
title
:
action
.
description
,
command
:
this
.
commandId
,
arguments
:
[
source
,
action
]
arguments
:
[
action
]
};
}
private
async
onCodeAction
(
source
:
Source
,
action
:
Proto
.
CodeAction
):
Promise
<
boolean
>
{
private
async
onCodeAction
(
action
:
Proto
.
CodeAction
):
Promise
<
boolean
>
{
const
workspaceEdit
=
new
WorkspaceEdit
();
for
(
const
change
of
action
.
changes
)
{
for
(
const
textChange
of
change
.
textChanges
)
{
...
...
@@ -114,35 +97,6 @@ export default class TypeScriptCodeActionProvider implements CodeActionProvider
}
}
const
success
=
workspace
.
applyEdit
(
workspaceEdit
);
if
(
!
success
)
{
return
false
;
}
let
firstEdit
:
TextEdit
|
undefined
=
undefined
;
for
(
const
[
uri
,
edits
]
of
workspaceEdit
.
entries
())
{
if
(
uri
.
toString
()
===
source
.
uri
.
toString
())
{
firstEdit
=
edits
[
0
];
break
;
}
}
if
(
!
firstEdit
)
{
return
true
;
}
const
newLines
=
firstEdit
.
newText
.
match
(
/
\n
/g
);
const
editedRange
=
new
Range
(
firstEdit
.
range
.
start
.
line
,
0
,
firstEdit
.
range
.
end
.
line
+
1
+
(
newLines
?
newLines
.
length
:
0
),
0
);
// TODO: Workaround for https://github.com/Microsoft/TypeScript/issues/12249
// apply formatting to the source range until TS returns formatted results
const
edits
=
(
await
commands
.
executeCommand
(
'
vscode.executeFormatRangeProvider
'
,
source
.
uri
,
editedRange
,
source
.
formattingOptions
||
{}))
as
TextEdit
[];
if
(
!
edits
||
!
edits
.
length
)
{
return
false
;
}
const
formattingEdit
=
new
WorkspaceEdit
();
formattingEdit
.
set
(
source
.
uri
,
edits
);
return
workspace
.
applyEdit
(
formattingEdit
);
return
workspace
.
applyEdit
(
workspaceEdit
);
}
}
\ No newline at end of file
extensions/typescript/src/features/formattingConfigurationManager.ts
浏览文件 @
0e4e0d8f
...
...
@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
workspace
as
Workspace
,
FormattingOptions
,
TextDocument
,
CancellationToken
,
WorkspaceConfiguration
}
from
'
vscode
'
;
import
{
workspace
as
Workspace
,
FormattingOptions
,
TextDocument
,
CancellationToken
,
WorkspaceConfiguration
,
window
}
from
'
vscode
'
;
import
*
as
Proto
from
'
../protocol
'
;
import
{
ITypescriptServiceClient
}
from
'
../typescriptService
'
;
...
...
@@ -58,8 +58,7 @@ namespace FormattingConfiguration {
}
export
default
class
FormattingConfigurationManager
{
private
jsConfig
:
FormattingConfiguration
=
FormattingConfiguration
.
def
;
private
tsConfig
:
FormattingConfiguration
=
FormattingConfiguration
.
def
;
private
config
:
FormattingConfiguration
=
FormattingConfiguration
.
def
;
private
formatOptions
:
{
[
key
:
string
]:
Proto
.
FormatCodeSettings
|
undefined
;
}
=
Object
.
create
(
null
);
...
...
@@ -76,67 +75,72 @@ export default class FormattingConfigurationManager {
});
}
public
async
ensureFormatOptionsForDocument
(
document
:
TextDocument
,
token
:
CancellationToken
|
undefined
):
Promise
<
void
>
{
for
(
const
editor
of
window
.
visibleTextEditors
)
{
if
(
editor
.
document
.
fileName
===
document
.
fileName
)
{
const
formattingOptions
=
{
tabSize
:
editor
.
options
.
tabSize
,
insertSpaces
:
editor
.
options
.
insertSpaces
}
as
FormattingOptions
;
return
this
.
ensureFormatOptions
(
document
,
formattingOptions
,
token
);
}
}
}
public
async
ensureFormatOptions
(
document
:
TextDocument
,
options
:
FormattingOptions
,
token
:
CancellationToken
):
Promise
<
Proto
.
FormatCodeSettings
>
{
token
:
CancellationToken
|
undefined
):
Promise
<
void
>
{
const
key
=
document
.
uri
.
toString
();
const
currentOptions
=
this
.
formatOptions
[
key
];
if
(
currentOptions
&&
currentOptions
.
tabSize
===
options
.
tabSize
&&
currentOptions
.
indentSize
===
options
.
tabSize
&&
currentOptions
.
convertTabsToSpaces
===
options
.
insertSpaces
)
{
return
currentOptions
;
return
;
}
const
absPath
=
this
.
client
.
normalizePath
(
document
.
uri
);
if
(
!
absPath
)
{
return
Object
.
create
(
null
);
}
const
formatOptions
=
this
.
getFormatOptions
(
document
,
options
);
const
formatOptions
=
this
.
getFormatOptions
(
options
);
const
args
:
Proto
.
ConfigureRequestArguments
=
{
file
:
absPath
,
formatOptions
:
formatOptions
};
await
this
.
client
.
execute
(
'
configure
'
,
args
,
token
);
this
.
formatOptions
[
key
]
=
formatOptions
;
return
formatOptions
;
}
public
updateConfiguration
(
config
:
WorkspaceConfiguration
):
void
{
const
newJsConfig
=
config
.
get
(
'
javascript.format
'
,
FormattingConfiguration
.
def
);
const
newTsConfig
=
config
.
get
(
'
typeScript.format
'
,
FormattingConfiguration
.
def
);
const
newConfig
=
config
.
get
(
'
format
'
,
FormattingConfiguration
.
def
);
if
(
!
FormattingConfiguration
.
equals
(
this
.
jsConfig
,
newJsConfig
)
||
!
FormattingConfiguration
.
equals
(
this
.
tsConfig
,
newTs
Config
))
{
if
(
!
FormattingConfiguration
.
equals
(
this
.
config
,
new
Config
))
{
this
.
formatOptions
=
Object
.
create
(
null
);
}
this
.
jsConfig
=
newJsConfig
;
this
.
tsConfig
=
newTsConfig
;
this
.
config
=
newConfig
;
}
private
getFormatOptions
(
document
:
TextDocument
,
options
:
FormattingOptions
):
Proto
.
FormatCodeSettings
{
const
config
=
document
.
languageId
===
'
typescript
'
||
document
.
languageId
===
'
typescriptreact
'
?
this
.
tsConfig
:
this
.
jsConfig
;
private
getFormatOptions
(
options
:
FormattingOptions
):
Proto
.
FormatCodeSettings
{
return
{
tabSize
:
options
.
tabSize
,
indentSize
:
options
.
tabSize
,
convertTabsToSpaces
:
options
.
insertSpaces
,
// We can use \n here since the editor normalizes later on to its line endings.
newLineCharacter
:
'
\n
'
,
insertSpaceAfterCommaDelimiter
:
config
.
insertSpaceAfterCommaDelimiter
,
insertSpaceAfterConstructor
:
config
.
insertSpaceAfterConstructor
,
insertSpaceAfterSemicolonInForStatements
:
config
.
insertSpaceAfterSemicolonInForStatements
,
insertSpaceBeforeAndAfterBinaryOperators
:
config
.
insertSpaceBeforeAndAfterBinaryOperators
,
insertSpaceAfterKeywordsInControlFlowStatements
:
config
.
insertSpaceAfterKeywordsInControlFlowStatements
,
insertSpaceAfterFunctionKeywordForAnonymousFunctions
:
config
.
insertSpaceAfterFunctionKeywordForAnonymousFunctions
,
insertSpaceBeforeFunctionParenthesis
:
config
.
insertSpaceBeforeFunctionParenthesis
,
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis
:
config
.
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis
,
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets
:
config
.
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets
,
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces
:
config
.
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces
,
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces
:
config
.
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces
,
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces
:
config
.
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces
,
insertSpaceAfterTypeAssertion
:
config
.
insertSpaceAfterTypeAssertion
,
placeOpenBraceOnNewLineForFunctions
:
config
.
placeOpenBraceOnNewLineForFunctions
,
placeOpenBraceOnNewLineForControlBlocks
:
config
.
placeOpenBraceOnNewLineForControlBlocks
,
insertSpaceAfterCommaDelimiter
:
this
.
config
.
insertSpaceAfterCommaDelimiter
,
insertSpaceAfterConstructor
:
this
.
config
.
insertSpaceAfterConstructor
,
insertSpaceAfterSemicolonInForStatements
:
this
.
config
.
insertSpaceAfterSemicolonInForStatements
,
insertSpaceBeforeAndAfterBinaryOperators
:
this
.
config
.
insertSpaceBeforeAndAfterBinaryOperators
,
insertSpaceAfterKeywordsInControlFlowStatements
:
this
.
config
.
insertSpaceAfterKeywordsInControlFlowStatements
,
insertSpaceAfterFunctionKeywordForAnonymousFunctions
:
this
.
config
.
insertSpaceAfterFunctionKeywordForAnonymousFunctions
,
insertSpaceBeforeFunctionParenthesis
:
this
.
config
.
insertSpaceBeforeFunctionParenthesis
,
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis
:
this
.
config
.
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis
,
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets
:
this
.
config
.
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets
,
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces
:
this
.
config
.
insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces
,
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces
:
this
.
config
.
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces
,
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces
:
this
.
config
.
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces
,
insertSpaceAfterTypeAssertion
:
this
.
config
.
insertSpaceAfterTypeAssertion
,
placeOpenBraceOnNewLineForFunctions
:
this
.
config
.
placeOpenBraceOnNewLineForFunctions
,
placeOpenBraceOnNewLineForControlBlocks
:
this
.
config
.
placeOpenBraceOnNewLineForControlBlocks
,
};
}
}
extensions/typescript/src/features/formattingProvider.ts
浏览文件 @
0e4e0d8f
...
...
@@ -19,7 +19,7 @@ export class TypeScriptFormattingProvider implements DocumentRangeFormattingEdit
)
{
}
public
updateConfiguration
(
config
:
WorkspaceConfiguration
):
void
{
this
.
enabled
=
config
.
get
(
'
format.enable
d
'
,
true
);
this
.
enabled
=
config
.
get
(
'
format.enable
'
,
true
);
}
public
isEnabled
():
boolean
{
...
...
extensions/typescript/src/features/refactorProvider.ts
浏览文件 @
0e4e0d8f
...
...
@@ -10,7 +10,7 @@ import { CodeActionProvider, TextDocument, Range, CancellationToken, CodeActionC
import
*
as
Proto
from
'
../protocol
'
;
import
{
ITypescriptServiceClient
}
from
'
../typescriptService
'
;
import
{
tsTextSpanToVsRange
,
vsRangeToTsFileRange
,
tsLocationToVsPosition
}
from
'
../utils/convert
'
;
import
FormattingOptionsManager
from
'
./formattingConfigurationManager
'
;
export
default
class
TypeScriptRefactorProvider
implements
CodeActionProvider
{
private
doRefactorCommandId
:
string
;
...
...
@@ -18,6 +18,7 @@ export default class TypeScriptRefactorProvider implements CodeActionProvider {
constructor
(
private
readonly
client
:
ITypescriptServiceClient
,
private
formattingOptionsManager
:
FormattingOptionsManager
,
mode
:
string
)
{
this
.
doRefactorCommandId
=
`_typescript.applyRefactoring.
${
mode
}
`
;
...
...
@@ -55,14 +56,14 @@ export default class TypeScriptRefactorProvider implements CodeActionProvider {
actions
.
push
({
title
:
info
.
description
,
command
:
this
.
selectRefactorCommandId
,
arguments
:
[
file
,
info
,
range
]
arguments
:
[
document
,
file
,
info
,
range
]
});
}
else
{
for
(
const
action
of
info
.
actions
)
{
actions
.
push
({
title
:
action
.
description
,
command
:
this
.
doRefactorCommandId
,
arguments
:
[
file
,
info
.
name
,
action
.
name
,
range
]
arguments
:
[
document
,
file
,
info
.
name
,
action
.
name
,
range
]
});
}
}
...
...
@@ -85,7 +86,7 @@ export default class TypeScriptRefactorProvider implements CodeActionProvider {
return
workspaceEdit
;
}
private
async
selectRefactoring
(
file
:
string
,
info
:
Proto
.
ApplicableRefactorInfo
,
range
:
Range
):
Promise
<
boolean
>
{
private
async
selectRefactoring
(
document
:
TextDocument
,
file
:
string
,
info
:
Proto
.
ApplicableRefactorInfo
,
range
:
Range
):
Promise
<
boolean
>
{
return
window
.
showQuickPick
(
info
.
actions
.
map
((
action
):
QuickPickItem
=>
({
label
:
action
.
name
,
description
:
action
.
description
...
...
@@ -93,11 +94,13 @@ export default class TypeScriptRefactorProvider implements CodeActionProvider {
if
(
!
selected
)
{
return
false
;
}
return
this
.
doRefactoring
(
file
,
info
.
name
,
selected
.
label
,
range
);
return
this
.
doRefactoring
(
document
,
file
,
info
.
name
,
selected
.
label
,
range
);
});
}
private
async
doRefactoring
(
file
:
string
,
refactor
:
string
,
action
:
string
,
range
:
Range
):
Promise
<
boolean
>
{
private
async
doRefactoring
(
document
:
TextDocument
,
file
:
string
,
refactor
:
string
,
action
:
string
,
range
:
Range
):
Promise
<
boolean
>
{
await
this
.
formattingOptionsManager
.
ensureFormatOptionsForDocument
(
document
,
undefined
);
const
args
:
Proto
.
GetEditsForRefactorRequestArgs
=
{
...
vsRangeToTsFileRange
(
file
,
range
),
refactor
,
...
...
extensions/typescript/src/typescriptMain.ts
浏览文件 @
0e4e0d8f
...
...
@@ -267,8 +267,8 @@ class LanguageProvider {
this
.
disposables
.
push
(
languages
.
registerDocumentSymbolProvider
(
selector
,
new
(
await
import
(
'
./features/documentSymbolProvider
'
)).
default
(
client
)));
this
.
disposables
.
push
(
languages
.
registerSignatureHelpProvider
(
selector
,
new
(
await
import
(
'
./features/signatureHelpProvider
'
)).
default
(
client
),
'
(
'
,
'
,
'
));
this
.
disposables
.
push
(
languages
.
registerRenameProvider
(
selector
,
new
(
await
import
(
'
./features/renameProvider
'
)).
default
(
client
)));
this
.
disposables
.
push
(
languages
.
registerCodeActionsProvider
(
selector
,
new
(
await
import
(
'
./features/codeActionProvider
'
)).
default
(
client
,
this
.
description
.
id
)));
this
.
disposables
.
push
(
languages
.
registerCodeActionsProvider
(
selector
,
new
(
await
import
(
'
./features/refactorProvider
'
)).
default
(
client
,
this
.
description
.
id
)));
this
.
disposables
.
push
(
languages
.
registerCodeActionsProvider
(
selector
,
new
(
await
import
(
'
./features/codeActionProvider
'
)).
default
(
client
,
this
.
formattingOptionsManager
,
this
.
description
.
id
)));
this
.
disposables
.
push
(
languages
.
registerCodeActionsProvider
(
selector
,
new
(
await
import
(
'
./features/refactorProvider
'
)).
default
(
client
,
this
.
formattingOptionsManager
,
this
.
description
.
id
)));
this
.
registerVersionDependentProviders
();
for
(
const
modeId
of
this
.
description
.
modeIds
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录