Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Phodal
Coca
提交
2772fb89
C
Coca
项目概览
Phodal
/
Coca
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
Coca
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
2772fb89
编写于
12月 15, 2019
作者:
P
Phodal Huang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: add bs code
上级
f2576cf4
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
668 addition
and
0 deletion
+668
-0
cmd/bs.go
cmd/bs.go
+53
-0
src/bs/BadSmellApp.go
src/bs/BadSmellApp.go
+171
-0
src/bs/BadSmellListener.go
src/bs/BadSmellListener.go
+379
-0
src/bs/models/BsModel.go
src/bs/models/BsModel.go
+65
-0
未找到文件。
cmd/bs.go
0 → 100644
浏览文件 @
2772fb89
package
cmd
import
(
"coca/src/bs"
"coca/src/utils"
"encoding/json"
"github.com/spf13/cobra"
"strings"
)
var
badsmellCmd
*
cobra
.
Command
=
&
cobra
.
Command
{
Use
:
"bs"
,
Short
:
"Bad Code Smell"
,
Long
:
``
,
Run
:
func
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
importPath
:=
cmd
.
Flag
(
"path"
)
.
Value
.
String
()
ignoreStr
:=
cmd
.
Flag
(
"ignore"
)
.
Value
.
String
()
sortType
:=
cmd
.
Flag
(
"sort"
)
.
Value
.
String
()
ignoreRules
:=
strings
.
Split
(
ignoreStr
,
","
)
if
importPath
!=
""
{
bsApp
:=
new
(
bs
.
BadSmellApp
)
bsList
:=
bsApp
.
AnalysisPath
(
importPath
,
ignoreRules
)
bsModel
,
_
:=
json
.
MarshalIndent
(
bsList
,
""
,
"
\t
"
)
if
sortType
==
"type"
{
sortSmells
:=
sortSmellByType
(
bsList
)
bsModel
,
_
=
json
.
MarshalIndent
(
sortSmells
,
""
,
"
\t
"
)
}
utils
.
WriteToFile
(
"bs.json"
,
string
(
bsModel
))
}
},
}
func
sortSmellByType
(
models
[]
bs
.
BadSmellModel
)
map
[
string
][]
bs
.
BadSmellModel
{
sortSmells
:=
make
(
map
[
string
][]
bs
.
BadSmellModel
)
for
_
,
model
:=
range
models
{
sortSmells
[
model
.
Bs
]
=
append
(
sortSmells
[
model
.
Bs
],
model
)
}
return
sortSmells
}
func
init
()
{
rootCmd
.
AddCommand
(
badsmellCmd
)
badsmellCmd
.
PersistentFlags
()
.
StringP
(
"path"
,
"p"
,
""
,
"example -p src/main"
)
badsmellCmd
.
PersistentFlags
()
.
StringP
(
"ignore"
,
"x"
,
""
,
"-x=dataClass,lazyElement,longMethod,refusedBequest"
)
badsmellCmd
.
PersistentFlags
()
.
StringP
(
"sort"
,
"s"
,
""
,
"sort bad smell -s=type"
)
}
src/bs/BadSmellApp.go
0 → 100644
浏览文件 @
2772fb89
package
bs
import
(
"coca/src/utils"
"encoding/json"
"fmt"
"github.com/antlr/antlr4/runtime/Go/antlr"
"os"
"path/filepath"
"strconv"
"strings"
.
"coca/src/bs/models"
.
"coca/src/language/java"
)
var
nodeInfos
[]
JFullClassNode
type
BadSmellModel
struct
{
File
string
`json:"File,omitempty"`
Line
string
`json:"Line,omitempty"`
Bs
string
`json:"BS,omitempty"`
Description
string
`json:"Description,omitempty"`
}
type
BadSmellApp
struct
{
}
func
(
j
*
BadSmellApp
)
AnalysisPath
(
codeDir
string
,
ignoreRules
[]
string
)
[]
BadSmellModel
{
nodeInfos
=
nil
files
:=
(
*
BadSmellApp
)(
nil
)
.
javaFiles
(
codeDir
)
for
index
:=
range
files
{
nodeInfo
:=
NewJFullClassNode
()
file
:=
files
[
index
]
displayName
:=
filepath
.
Base
(
file
)
fmt
.
Println
(
"Start parse java call: "
+
displayName
)
parser
:=
(
*
BadSmellApp
)(
nil
)
.
processFile
(
file
)
context
:=
parser
.
CompilationUnit
()
listener
:=
NewBadSmellListener
()
antlr
.
NewParseTreeWalker
()
.
Walk
(
listener
,
context
)
nodeInfo
=
listener
.
getNodeInfo
()
nodeInfo
.
Path
=
file
nodeInfos
=
append
(
nodeInfos
,
*
nodeInfo
)
}
bsModel
,
_
:=
json
.
MarshalIndent
(
nodeInfos
,
""
,
"
\t
"
)
utils
.
WriteToFile
(
"nodeInfos.json"
,
string
(
bsModel
))
bsList
:=
analysisBadSmell
(
nodeInfos
)
mapIgnoreRules
:=
make
(
map
[
string
]
bool
)
for
_
,
ignore
:=
range
ignoreRules
{
mapIgnoreRules
[
ignore
]
=
true
}
filteredBsList
:=
filterBadsmellList
(
bsList
,
mapIgnoreRules
)
return
filteredBsList
}
func
filterBadsmellList
(
models
[]
BadSmellModel
,
ignoreRules
map
[
string
]
bool
)
[]
BadSmellModel
{
var
results
[]
BadSmellModel
for
_
,
model
:=
range
models
{
if
!
ignoreRules
[
model
.
Bs
]
{
results
=
append
(
results
,
model
)
}
}
return
results
}
func
analysisBadSmell
(
nodes
[]
JFullClassNode
)
[]
BadSmellModel
{
var
badSmellList
[]
BadSmellModel
for
_
,
node
:=
range
nodes
{
// To be Defined number
if
node
.
Type
==
"Class"
&&
len
(
node
.
Methods
)
<
1
{
badSmellList
=
append
(
badSmellList
,
*&
BadSmellModel
{
node
.
Path
,
""
,
"lazyElement"
,
""
})
}
onlyHaveGetterAndSetter
:=
true
// Long Method
for
_
,
method
:=
range
node
.
Methods
{
methodLength
:=
method
.
StopLine
-
method
.
StartLine
if
methodLength
>
30
{
description
:=
"method length: "
+
strconv
.
Itoa
(
methodLength
)
longMethod
:=
&
BadSmellModel
{
node
.
Path
,
strconv
.
Itoa
(
method
.
StartLine
),
"longMethod"
,
description
}
badSmellList
=
append
(
badSmellList
,
*
longMethod
)
}
if
strings
.
Contains
(
method
.
Name
,
"get"
)
&&
strings
.
Contains
(
method
.
Name
,
"set"
)
{
onlyHaveGetterAndSetter
=
false
}
// longParameterList
if
len
(
method
.
Parameters
)
>
6
{
paramsJson
,
_
:=
json
.
Marshal
(
method
.
Parameters
)
str
:=
string
(
paramsJson
[
:
])
longParams
:=
&
BadSmellModel
{
node
.
Path
,
strconv
.
Itoa
(
method
.
StartLine
),
"longParameterList"
,
str
}
badSmellList
=
append
(
badSmellList
,
*
longParams
)
}
// repeatedSwitches
if
method
.
MethodBs
.
IfSize
>
8
||
method
.
MethodBs
.
SwitchSize
>
8
{
longParams
:=
&
BadSmellModel
{
node
.
Path
,
strconv
.
Itoa
(
method
.
StartLine
),
"repeatedSwitches"
,
""
}
badSmellList
=
append
(
badSmellList
,
*
longParams
)
}
}
// dataClass
if
onlyHaveGetterAndSetter
&&
node
.
Type
==
"Class"
&&
len
(
node
.
Methods
)
>
0
{
dataClass
:=
&
BadSmellModel
{
node
.
Path
,
""
,
"dataClass"
,
""
}
badSmellList
=
append
(
badSmellList
,
*
dataClass
)
}
//Refused Bequest
if
node
.
Extends
!=
""
{
hasCallParentMethod
:=
false
for
_
,
methodCall
:=
range
node
.
MethodCalls
{
if
methodCall
.
Class
==
node
.
Extends
{
hasCallParentMethod
=
true
}
}
if
!
hasCallParentMethod
{
badSmellList
=
append
(
badSmellList
,
*&
BadSmellModel
{
node
.
Path
,
""
,
"refusedBequest"
,
""
})
}
}
// LargeClass
normalClassLength
:=
withOutGetterSetterClass
(
node
.
Methods
)
if
node
.
Type
==
"Class"
&&
normalClassLength
>
20
{
description
:=
"methods number (without getter/setter): "
+
strconv
.
Itoa
(
normalClassLength
)
badSmellList
=
append
(
badSmellList
,
*&
BadSmellModel
{
node
.
Path
,
""
,
"largeClass"
,
description
})
}
}
return
badSmellList
}
func
withOutGetterSetterClass
(
fullMethods
[]
JFullMethod
)
int
{
var
normalMethodSize
=
0
for
_
,
method
:=
range
fullMethods
{
if
!
strings
.
Contains
(
method
.
Name
,
"get"
)
&&
!
strings
.
Contains
(
method
.
Name
,
"set"
)
{
normalMethodSize
++
}
}
return
normalMethodSize
}
func
(
j
*
BadSmellApp
)
javaFiles
(
codeDir
string
)
[]
string
{
files
:=
make
([]
string
,
0
)
_
=
filepath
.
Walk
(
codeDir
,
func
(
path
string
,
fi
os
.
FileInfo
,
err
error
)
error
{
if
strings
.
HasSuffix
(
path
,
".java"
)
&&
!
strings
.
Contains
(
path
,
"Test.java"
)
{
files
=
append
(
files
,
path
)
}
return
nil
})
return
files
}
func
(
j
*
BadSmellApp
)
processFile
(
path
string
)
*
JavaParser
{
is
,
_
:=
antlr
.
NewFileStream
(
path
)
lexer
:=
NewJavaLexer
(
is
)
stream
:=
antlr
.
NewCommonTokenStream
(
lexer
,
0
);
parser
:=
NewJavaParser
(
stream
)
return
parser
}
src/bs/BadSmellListener.go
0 → 100644
浏览文件 @
2772fb89
package
bs
import
(
.
"coca/src/bs/models"
.
"coca/src/language/java"
"github.com/antlr/antlr4/runtime/Go/antlr"
"reflect"
"strings"
)
var
imports
[]
string
var
clzs
[]
string
var
currentPkg
string
var
currentClz
string
var
currentClzType
string
var
currentClzExtends
string
var
currentClzImplements
[]
string
var
methods
[]
JFullMethod
var
methodCalls
[]
JFullMethodCall
var
fields
=
make
(
map
[
string
]
string
)
var
localVars
=
make
(
map
[
string
]
string
)
var
formalParameters
=
make
(
map
[
string
]
string
)
var
currentClassBs
ClassBadSmellInfo
func
NewBadSmellListener
()
*
BadSmellListener
{
currentClz
=
""
currentPkg
=
""
methods
=
nil
methodCalls
=
nil
currentClzImplements
=
nil
currentClzExtends
=
""
return
&
BadSmellListener
{}
}
type
BadSmellListener
struct
{
BaseJavaParserListener
}
func
(
s
*
BadSmellListener
)
getNodeInfo
()
*
JFullClassNode
{
return
&
JFullClassNode
{
currentPkg
,
currentClz
,
currentClzType
,
""
,
currentClzExtends
,
currentClzImplements
,
methods
,
methodCalls
,
currentClassBs
,
}
}
func
(
s
*
BadSmellListener
)
EnterPackageDeclaration
(
ctx
*
PackageDeclarationContext
)
{
currentPkg
=
ctx
.
QualifiedName
()
.
GetText
()
}
func
(
s
*
BadSmellListener
)
EnterImportDeclaration
(
ctx
*
ImportDeclarationContext
)
{
importText
:=
ctx
.
QualifiedName
()
.
GetText
()
imports
=
append
(
imports
,
importText
)
}
func
(
s
*
BadSmellListener
)
EnterClassDeclaration
(
ctx
*
ClassDeclarationContext
)
{
currentClzType
=
"Class"
currentClz
=
ctx
.
IDENTIFIER
()
.
GetText
()
if
ctx
.
EXTENDS
()
!=
nil
{
currentClzExtends
=
ctx
.
TypeType
()
.
GetText
()
}
if
ctx
.
IMPLEMENTS
()
!=
nil
{
typeList
:=
ctx
.
TypeList
()
.
(
*
TypeListContext
)
for
_
,
typ
:=
range
typeList
.
AllTypeType
()
{
typeData
:=
getTypeDATA
(
typ
.
(
*
TypeTypeContext
))
currentClzImplements
=
append
(
currentClzImplements
,
typeData
)
}
}
}
func
getTypeDATA
(
typ
*
TypeTypeContext
)
string
{
var
typeData
string
classOrInterface
:=
typ
.
ClassOrInterfaceType
()
.
(
*
ClassOrInterfaceTypeContext
)
if
classOrInterface
!=
nil
{
identifiers
:=
classOrInterface
.
AllIDENTIFIER
()
typeData
=
identifiers
[
len
(
identifiers
)
-
1
]
.
GetText
()
}
return
typeData
}
func
(
s
*
BadSmellListener
)
EnterInterfaceDeclaration
(
ctx
*
InterfaceDeclarationContext
)
{
currentClzType
=
"Interface"
currentClz
=
ctx
.
IDENTIFIER
()
.
GetText
()
}
func
(
s
*
BadSmellListener
)
EnterInterfaceMethodDeclaration
(
ctx
*
InterfaceMethodDeclarationContext
)
{
startLine
:=
ctx
.
GetStart
()
.
GetLine
()
startLinePosition
:=
ctx
.
IDENTIFIER
()
.
GetSymbol
()
.
GetColumn
()
stopLine
:=
ctx
.
GetStop
()
.
GetLine
()
name
:=
ctx
.
IDENTIFIER
()
.
GetText
()
stopLinePosition
:=
startLinePosition
+
len
(
name
)
methodBody
:=
ctx
.
MethodBody
()
.
GetText
()
typeType
:=
ctx
.
TypeTypeOrVoid
()
.
GetText
()
var
methodParams
[]
JFullParameter
=
nil
parameters
:=
ctx
.
FormalParameters
()
if
parameters
!=
nil
{
if
reflect
.
TypeOf
(
parameters
.
GetChild
(
1
))
.
String
()
==
"*parser.FormalParameterListContext"
{
allFormal
:=
parameters
.
GetChild
(
1
)
.
(
*
FormalParameterListContext
)
formalParameter
:=
allFormal
.
AllFormalParameter
()
for
_
,
param
:=
range
formalParameter
{
paramContext
:=
param
.
(
*
FormalParameterContext
)
paramType
:=
paramContext
.
TypeType
()
.
GetText
()
paramValue
:=
paramContext
.
VariableDeclaratorId
()
.
(
*
VariableDeclaratorIdContext
)
.
IDENTIFIER
()
.
GetText
()
methodParams
=
append
(
methodParams
,
*&
JFullParameter
{
paramType
,
paramValue
})
}
}
}
methodBSInfo
:=
*&
MethodBadSmellInfo
{
0
,
0
}
method
:=
&
JFullMethod
{
name
,
typeType
,
startLine
,
startLinePosition
,
stopLine
,
stopLinePosition
,
methodBody
,
methodParams
,
methodBSInfo
,
}
methods
=
append
(
methods
,
*
method
)
}
func
(
s
*
BadSmellListener
)
EnterFormalParameter
(
ctx
*
FormalParameterContext
)
{
formalParameters
[
ctx
.
VariableDeclaratorId
()
.
GetText
()]
=
ctx
.
TypeType
()
.
GetText
()
}
func
(
s
*
BadSmellListener
)
EnterFieldDeclaration
(
ctx
*
FieldDeclarationContext
)
{
declarators
:=
ctx
.
VariableDeclarators
()
variableName
:=
declarators
.
GetParent
()
.
GetChild
(
0
)
.
(
antlr
.
ParseTree
)
.
GetText
()
for
_
,
declarator
:=
range
declarators
.
(
*
VariableDeclaratorsContext
)
.
AllVariableDeclarator
()
{
value
:=
declarator
.
(
*
VariableDeclaratorContext
)
.
VariableDeclaratorId
()
.
(
*
VariableDeclaratorIdContext
)
.
IDENTIFIER
()
.
GetText
()
fields
[
value
]
=
variableName
}
}
func
(
s
*
BadSmellListener
)
EnterLocalVariableDeclaration
(
ctx
*
LocalVariableDeclarationContext
)
{
typ
:=
ctx
.
GetChild
(
0
)
.
(
antlr
.
ParseTree
)
.
GetText
()
variableName
:=
ctx
.
GetChild
(
1
)
.
GetChild
(
0
)
.
GetChild
(
0
)
.
(
antlr
.
ParseTree
)
.
GetText
()
localVars
[
variableName
]
=
typ
}
func
(
s
*
BadSmellListener
)
EnterMethodDeclaration
(
ctx
*
MethodDeclarationContext
)
{
startLine
:=
ctx
.
GetStart
()
.
GetLine
()
startLinePosition
:=
ctx
.
IDENTIFIER
()
.
GetSymbol
()
.
GetColumn
()
stopLine
:=
ctx
.
GetStop
()
.
GetLine
()
name
:=
ctx
.
IDENTIFIER
()
.
GetText
()
stopLinePosition
:=
startLinePosition
+
len
(
name
)
//XXX: find the start position of {, not public
typeType
:=
ctx
.
TypeTypeOrVoid
()
.
GetText
()
methodBody
:=
ctx
.
MethodBody
()
.
GetText
()
var
methodParams
[]
JFullParameter
=
nil
parameters
:=
ctx
.
FormalParameters
()
if
parameters
!=
nil
{
if
reflect
.
TypeOf
(
parameters
.
GetChild
(
1
))
.
String
()
==
"*parser.FormalParameterListContext"
{
allFormal
:=
parameters
.
GetChild
(
1
)
.
(
*
FormalParameterListContext
)
formalParameter
:=
allFormal
.
AllFormalParameter
()
for
_
,
param
:=
range
formalParameter
{
paramContext
:=
param
.
(
*
FormalParameterContext
)
paramType
:=
paramContext
.
TypeType
()
.
GetText
()
paramValue
:=
paramContext
.
VariableDeclaratorId
()
.
(
*
VariableDeclaratorIdContext
)
.
IDENTIFIER
()
.
GetText
()
methodParams
=
append
(
methodParams
,
*&
JFullParameter
{
paramType
,
paramValue
})
localVars
[
paramValue
]
=
paramType
}
}
}
methodBSInfo
:=
*&
MethodBadSmellInfo
{
0
,
0
}
methodBadSmellInfo
:=
buildMethodBSInfo
(
ctx
,
methodBSInfo
)
method
:=
&
JFullMethod
{
name
,
typeType
,
startLine
,
startLinePosition
,
stopLine
,
stopLinePosition
,
methodBody
,
methodParams
,
methodBadSmellInfo
,
}
methods
=
append
(
methods
,
*
method
)
}
func
buildMethodBSInfo
(
context
*
MethodDeclarationContext
,
bsInfo
MethodBadSmellInfo
)
MethodBadSmellInfo
{
methodBody
:=
context
.
MethodBody
()
blockContext
:=
methodBody
.
GetChild
(
0
)
if
reflect
.
TypeOf
(
blockContext
)
.
String
()
==
"*parser.BlockContext"
{
blcStatement
:=
blockContext
.
(
*
BlockContext
)
.
AllBlockStatement
()
for
_
,
statement
:=
range
blcStatement
{
if
reflect
.
TypeOf
(
statement
.
GetChild
(
0
))
.
String
()
==
"*parser.StatementContext"
{
if
len
(
statement
.
GetChild
(
0
)
.
(
*
StatementContext
)
.
GetChildren
())
<
3
{
continue
}
statementCtx
:=
statement
.
GetChild
(
0
)
.
(
*
StatementContext
)
if
(
reflect
.
TypeOf
(
statementCtx
.
GetChild
(
1
))
.
String
())
==
"*parser.ParExpressionContext"
{
if
statementCtx
.
GetChild
(
0
)
.
(
antlr
.
ParseTree
)
.
GetText
()
==
"if"
{
bsInfo
.
IfSize
=
bsInfo
.
IfSize
+
1
}
if
statementCtx
.
GetChild
(
0
)
.
(
antlr
.
ParseTree
)
.
GetText
()
==
"switch"
{
bsInfo
.
SwitchSize
=
bsInfo
.
SwitchSize
+
1
}
}
}
}
}
return
bsInfo
}
func
(
s
*
BadSmellListener
)
EnterFormalParameterList
(
ctx
*
FormalParameterListContext
)
{
//fmt.Println(ctx.GetParent().GetParent().(antlr.RuleNode).get)
//fmt.Println(ctx.AllFormalParameter()
}
func
(
s
*
BadSmellListener
)
EnterAnnotation
(
ctx
*
AnnotationContext
)
{
if
currentClzType
==
"Class"
&&
ctx
.
QualifiedName
()
.
GetText
()
==
"Override"
{
currentClassBs
.
OverrideSize
++
}
}
func
(
s
*
BadSmellListener
)
EnterCreator
(
ctx
*
CreatorContext
)
{
variableName
:=
ctx
.
GetParent
()
.
GetParent
()
.
GetChild
(
0
)
.
(
antlr
.
ParseTree
)
.
GetText
()
localVars
[
variableName
]
=
ctx
.
CreatedName
()
.
GetText
()
}
func
(
s
*
BadSmellListener
)
EnterLocalTypeDeclaration
(
ctx
*
LocalTypeDeclarationContext
)
{
}
func
(
s
*
BadSmellListener
)
EnterMethodCall
(
ctx
*
MethodCallContext
)
{
var
targetCtx
=
ctx
.
GetParent
()
.
GetChild
(
0
)
.
(
antlr
.
ParseTree
)
.
GetText
()
var
targetType
=
parseTargetType
(
targetCtx
)
callee
:=
ctx
.
GetChild
(
0
)
.
(
antlr
.
ParseTree
)
.
GetText
()
startLine
:=
ctx
.
GetStart
()
.
GetLine
()
startLinePosition
:=
ctx
.
GetStart
()
.
GetColumn
()
stopLine
:=
ctx
.
GetStop
()
.
GetLine
()
stopLinePosition
:=
startLinePosition
+
len
(
callee
)
//typeType := ctx.GetChild(0).(antlr.ParseTree).TypeTypeOrVoid().GetText()
// TODO: 处理链试调用
if
strings
.
Contains
(
targetType
,
"()"
)
&&
strings
.
Contains
(
targetType
,
"."
)
{
split
:=
strings
.
Split
(
targetType
,
"."
)
sourceTarget
:=
split
[
0
]
targetType
=
localVars
[
sourceTarget
]
}
fullType
:=
warpTargetFullType
(
targetType
)
if
targetType
==
"super"
{
targetType
=
currentClzExtends
}
if
fullType
!=
""
{
jMethodCall
:=
&
JFullMethodCall
{
removeTarget
(
fullType
),
""
,
targetType
,
callee
,
startLine
,
startLinePosition
,
stopLine
,
stopLinePosition
}
methodCalls
=
append
(
methodCalls
,
*
jMethodCall
)
}
else
{
if
ctx
.
GetText
()
==
targetType
{
methodName
:=
ctx
.
IDENTIFIER
()
.
GetText
()
jMethodCall
:=
&
JFullMethodCall
{
currentPkg
,
""
,
currentClz
,
methodName
,
startLine
,
startLinePosition
,
stopLine
,
stopLinePosition
}
methodCalls
=
append
(
methodCalls
,
*
jMethodCall
)
}
else
{
methodName
:=
ctx
.
IDENTIFIER
()
.
GetText
()
jMethodCall
:=
&
JFullMethodCall
{
currentPkg
,
"NEEDFIX"
,
targetType
,
methodName
,
startLine
,
startLinePosition
,
stopLine
,
stopLinePosition
}
methodCalls
=
append
(
methodCalls
,
*
jMethodCall
)
}
}
}
func
(
s
*
BadSmellListener
)
EnterExpression
(
ctx
*
ExpressionContext
)
{
// lambda BlogPO::of
if
ctx
.
COLONCOLON
()
!=
nil
{
text
:=
ctx
.
Expression
(
0
)
.
GetText
()
methodName
:=
ctx
.
IDENTIFIER
()
.
GetText
()
targetType
:=
parseTargetType
(
text
)
fullType
:=
warpTargetFullType
(
targetType
)
startLine
:=
ctx
.
GetStart
()
.
GetLine
()
startLinePosition
:=
ctx
.
GetStart
()
.
GetColumn
()
stopLine
:=
ctx
.
GetStop
()
.
GetLine
()
stopLinePosition
:=
startLinePosition
+
len
(
text
)
jMethodCall
:=
&
JFullMethodCall
{
removeTarget
(
fullType
),
""
,
targetType
,
methodName
,
startLine
,
startLinePosition
,
stopLine
,
stopLinePosition
}
methodCalls
=
append
(
methodCalls
,
*
jMethodCall
)
}
}
func
(
s
*
BadSmellListener
)
appendClasses
(
classes
[]
string
)
{
clzs
=
classes
}
func
removeTarget
(
fullType
string
)
string
{
split
:=
strings
.
Split
(
fullType
,
"."
)
return
strings
.
Join
(
split
[
:
len
(
split
)
-
1
],
"."
)
}
func
parseTargetType
(
targetCtx
string
)
string
{
targetVar
:=
targetCtx
targetType
:=
targetVar
//TODO: update this reflect
typeOf
:=
reflect
.
TypeOf
(
targetCtx
)
.
String
()
if
strings
.
HasSuffix
(
typeOf
,
"MethodCallContext"
)
{
targetType
=
currentClz
;
}
else
{
fieldType
:=
fields
[
targetVar
]
formalType
:=
formalParameters
[
targetVar
]
localVarType
:=
localVars
[
targetVar
]
if
fieldType
!=
""
{
targetType
=
fieldType
}
else
if
formalType
!=
""
{
targetType
=
formalType
;
}
else
if
localVarType
!=
""
{
targetType
=
localVarType
;
}
}
return
targetType
}
func
warpTargetFullType
(
targetType
string
)
string
{
if
strings
.
EqualFold
(
currentClz
,
targetType
)
{
return
currentPkg
+
"."
+
targetType
}
// TODO: update for array
split
:=
strings
.
Split
(
targetType
,
"."
)
str
:=
split
[
0
]
pureTargetType
:=
strings
.
ReplaceAll
(
strings
.
ReplaceAll
(
str
,
"["
,
""
),
"]"
,
""
)
for
index
:=
range
imports
{
imp
:=
imports
[
index
]
if
strings
.
HasSuffix
(
imp
,
pureTargetType
)
{
return
imp
}
}
//maybe the same package
for
_
,
clz
:=
range
clzs
{
if
strings
.
HasSuffix
(
clz
,
"."
+
pureTargetType
)
{
return
clz
}
}
//1. current package, 2. import by *
if
pureTargetType
==
"super"
{
for
index
:=
range
imports
{
imp
:=
imports
[
index
]
if
strings
.
HasSuffix
(
imp
,
currentClzExtends
)
{
return
imp
}
}
}
return
""
}
src/bs/models/BsModel.go
0 → 100644
浏览文件 @
2772fb89
package
models
type
JFullClassNode
struct
{
Package
string
Class
string
Type
string
Path
string
Extends
string
Implements
[]
string
Methods
[]
JFullMethod
MethodCalls
[]
JFullMethodCall
ClassBS
ClassBadSmellInfo
}
type
JFullMethodCall
struct
{
Package
string
Type
string
Class
string
MethodName
string
StartLine
int
StartLinePosition
int
StopLine
int
StopLinePosition
int
}
type
JFullMethod
struct
{
Name
string
Type
string
StartLine
int
StartLinePosition
int
StopLine
int
StopLinePosition
int
MethodBody
string
Parameters
[]
JFullParameter
MethodBs
MethodBadSmellInfo
}
type
MethodBadSmellInfo
struct
{
IfSize
int
SwitchSize
int
}
type
ClassBadSmellInfo
struct
{
OverrideSize
int
PublicVarSize
int
}
type
JFullParameter
struct
{
Name
string
Type
string
}
func
NewJFullClassNode
()
*
JFullClassNode
{
info
:=
&
ClassBadSmellInfo
{
0
,
0
};
return
&
JFullClassNode
{
""
,
""
,
""
,
""
,
""
,
nil
,
nil
,
nil
,
*
info
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录