Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Phodal
Coca
提交
f5f1b2ea
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 搜索 >>
未验证
提交
f5f1b2ea
编写于
1月 17, 2020
作者:
P
Phodal Huang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: [cmd] add golang analysis api support
上级
2d5f6629
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
168 addition
and
112 deletion
+168
-112
cmd/analysis.go
cmd/analysis.go
+48
-14
cmd/analysis_test.go
cmd/analysis_test.go
+17
-0
cmd/api_test.go
cmd/api_test.go
+1
-1
cmd/testdata/analysis_go.txt
cmd/testdata/analysis_go.txt
+1
-0
pkg/application/concept/concept_analyser.go
pkg/application/concept/concept_analyser.go
+0
-1
pkg/application/goapp/process.go
pkg/application/goapp/process.go
+3
-1
pkg/infrastructure/ast/cocago/cocago_parser.go
pkg/infrastructure/ast/cocago/cocago_parser.go
+30
-29
pkg/infrastructure/ast/cocago/cocago_parser_test.go
pkg/infrastructure/ast/cocago/cocago_parser_test.go
+3
-1
pkg/infrastructure/ast/cocago/testdata/node_infos/struct_type_zero.json
...ture/ast/cocago/testdata/node_infos/struct_type_zero.json
+18
-18
pkg/infrastructure/ast/cocago/testdata/node_infos/struct_with_func_decl.json
...ast/cocago/testdata/node_infos/struct_with_func_decl.json
+47
-47
未找到文件。
cmd/analysis.go
浏览文件 @
f5f1b2ea
...
...
@@ -3,13 +3,17 @@ package cmd
import
(
"encoding/json"
"github.com/phodal/coca/cmd/cmd_util"
"github.com/phodal/coca/pkg/adapter/cocafile"
"github.com/phodal/coca/pkg/application/analysis"
"github.com/phodal/coca/pkg/domain/core_domain"
"github.com/phodal/coca/pkg/infrastructure/ast/cocago"
"github.com/spf13/cobra"
)
type
AnalysisCmdConfig
struct
{
Path
string
ForceUpdate
bool
Lang
string
}
var
(
...
...
@@ -21,31 +25,61 @@ var analysisCmd = &cobra.Command{
Short
:
"analysis code"
,
Long
:
``
,
Run
:
func
(
cmd
*
cobra
.
Command
,
args
[]
string
)
{
importPath
:=
analysisCmdConfig
.
Path
if
analysisCmdConfig
.
Lang
==
"go"
{
analysisGo
()
}
else
{
analysisJava
()
}
},
}
identifierApp
:=
analysis
.
NewJavaIdentifierApp
()
iNodes
:=
identifierApp
.
AnalysisPath
(
importPath
)
func
analysisGo
()
{
importPath
:=
analysisCmdConfig
.
Path
identModel
,
_
:=
json
.
MarshalIndent
(
iNodes
,
""
,
"
\t
"
)
cmd_util
.
WriteToCocaFile
(
"identify.json"
,
string
(
identModel
))
var
results
[]
core_domain
.
CodeFile
files
:=
cocafile
.
GetFilesWithFilter
(
importPath
,
cocafile
.
GoFileFilter
)
for
_
,
file
:=
range
files
{
parser
:=
cocago
.
NewCocagoParser
()
parser
.
SetOutput
(
output
)
result
:=
parser
.
ProcessFile
(
file
)
var
classes
[]
string
=
nil
results
=
append
(
results
,
result
)
}
for
_
,
node
:=
range
iNodes
{
classes
=
append
(
classes
,
node
.
Package
+
"."
+
node
.
NodeName
)
}
var
ds
[]
core_domain
.
CodeDataStruct
for
_
,
result
:=
range
results
{
ds
=
append
(
ds
,
result
.
DataStructures
...
)
}
callApp
:=
analysis
.
NewJavaFullApp
()
cModel
,
_
:=
json
.
MarshalIndent
(
ds
,
""
,
"
\t
"
)
cmd_util
.
WriteToCocaFile
(
"godeps.json"
,
string
(
cModel
))
}
callNodes
:=
callApp
.
AnalysisPath
(
importPath
,
classes
,
iNodes
)
cModel
,
_
:=
json
.
MarshalIndent
(
callNodes
,
""
,
"
\t
"
)
cmd_util
.
WriteToCocaFile
(
"deps.json"
,
string
(
cModel
))
},
func
analysisJava
()
{
importPath
:=
analysisCmdConfig
.
Path
identifierApp
:=
analysis
.
NewJavaIdentifierApp
()
iNodes
:=
identifierApp
.
AnalysisPath
(
importPath
)
identModel
,
_
:=
json
.
MarshalIndent
(
iNodes
,
""
,
"
\t
"
)
cmd_util
.
WriteToCocaFile
(
"identify.json"
,
string
(
identModel
))
var
classes
[]
string
=
nil
for
_
,
node
:=
range
iNodes
{
classes
=
append
(
classes
,
node
.
Package
+
"."
+
node
.
NodeName
)
}
callApp
:=
analysis
.
NewJavaFullApp
()
callNodes
:=
callApp
.
AnalysisPath
(
importPath
,
classes
,
iNodes
)
cModel
,
_
:=
json
.
MarshalIndent
(
callNodes
,
""
,
"
\t
"
)
cmd_util
.
WriteToCocaFile
(
"deps.json"
,
string
(
cModel
))
}
func
init
()
{
rootCmd
.
AddCommand
(
analysisCmd
)
analysisCmd
.
PersistentFlags
()
.
StringVarP
(
&
analysisCmdConfig
.
Path
,
"path"
,
"p"
,
"."
,
"example -p core/main"
)
analysisCmd
.
PersistentFlags
()
.
StringVarP
(
&
analysisCmdConfig
.
Lang
,
"lang"
,
"l"
,
"java"
,
"coca analysis -l java"
)
analysisCmd
.
PersistentFlags
()
.
BoolVarP
(
&
analysisCmdConfig
.
ForceUpdate
,
"force"
,
"f"
,
false
,
"force update -f"
)
}
cmd/analysis_test.go
0 → 100644
浏览文件 @
f5f1b2ea
package
cmd
import
(
"github.com/phodal/coca/cocatest/testcase"
"testing"
)
func
Test_Analysis_Go
(
t
*
testing
.
T
)
{
path
:=
"config"
analysis
:=
[]
testcase
.
CmdTestCase
{{
Name
:
"analysis"
,
Cmd
:
"analysis -f -l go -p "
+
path
,
Golden
:
"testdata/analysis_go.txt"
,
}}
RunTestCmd
(
t
,
analysis
)
}
cmd/api_test.go
浏览文件 @
f5f1b2ea
...
...
@@ -10,7 +10,7 @@ func TestApi(t *testing.T) {
analysis
:=
[]
testcase
.
CmdTestCase
{{
Name
:
"analysis"
,
Cmd
:
"analysis -p "
+
path
,
Cmd
:
"analysis -
l java -
p "
+
path
,
Golden
:
""
,
}}
RunTestCmd
(
t
,
analysis
)
...
...
cmd/testdata/analysis_go.txt
0 → 100644
浏览文件 @
f5f1b2ea
process file config/cmd_config.go
pkg/application/concept/concept_analyser.go
浏览文件 @
f5f1b2ea
...
...
@@ -30,7 +30,6 @@ func buildMethodsFromDeps(clzs []core_domain.CodeDataStruct) string_helper.PairL
}
words
:=
SegmentConceptCamelcase
(
methodsName
)
words
=
removeNormalWords
(
words
)
wordCounts
:=
string_helper
.
RankByWordCount
(
words
)
...
...
pkg/application/goapp/process.go
浏览文件 @
f5f1b2ea
package
goapp
import
(
"bytes"
"github.com/phodal/coca/pkg/adapter/cocafile"
"github.com/phodal/coca/pkg/domain/core_domain"
"github.com/phodal/coca/pkg/infrastructure/ast/cocago"
...
...
@@ -16,7 +17,8 @@ func ProcessPackage(path string, debug bool) []*core_domain.CodeFile {
filesData
:=
make
([]
*
core_domain
.
CodeFile
,
len
(
files
))
parser
:=
cocago
.
NewCocagoParser
()
if
debug
{
parser
.
SetOutput
(
true
)
buf
:=
new
(
bytes
.
Buffer
)
parser
.
SetOutput
(
buf
)
}
for
i
,
file
:=
range
files
{
processFile
:=
parser
.
ProcessFile
(
file
)
...
...
pkg/infrastructure/ast/cocago/cocago_parser.go
浏览文件 @
f5f1b2ea
package
cocago
import
(
"bytes"
"fmt"
"github.com/phodal/coca/pkg/domain/core_domain"
"go/ast"
...
...
@@ -19,7 +18,6 @@ var currentPackage *core_domain.CodePackage
type
CocagoParser
struct
{
}
var
debug
=
false
var
output
io
.
Writer
func
NewCocagoParser
()
*
CocagoParser
{
...
...
@@ -28,10 +26,8 @@ func NewCocagoParser() *CocagoParser {
return
&
CocagoParser
{}
}
func
(
n
*
CocagoParser
)
SetOutput
(
isDebug
bool
)
io
.
Writer
{
output
=
new
(
bytes
.
Buffer
)
debug
=
isDebug
func
(
n
*
CocagoParser
)
SetOutput
(
out
io
.
Writer
)
io
.
Writer
{
output
=
out
return
output
}
...
...
@@ -56,6 +52,7 @@ func (n *CocagoParser) Visitor(f *ast.File, fset *token.FileSet, fileName string
var
currentStruct
core_domain
.
CodeDataStruct
var
currentFile
core_domain
.
CodeFile
var
currentFunc
*
core_domain
.
CodeFunction
var
dsMap
=
make
(
map
[
string
]
*
core_domain
.
CodeDataStruct
)
currentFile
.
FullName
=
fileName
var
funcType
=
""
...
...
@@ -72,12 +69,17 @@ func (n *CocagoParser) Visitor(f *ast.File, fset *token.FileSet, fileName string
currentFile
.
Imports
=
append
(
currentFile
.
Imports
,
*
imp
)
case
*
ast
.
TypeSpec
:
currentStruct
=
core_domain
.
CodeDataStruct
{}
currentStruct
.
NodeName
=
x
.
Name
.
String
()
currentStruct
.
NodeName
=
x
.
Name
.
Name
dsMap
[
currentStruct
.
NodeName
]
=
&
currentStruct
case
*
ast
.
StructType
:
AddStructType
(
currentStruct
,
x
,
&
currentFile
)
fmt
.
Println
(
currentStruct
.
NodeName
)
AddStructType
(
currentStruct
.
NodeName
,
x
,
&
currentFile
,
dsMap
)
case
*
ast
.
FuncDecl
:
funcType
=
"FuncDecl"
currentFunc
=
AddFunctionDecl
(
currentStruct
,
x
,
&
currentFile
)
currentFunc
,
recv
:=
AddFunctionDecl
(
x
,
&
currentFile
)
if
recv
!=
""
{
dsMap
[
recv
]
.
Functions
=
append
(
dsMap
[
recv
]
.
Functions
,
*
currentFunc
)
}
case
*
ast
.
FuncType
:
if
funcType
!=
"FuncDecl"
{
AddNestedFunction
(
currentFunc
,
x
)
...
...
@@ -85,15 +87,21 @@ func (n *CocagoParser) Visitor(f *ast.File, fset *token.FileSet, fileName string
funcType
=
""
case
*
ast
.
InterfaceType
:
AddInterface
(
x
,
lastIdent
,
&
currentFile
)
currentStruct
:=
AddInterface
(
x
,
lastIdent
,
&
currentFile
)
dsMap
[
currentStruct
.
NodeName
]
=
&
currentStruct
default
:
if
reflect
.
TypeOf
(
x
)
!=
nil
{
if
reflect
.
TypeOf
(
x
)
!=
nil
&&
reflect
.
TypeOf
(
output
)
.
String
()
!=
"*bytes.Buffer"
{
fmt
.
Fprintf
(
output
,
"Visitor case %s
\n
"
,
reflect
.
TypeOf
(
x
))
}
}
return
true
})
currentFile
.
DataStructures
=
nil
for
_
,
ds
:=
range
dsMap
{
currentFile
.
DataStructures
=
append
(
currentFile
.
DataStructures
,
*
ds
)
}
return
&
currentFile
}
...
...
@@ -114,7 +122,7 @@ func BuildImport(x *ast.ImportSpec) *core_domain.CodeImport {
return
imp
}
func
AddInterface
(
x
*
ast
.
InterfaceType
,
ident
string
,
codeFile
*
core_domain
.
CodeFile
)
{
func
AddInterface
(
x
*
ast
.
InterfaceType
,
ident
string
,
codeFile
*
core_domain
.
CodeFile
)
core_domain
.
CodeDataStruct
{
properties
:=
BuildFieldToProperty
(
x
.
Methods
.
List
)
dataStruct
:=
core_domain
.
CodeDataStruct
{
...
...
@@ -123,34 +131,27 @@ func AddInterface(x *ast.InterfaceType, ident string, codeFile *core_domain.Code
}
member
:=
core_domain
.
CodeMember
{
DataStructID
:
dataStruct
.
NodeName
,
DataStructID
:
ident
,
Type
:
"interface"
,
}
codeFile
.
Members
=
append
(
codeFile
.
Members
,
&
member
)
codeFile
.
DataStructures
=
append
(
codeFile
.
DataStructures
,
dataStruct
)
return
dataStruct
}
func
AddNestedFunction
(
currentFunc
*
core_domain
.
CodeFunction
,
x
*
ast
.
FuncType
)
{
}
func
AddFunctionDecl
(
currentStruct
core_domain
.
CodeDataStruct
,
x
*
ast
.
FuncDecl
,
currentFile
*
core_domain
.
CodeFile
)
*
core_domain
.
CodeFunction
{
func
AddFunctionDecl
(
x
*
ast
.
FuncDecl
,
currentFile
*
core_domain
.
CodeFile
)
(
*
core_domain
.
CodeFunction
,
string
)
{
recv
:=
""
if
x
.
Recv
!=
nil
{
recv
=
BuildReceiver
(
x
,
recv
)
}
codeFunc
:=
BuildFunction
(
x
)
if
recv
!=
""
{
member
:=
GetMemberFromFile
(
*
currentFile
,
recv
)
if
member
!=
nil
{
member
.
FunctionNodes
=
append
(
member
.
FunctionNodes
,
*
codeFunc
)
}
else
{
createMember
(
currentStruct
)
// todo
}
}
else
{
if
recv
==
""
{
member
:=
GetMemberFromFile
(
*
currentFile
,
"default"
)
if
member
==
nil
{
member
=
&
core_domain
.
CodeMember
{
...
...
@@ -163,7 +164,7 @@ func AddFunctionDecl(currentStruct core_domain.CodeDataStruct, x *ast.FuncDecl,
currentFile
.
Members
=
append
(
currentFile
.
Members
,
member
)
}
return
codeFunc
return
codeFunc
,
recv
}
func
BuildReceiver
(
x
*
ast
.
FuncDecl
,
recv
string
)
string
{
...
...
@@ -260,16 +261,16 @@ func getFieldName(field *ast.Field) string {
return
field
.
Names
[
0
]
.
Name
}
func
AddStructType
(
current
Struct
core_domain
.
CodeDataStruct
,
x
*
ast
.
StructType
,
currentFile
*
core_domain
.
CodeFile
)
{
func
AddStructType
(
current
NodeName
string
,
x
*
ast
.
StructType
,
currentFile
*
core_domain
.
CodeFile
,
dsMap
map
[
string
]
*
core_domain
.
CodeDataStruct
)
{
member
:=
core_domain
.
CodeMember
{
DataStructID
:
current
Struct
.
NodeName
,
DataStructID
:
currentNodeName
,
Type
:
"struct"
,
}
for
_
,
field
:=
range
x
.
Fields
.
List
{
property
:=
BuildPropertyField
(
getFieldName
(
field
),
field
)
member
.
FileID
=
currentFile
.
FullName
currentStruct
.
InOutProperties
=
append
(
currentStruct
.
InOutProperties
,
*
property
)
dsMap
[
currentNodeName
]
.
InOutProperties
=
append
(
dsMap
[
currentNodeName
]
.
InOutProperties
,
*
property
)
}
currentFile
.
Members
=
append
(
currentFile
.
Members
,
&
member
)
currentFile
.
DataStructures
=
append
(
currentFile
.
DataStructures
,
currentStruct
)
}
pkg/infrastructure/ast/cocago/cocago_parser_test.go
浏览文件 @
f5f1b2ea
package
cocago
import
(
"bytes"
.
"github.com/onsi/gomega"
"github.com/phodal/coca/cocatest"
"os"
...
...
@@ -18,7 +19,8 @@ var testParser *CocagoParser
func
setup
()
{
testParser
=
NewCocagoParser
()
testParser
.
SetOutput
(
true
)
buf
:=
new
(
bytes
.
Buffer
)
testParser
.
SetOutput
(
buf
)
}
func
shutdown
()
{
...
...
pkg/infrastructure/ast/cocago/testdata/node_infos/struct_type_zero.json
浏览文件 @
f5f1b2ea
...
...
@@ -7,24 +7,7 @@
"Fields"
:
null
,
"FilePath"
:
""
,
"FunctionCalls"
:
null
,
"Functions"
:
null
,
"Implements"
:
null
,
"Imports"
:
null
,
"InOutProperties"
:
null
,
"InnerStructures"
:
null
,
"MultipleExtend"
:
null
,
"NodeName"
:
"O"
,
"Package"
:
""
,
"Type"
:
""
}
],
"FullName"
:
"testdata/node_infos/struct_type_zero.code"
,
"Imports"
:
null
,
"Members"
:
[
{
"DataStructID"
:
"O"
,
"FileID"
:
""
,
"FunctionNodes"
:
[
"Functions"
:
[
{
"Annotations"
:
null
,
"Extension"
:
null
,
...
...
@@ -47,6 +30,23 @@
"ReturnType"
:
""
}
],
"Implements"
:
null
,
"Imports"
:
null
,
"InOutProperties"
:
null
,
"InnerStructures"
:
null
,
"MultipleExtend"
:
null
,
"NodeName"
:
"O"
,
"Package"
:
""
,
"Type"
:
""
}
],
"FullName"
:
"testdata/node_infos/struct_type_zero.code"
,
"Imports"
:
null
,
"Members"
:
[
{
"DataStructID"
:
"O"
,
"FileID"
:
""
,
"FunctionNodes"
:
null
,
"ID"
:
""
,
"Name"
:
""
,
"Namespace"
:
null
,
...
...
pkg/infrastructure/ast/cocago/testdata/node_infos/struct_with_func_decl.json
浏览文件 @
f5f1b2ea
...
...
@@ -7,7 +7,52 @@
"Fields"
:
null
,
"FilePath"
:
""
,
"FunctionCalls"
:
null
,
"Functions"
:
null
,
"Functions"
:
[
{
"Annotations"
:
null
,
"Extension"
:
null
,
"InnerFunctions"
:
null
,
"InnerStructures"
:
null
,
"IsConstructor"
:
false
,
"IsReturnNull"
:
false
,
"MethodCalls"
:
[
{
"MethodName"
:
"Println"
,
"NodeName"
:
"fmt"
,
"Package"
:
""
,
"Parameters"
:
[
{
"Modifiers"
:
null
,
"Name"
:
""
,
"Parameters"
:
null
,
"ReturnTypes"
:
null
,
"TypeType"
:
"STRING"
,
"TypeValue"
:
"
\"
Declared outside and invoked!!!
\"
"
}
],
"Position"
:
{
"StartLine"
:
0
,
"StartLinePosition"
:
0
,
"StopLine"
:
0
,
"StopLinePosition"
:
0
},
"Type"
:
""
}
],
"Modifiers"
:
null
,
"MultipleReturns"
:
null
,
"Name"
:
"outside"
,
"Override"
:
false
,
"Parameters"
:
null
,
"Position"
:
{
"StartLine"
:
0
,
"StartLinePosition"
:
0
,
"StopLine"
:
0
,
"StopLinePosition"
:
0
},
"ReturnType"
:
""
}
],
"Implements"
:
null
,
"Imports"
:
null
,
"InOutProperties"
:
[
...
...
@@ -57,52 +102,7 @@
{
"DataStructID"
:
"person"
,
"FileID"
:
"testdata/node_infos/struct_with_func_decl.code"
,
"FunctionNodes"
:
[
{
"Annotations"
:
null
,
"Extension"
:
null
,
"InnerFunctions"
:
null
,
"InnerStructures"
:
null
,
"IsConstructor"
:
false
,
"IsReturnNull"
:
false
,
"MethodCalls"
:
[
{
"MethodName"
:
"Println"
,
"NodeName"
:
"fmt"
,
"Package"
:
""
,
"Parameters"
:
[
{
"Modifiers"
:
null
,
"Name"
:
""
,
"Parameters"
:
null
,
"ReturnTypes"
:
null
,
"TypeType"
:
"STRING"
,
"TypeValue"
:
"
\"
Declared outside and invoked!!!
\"
"
}
],
"Position"
:
{
"StartLine"
:
0
,
"StartLinePosition"
:
0
,
"StopLine"
:
0
,
"StopLinePosition"
:
0
},
"Type"
:
""
}
],
"Modifiers"
:
null
,
"MultipleReturns"
:
null
,
"Name"
:
"outside"
,
"Override"
:
false
,
"Parameters"
:
null
,
"Position"
:
{
"StartLine"
:
0
,
"StartLinePosition"
:
0
,
"StopLine"
:
0
,
"StopLinePosition"
:
0
},
"ReturnType"
:
""
}
],
"FunctionNodes"
:
null
,
"ID"
:
""
,
"Name"
:
""
,
"Namespace"
:
null
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录