Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell11
提交
cff0ad46
D
dragonwell11
项目概览
openanolis
/
dragonwell11
通知
7
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell11
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
cff0ad46
编写于
10月 26, 2017
作者:
S
sundar
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8190217: Add a JS "static checker" sample for nashorn parser API
Reviewed-by: jlaskey
上级
c81ea49d
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
275 addition
and
0 deletion
+275
-0
src/sample/nashorn/bad_patterns.js
src/sample/nashorn/bad_patterns.js
+68
-0
src/sample/nashorn/staticchecker.js
src/sample/nashorn/staticchecker.js
+207
-0
未找到文件。
src/sample/nashorn/bad_patterns.js
0 → 100644
浏览文件 @
cff0ad46
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* This is a test script file for staticchecker.js.
*
* Usage:
* jjs --language=es6 staticcheker.js -- bad_patterns.js
*/
var
obj
=
{}
obj
.
__proto__
=
null
;
with
(
obj
)
{}
delete
obj
;
eval
(
"
print('hello')
"
)
Object
=
null
JavaImporter
=
undefined
function
func
()
{}
func
.
prototype
.
x
=
44
;
Object
.
prototype
.
foo
=
"
hello
"
;
String
.
prototype
.
bar
=
function
()
{}
try
{
eval
(
"
***
"
);
}
catch
(
e
)
{}
try
{
eval
(
"
***
"
);
}
catch
(
e
)
{
;
}
try
{
eval
(
"
***
"
);
}
catch
(
e
)
{
print
(
e
)
}
src/sample/nashorn/staticchecker.js
0 → 100644
浏览文件 @
cff0ad46
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// Usage: jjs --language=es6 staticchecker.js -- <file>
// or jjs --language=es6 staticchecker.js -- <directory>
// default argument is the current directory
if
(
arguments
.
length
==
0
)
{
arguments
[
0
]
=
"
.
"
;
}
const
File
=
Java
.
type
(
"
java.io.File
"
);
const
file
=
new
File
(
arguments
[
0
]);
if
(
!
file
.
exists
())
{
print
(
arguments
[
0
]
+
"
is neither a file nor a directory
"
);
exit
(
1
);
}
// A simple static checker for javascript best practices.
// static checks performed are:
//
// * __proto__ magic property is bad (non-standard)
// * 'with' statements are bad
// * 'eval' calls are bad
// * 'delete foo' (scope variable delete) is bad
// * assignment to standard globals is bad (eg. Object = "hello")
// * assignment to property on standard prototype is bad (eg. String.prototype.foo = 45)
// * exception swallow (empty catch block in try-catch statements)
const
Files
=
Java
.
type
(
"
java.nio.file.Files
"
);
const
EmptyStatementTree
=
Java
.
type
(
"
jdk.nashorn.api.tree.EmptyStatementTree
"
);
const
IdentifierTree
=
Java
.
type
(
"
jdk.nashorn.api.tree.IdentifierTree
"
);
const
MemberSelectTree
=
Java
.
type
(
"
jdk.nashorn.api.tree.MemberSelectTree
"
);
const
Parser
=
Java
.
type
(
"
jdk.nashorn.api.tree.Parser
"
);
const
SimpleTreeVisitor
=
Java
.
type
(
"
jdk.nashorn.api.tree.SimpleTreeVisitorES6
"
);
const
Tree
=
Java
.
type
(
"
jdk.nashorn.api.tree.Tree
"
);
const
parser
=
Parser
.
create
(
"
-scripting
"
,
"
--language=es6
"
);
// capture standard global upfront
const
globals
=
new
Set
();
for
(
let
name
of
Object
.
getOwnPropertyNames
(
this
))
{
globals
.
add
(
name
);
}
const
checkFile
=
function
(
file
)
{
print
(
"
Parsing
"
+
file
);
const
ast
=
parser
.
parse
(
file
,
print
);
if
(
!
ast
)
{
print
(
"
FAILED to parse:
"
+
file
);
return
;
}
const
checker
=
new
(
Java
.
extend
(
SimpleTreeVisitor
))
{
lineMap
:
null
,
printWarning
(
node
,
msg
)
{
var
pos
=
node
.
startPosition
;
var
line
=
this
.
lineMap
.
getLineNumber
(
pos
);
var
column
=
this
.
lineMap
.
getColumnNumber
(
pos
);
print
(
`WARNING:
${
msg
}
in
${
file
}
@
${
line
}
:
${
column
}
`
);
},
printWithWarning
(
node
)
{
this
.
printWarning
(
node
,
"
'with' usage
"
);
},
printProtoWarning
(
node
)
{
this
.
printWarning
(
node
,
"
__proto__ usage
"
);
},
printScopeDeleteWarning
(
node
,
varName
)
{
this
.
printWarning
(
node
,
`delete
${
varName
}
`
);
},
hasOnlyEmptyStats
(
stats
)
{
const
itr
=
stats
.
iterator
();
while
(
itr
.
hasNext
())
{
if
(
!
(
itr
.
next
()
instanceof
EmptyStatementTree
))
{
return
false
;
}
}
return
true
;
},
checkProto
(
node
,
name
)
{
if
(
name
==
"
__proto__
"
)
{
this
.
printProtoWarning
(
node
);
}
},
checkAssignment
(
lhs
)
{
if
(
lhs
instanceof
IdentifierTree
&&
globals
.
has
(
lhs
.
name
))
{
this
.
printWarning
(
lhs
,
`assignment to standard global "
${
lhs
.
name
}
"`
);
}
else
if
(
lhs
instanceof
MemberSelectTree
)
{
const
expr
=
lhs
.
expression
;
if
(
expr
instanceof
MemberSelectTree
&&
expr
.
expression
instanceof
IdentifierTree
&&
globals
.
has
(
expr
.
expression
.
name
)
&&
"
prototype
"
==
expr
.
identifier
)
{
this
.
printWarning
(
lhs
,
`property set "
${
expr
.
expression
.
name
}
.prototype.
${
lhs
.
identifier
}
"`
);
}
}
},
visitAssignment
(
node
,
extra
)
{
this
.
checkAssignment
(
node
.
variable
);
Java
.
super
(
checker
).
visitAssignment
(
node
,
extra
);
},
visitCatch
(
node
,
extra
)
{
var
stats
=
node
.
block
.
statements
;
if
(
stats
.
empty
||
this
.
hasOnlyEmptyStats
(
stats
))
{
this
.
printWarning
(
node
,
"
exception swallow
"
);
}
Java
.
super
(
checker
).
visitCatch
(
node
,
extra
);
},
visitCompilationUnit
(
node
,
extra
)
{
this
.
lineMap
=
node
.
lineMap
;
Java
.
super
(
checker
).
visitCompilationUnit
(
node
,
extra
);
},
visitFunctionCall
(
node
,
extra
)
{
var
func
=
node
.
functionSelect
;
if
(
func
instanceof
IdentifierTree
&&
func
.
name
==
"
eval
"
)
{
this
.
printWarning
(
node
,
"
eval call found
"
);
}
Java
.
super
(
checker
).
visitFunctionCall
(
node
,
extra
);
},
visitIdentifier
(
node
,
extra
)
{
this
.
checkProto
(
node
,
node
.
name
);
Java
.
super
(
checker
).
visitIdentifier
(
node
,
extra
);
},
visitMemberSelect
(
node
,
extra
)
{
this
.
checkProto
(
node
,
node
.
identifier
);
Java
.
super
(
checker
).
visitMemberSelect
(
node
,
extra
);
},
visitProperty
(
node
,
extra
)
{
this
.
checkProto
(
node
,
node
.
key
);
Java
.
super
(
checker
).
visitProperty
(
node
,
extra
);
},
visitUnary
(
node
,
extra
)
{
if
(
node
.
kind
==
Tree
.
Kind
.
DELETE
&&
node
.
expression
instanceof
IdentifierTree
)
{
this
.
printScopeDeleteWarning
(
node
,
node
.
expression
.
name
);
}
Java
.
super
(
checker
).
visitUnary
(
node
,
extra
);
},
visitWith
(
node
,
extra
)
{
this
.
printWithWarning
(
node
);
Java
.
super
(
checker
).
visitWith
(
node
,
extra
);
}
};
try
{
ast
.
accept
(
checker
,
null
);
}
catch
(
e
)
{
print
(
e
);
if
(
e
.
printStackTrace
)
e
.
printStackTrace
();
if
(
e
.
stack
)
print
(
e
.
stack
);
}
}
if
(
file
.
isDirectory
())
{
Files
.
walk
(
file
.
toPath
())
.
filter
(
function
(
p
)
Files
.
isRegularFile
(
p
))
.
filter
(
function
(
p
)
p
.
toFile
().
name
.
endsWith
(
'
.js
'
))
.
forEach
(
checkFile
);
}
else
{
checkFile
(
file
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录