Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
54b41017
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,发现更多精彩内容 >>
提交
54b41017
编写于
1月 31, 2017
作者:
D
Dirk Baeumer
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fixes #19624: Adopt "php.validate.executablePath" handling to new TS behavior
上级
72a03227
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
71 addition
and
207 deletion
+71
-207
extensions/php/package.json
extensions/php/package.json
+1
-2
extensions/php/src/features/validationProvider.ts
extensions/php/src/features/validationProvider.ts
+68
-26
extensions/php/src/phpMain.ts
extensions/php/src/phpMain.ts
+2
-179
未找到文件。
extensions/php/package.json
浏览文件 @
54b41017
...
...
@@ -52,8 +52,7 @@
"php.validate.executablePath"
:
{
"type"
:
[
"string"
,
"null"
],
"default"
:
null
,
"description"
:
"%configuration.validate.executablePath%"
,
"isExecutable"
:
true
"description"
:
"%configuration.validate.executablePath%"
},
"php.validate.run"
:
{
"type"
:
"string"
,
...
...
extensions/php/src/features/validationProvider.ts
浏览文件 @
54b41017
...
...
@@ -79,6 +79,8 @@ namespace RunTrigger {
};
}
const
CheckedExecutablePath
=
'
php.validate.checkedExecutablePath
'
;
export
default
class
PHPValidationProvider
{
private
static
MatchExpression
:
RegExp
=
/
(?:(?:
Parse|Fatal
)
error
)
:
(
.*
)(?:
in
)(
.*
?)(?:
on line
)(\d
+
)
/
;
...
...
@@ -86,19 +88,20 @@ export default class PHPValidationProvider {
private
static
FileArgs
:
string
[]
=
[
'
-l
'
,
'
-n
'
,
'
-d
'
,
'
display_errors=On
'
,
'
-d
'
,
'
log_errors=Off
'
,
'
-f
'
];
private
validationEnabled
:
boolean
;
private
executableIsUserDefined
:
boolean
;
private
executable
:
string
;
private
trigger
:
RunTrigger
;
private
executableNotFound
:
boolean
;
private
pauseValidation
:
boolean
;
private
documentListener
:
vscode
.
Disposable
;
private
diagnosticCollection
:
vscode
.
DiagnosticCollection
;
private
delayers
:
{
[
key
:
string
]:
ThrottledDelayer
<
void
>
};
constructor
(
private
workspace
ExecutablePath
:
string
)
{
constructor
(
private
workspace
Store
:
vscode
.
Memento
)
{
this
.
executable
=
null
;
this
.
validationEnabled
=
true
;
this
.
trigger
=
RunTrigger
.
onSave
;
this
.
executableNotFound
=
false
;
this
.
pauseValidation
=
false
;
}
public
activate
(
subscriptions
:
vscode
.
Disposable
[])
{
...
...
@@ -114,17 +117,6 @@ export default class PHPValidationProvider {
},
null
,
subscriptions
);
}
public
updateWorkspaceExecutablePath
(
workspaceExecutablePath
:
string
,
loadConfig
:
boolean
=
false
):
void
{
if
(
workspaceExecutablePath
&&
workspaceExecutablePath
.
length
===
0
)
{
this
.
workspaceExecutablePath
=
undefined
;
}
else
{
this
.
workspaceExecutablePath
=
workspaceExecutablePath
;
}
if
(
loadConfig
)
{
this
.
loadConfiguration
();
}
}
public
dispose
():
void
{
this
.
diagnosticCollection
.
clear
();
this
.
diagnosticCollection
.
dispose
();
...
...
@@ -135,12 +127,22 @@ export default class PHPValidationProvider {
let
oldExecutable
=
this
.
executable
;
if
(
section
)
{
this
.
validationEnabled
=
section
.
get
<
boolean
>
(
'
validate.enable
'
,
true
);
this
.
executable
=
this
.
workspaceExecutablePath
||
section
.
get
<
string
>
(
'
validate.executablePath
'
,
null
);
let
inspect
=
section
.
inspect
<
string
>
(
'
validate.executablePath
'
);
if
(
inspect
.
workspaceValue
)
{
this
.
executable
=
inspect
.
workspaceValue
;
this
.
executableIsUserDefined
=
false
;
}
else
if
(
inspect
.
globalValue
)
{
this
.
executable
=
inspect
.
globalValue
;
this
.
executableIsUserDefined
=
true
;
}
else
{
this
.
executable
=
undefined
;
this
.
executableIsUserDefined
=
undefined
;
}
this
.
trigger
=
RunTrigger
.
from
(
section
.
get
<
string
>
(
'
validate.run
'
,
RunTrigger
.
strings
.
onSave
));
}
this
.
delayers
=
Object
.
create
(
null
);
if
(
this
.
executableNotFound
)
{
this
.
executableNotFound
=
oldExecutable
===
this
.
executable
;
if
(
this
.
pauseValidation
)
{
this
.
pauseValidation
=
oldExecutable
===
this
.
executable
;
}
if
(
this
.
documentListener
)
{
this
.
documentListener
.
dispose
();
...
...
@@ -160,16 +162,56 @@ export default class PHPValidationProvider {
}
private
triggerValidate
(
textDocument
:
vscode
.
TextDocument
):
void
{
if
(
textDocument
.
languageId
!==
'
php
'
||
this
.
executableNotFound
||
!
this
.
validationEnabled
)
{
if
(
textDocument
.
languageId
!==
'
php
'
||
this
.
pauseValidation
||
!
this
.
validationEnabled
)
{
return
;
}
let
key
=
textDocument
.
uri
.
toString
();
let
delayer
=
this
.
delayers
[
key
];
if
(
!
delayer
)
{
delayer
=
new
ThrottledDelayer
<
void
>
(
this
.
trigger
===
RunTrigger
.
onType
?
250
:
0
);
this
.
delayers
[
key
]
=
delayer
;
interface
MessageItem
extends
vscode
.
MessageItem
{
id
:
string
;
}
let
trigger
=
()
=>
{
let
key
=
textDocument
.
uri
.
toString
();
let
delayer
=
this
.
delayers
[
key
];
if
(
!
delayer
)
{
delayer
=
new
ThrottledDelayer
<
void
>
(
this
.
trigger
===
RunTrigger
.
onType
?
250
:
0
);
this
.
delayers
[
key
]
=
delayer
;
}
delayer
.
trigger
(()
=>
this
.
doValidate
(
textDocument
));
};
if
(
this
.
executableIsUserDefined
!==
void
0
&&
!
this
.
executableIsUserDefined
)
{
let
checkedExecutablePath
=
this
.
workspaceStore
.
get
<
string
>
(
CheckedExecutablePath
,
undefined
);
if
(
!
checkedExecutablePath
||
checkedExecutablePath
!==
this
.
executable
)
{
vscode
.
window
.
showInformationMessage
<
MessageItem
>
(
localize
(
'
php.useExecutablePath
'
,
'
Do you allow {0} to be executed to lint this file?
'
,
this
.
executable
),
{
title
:
localize
(
'
php.yes
'
,
'
Yes
'
),
id
:
'
yes
'
},
{
title
:
localize
(
'
php.no
'
,
'
No
'
),
isCloseAffordance
:
true
,
id
:
'
no
'
},
{
title
:
localize
(
'
php.more
'
,
'
Learn More
'
),
id
:
'
more
'
}
).
then
(
selected
=>
{
if
(
!
selected
||
selected
.
id
===
'
no
'
)
{
this
.
pauseValidation
=
true
;
}
else
if
(
selected
.
id
===
'
yes
'
)
{
this
.
workspaceStore
.
update
(
CheckedExecutablePath
,
this
.
executable
);
trigger
();
}
else
if
(
selected
.
id
===
'
more
'
)
{
vscode
.
commands
.
executeCommand
(
'
vscode.open
'
,
vscode
.
Uri
.
parse
(
'
https://go.microsoft.com/fwlink/?linkid=839878
'
));
}
});
return
;
}
}
delayer
.
trigger
(()
=>
this
.
doValidate
(
textDocument
)
);
trigger
(
);
}
private
doValidate
(
textDocument
:
vscode
.
TextDocument
):
Promise
<
void
>
{
...
...
@@ -201,12 +243,12 @@ export default class PHPValidationProvider {
try
{
let
childProcess
=
cp
.
spawn
(
executable
,
args
,
options
);
childProcess
.
on
(
'
error
'
,
(
error
:
Error
)
=>
{
if
(
this
.
executableNotFound
)
{
if
(
this
.
pauseValidation
)
{
resolve
();
return
;
}
this
.
showError
(
error
,
executable
);
this
.
executableNotFound
=
true
;
this
.
pauseValidation
=
true
;
resolve
();
});
if
(
childProcess
.
pid
)
{
...
...
extensions/php/src/phpMain.ts
浏览文件 @
54b41017
...
...
@@ -4,9 +4,6 @@
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
*
as
fs
from
'
fs
'
;
import
*
as
path
from
'
path
'
;
import
PHPCompletionItemProvider
from
'
./features/completionItemProvider
'
;
import
PHPHoverProvider
from
'
./features/hoverProvider
'
;
import
PHPSignatureHelpProvider
from
'
./features/signatureHelpProvider
'
;
...
...
@@ -15,63 +12,11 @@ import * as vscode from 'vscode';
import
*
as
nls
from
'
vscode-nls
'
;
nls
.
config
({
locale
:
vscode
.
env
.
language
});
let
localize
=
nls
.
loadMessageBundle
();
const
MigratedKey
=
'
php.validate.executablePaht.migrated
'
;
const
PathKey
=
'
php.validate.executablePath
'
;
namespace
is
{
const
toString
=
Object
.
prototype
.
toString
;
export
function
string
(
value
:
any
):
value
is
string
{
return
toString
.
call
(
value
)
===
'
[object String]
'
;
}
}
let
statusBarItem
:
vscode
.
StatusBarItem
;
export
function
activate
(
context
:
vscode
.
ExtensionContext
):
any
{
let
workspaceExecutablePath
=
context
.
workspaceState
.
get
<
string
>
(
PathKey
,
undefined
);
let
migrated
=
context
.
workspaceState
.
get
<
boolean
>
(
MigratedKey
,
false
);
let
validator
=
new
PHPValidationProvider
(
workspaceExecutablePath
);
context
.
subscriptions
.
push
(
vscode
.
commands
.
registerCommand
(
'
_php.onPathClicked
'
,
()
=>
{
onPathClicked
(
context
,
validator
);
}));
statusBarItem
=
vscode
.
window
.
createStatusBarItem
(
vscode
.
StatusBarAlignment
.
Right
,
Number
.
MIN_VALUE
);
statusBarItem
.
text
=
localize
(
'
php.path
'
,
'
Path
'
);
statusBarItem
.
color
=
'
white
'
;
statusBarItem
.
command
=
'
_php.onPathClicked
'
;
vscode
.
workspace
.
onDidChangeConfiguration
(()
=>
updateStatusBarItem
(
context
));
vscode
.
window
.
onDidChangeActiveTextEditor
((
editor
)
=>
{
updateStatusBarItem
(
context
,
editor
);
});
updateStatusBarItem
(
context
,
vscode
.
window
.
activeTextEditor
);
if
(
workspaceExecutablePath
===
void
0
&&
!
migrated
)
{
let
settingsExecutablePath
=
readLocalExecutableSetting
();
if
(
settingsExecutablePath
)
{
migrateExecutablePath
(
settingsExecutablePath
).
then
((
value
)
=>
{
context
.
workspaceState
.
update
(
MigratedKey
,
true
);
// User has pressed escape;
if
(
!
value
)
{
// activate the validator with the current settings.
validator
.
activate
(
context
.
subscriptions
);
return
;
}
context
.
workspaceState
.
update
(
PathKey
,
value
);
validator
.
updateWorkspaceExecutablePath
(
value
,
false
);
validator
.
activate
(
context
.
subscriptions
);
updateStatusBarItem
(
context
);
});
}
else
{
context
.
workspaceState
.
update
(
MigratedKey
,
true
);
validator
.
activate
(
context
.
subscriptions
);
}
}
else
{
validator
.
activate
(
context
.
subscriptions
);
}
let
validator
=
new
PHPValidationProvider
(
context
.
workspaceState
);
validator
.
activate
(
context
.
subscriptions
);
// add providers
context
.
subscriptions
.
push
(
vscode
.
languages
.
registerCompletionItemProvider
(
'
php
'
,
new
PHPCompletionItemProvider
(),
'
.
'
,
'
$
'
));
...
...
@@ -83,126 +28,4 @@ export function activate(context: vscode.ExtensionContext): any {
vscode
.
languages
.
setLanguageConfiguration
(
'
php
'
,
{
wordPattern
:
/
(
-
?\d
*
\.\d\w
*
)
|
([^\-\`\~\!\@\#\%\^\&\*\(\)\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]
+
)
/g
});
}
function
updateStatusBarItem
(
context
:
vscode
.
ExtensionContext
,
editor
:
vscode
.
TextEditor
=
vscode
.
window
.
activeTextEditor
):
void
{
statusBarItem
.
tooltip
=
getExecutablePath
(
context
);
if
(
editor
&&
editor
.
document
&&
editor
.
document
.
languageId
===
'
php
'
)
{
statusBarItem
.
show
();
}
else
{
statusBarItem
.
hide
();
}
}
function
onPathClicked
(
context
:
vscode
.
ExtensionContext
,
validator
:
PHPValidationProvider
)
{
let
value
=
getExecutablePath
(
context
);
vscode
.
window
.
showInputBox
({
prompt
:
localize
(
'
php.enterPath
'
,
'
The path to the PHP executable
'
),
value
:
value
||
''
}).
then
(
value
=>
{
if
(
!
value
)
{
// User pressed Escape
return
;
}
context
.
workspaceState
.
update
(
PathKey
,
value
);
validator
.
updateWorkspaceExecutablePath
(
value
,
true
);
updateStatusBarItem
(
context
);
},
(
error
)
=>
{
});
}
function
getExecutablePath
(
context
:
vscode
.
ExtensionContext
):
string
{
let
result
=
context
.
workspaceState
.
get
<
string
>
(
PathKey
,
undefined
);
if
(
result
)
{
return
result
;
}
let
section
=
vscode
.
workspace
.
getConfiguration
(
'
php.validate
'
);
if
(
section
)
{
return
section
.
get
(
'
executablePath
'
,
undefined
);
}
return
undefined
;
}
function
migrateExecutablePath
(
settingsExecutablePath
:
string
):
Thenable
<
string
>
{
return
vscode
.
window
.
showInformationMessage
(
localize
(
'
php.migrateWorkspaceSetting
'
,
'
Do you want to use {0} as your future PHP executable path?
'
,
settingsExecutablePath
),
{
title
:
localize
(
'
php.yes
'
,
'
Yes
'
),
id
:
'
yes
'
},
{
title
:
localize
(
'
php.edit
'
,
'
Edit
'
),
id
:
'
edit
'
},
{
title
:
localize
(
'
php.more
'
,
'
Learn More
'
),
id
:
'
more
'
}
).
then
((
selected
)
=>
{
if
(
!
selected
)
{
return
undefined
;
}
if
(
selected
.
id
===
'
yes
'
)
{
return
settingsExecutablePath
;
}
else
if
(
selected
.
id
===
'
edit
'
)
{
return
vscode
.
window
.
showInputBox
(
{
prompt
:
localize
(
'
php.migrateExecutablePath
'
,
'
Use the above path as the PHP executable path?
'
),
value
:
settingsExecutablePath
}
);
}
else
if
(
selected
.
id
===
'
more
'
)
{
vscode
.
commands
.
executeCommand
(
'
vscode.open
'
,
vscode
.
Uri
.
parse
(
'
https://go.microsoft.com/fwlink/?linkid=839919
'
));
return
undefined
;
}
});
}
function
readLocalExecutableSetting
():
string
{
function
stripComments
(
content
:
string
):
string
{
/**
* First capturing group matches double quoted string
* Second matches single quotes string
* Third matches block comments
* Fourth matches line comments
*/
var
regexp
:
RegExp
=
/
(
"
(?:[^\\\"]
*
(?:\\
.
)?)
*"
)
|
(
'
(?:[^\\\']
*
(?:\\
.
)?)
*'
)
|
(\/\*(?:\r?\n
|.
)
*
?\*\/)
|
(\/{2,}
.*
?(?:(?:\r?\n)
|$
))
/g
;
let
result
=
content
.
replace
(
regexp
,
(
match
,
m1
,
m2
,
m3
,
m4
)
=>
{
// Only one of m1, m2, m3, m4 matches
if
(
m3
)
{
// A block comment. Replace with nothing
return
''
;
}
else
if
(
m4
)
{
// A line comment. If it ends in \r?\n then keep it.
let
length
=
m4
.
length
;
if
(
length
>
2
&&
m4
[
length
-
1
]
===
'
\n
'
)
{
return
m4
[
length
-
2
]
===
'
\r
'
?
'
\r\n
'
:
'
\n
'
;
}
else
{
return
''
;
}
}
else
{
// We match a string
return
match
;
}
});
return
result
;
};
try
{
let
rootPath
=
vscode
.
workspace
.
rootPath
;
if
(
!
rootPath
)
{
return
undefined
;
}
let
settingsFile
=
path
.
join
(
rootPath
,
'
.vscode
'
,
'
settings.json
'
);
if
(
!
fs
.
existsSync
(
settingsFile
))
{
return
undefined
;
}
let
content
=
fs
.
readFileSync
(
settingsFile
,
'
utf8
'
);
if
(
!
content
||
content
.
length
===
0
)
{
return
undefined
;
}
content
=
stripComments
(
content
);
let
json
=
JSON
.
parse
(
content
);
let
value
=
json
[
'
php.validate.executablePath
'
];
return
is
.
string
(
value
)
?
value
:
undefined
;
}
catch
(
error
)
{
}
return
undefined
;
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录