Skip to content

Commit

Permalink
feat: [python] make annotation works
Browse files Browse the repository at this point in the history
  • Loading branch information
phodal committed Jan 15, 2020
1 parent f50d158 commit 6bd5da2
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 15 deletions.
2 changes: 1 addition & 1 deletion pkg/domain/trial/code_data_struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ type CodeDataStruct struct {
MemberIds []string
Extend string
Implements []string
Annotations []interface{}
Annotations interface{}
Properties []CodeProperty
Extension interface{}
}
Expand Down
5 changes: 1 addition & 4 deletions pkg/domain/trial/code_function.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@ type CodeFunction struct {
Parameters []CodeProperty
MethodCalls []CodeCall
Override bool
Annotations []CodeAnnotation
Annotations interface{}
Modifiers []string
Creators []CodeDataStruct
InnerFunctions []CodeFunction
}

type CodeAnnotation struct {
}
3 changes: 2 additions & 1 deletion trial/pkg/application/pyapp/py_ident_app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ func Test_PythonClassWithDecorator(t *testing.T) {
codeFile := app.Analysis(string(file), "testdata/grammar/class_or_func_def_stmt.py")

g.Expect(len(codeFile.DataStructures)).To(Equal(1))
g.Expect(codeFile.DataStructures[0].Annotations[0].(*trial.PythonAnnotation).Name).To(Equal("decorator"))
g.Expect(len(codeFile.DataStructures[0].Annotations.([]trial.PythonAnnotation))).To(Equal(1))

g.Expect(codeFile.Members[0].MethodNodes[0].Name).To(Equal("bar"))
g.Expect(len(codeFile.Members[0].MethodNodes[0].Annotations.([]trial.PythonAnnotation))).To(Equal(2))
}
25 changes: 25 additions & 0 deletions trial/pkg/ast/pyast/pare_tree_util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package pyast

import "github.com/antlr/antlr4/runtime/Go/antlr"

func GetNodeIndex(node antlr.ParseTree) int {
if node == nil || node.GetParent() == nil {
return -1
}
parent := node.GetParent()

for i := 0; i < parent.GetChildCount(); i++ {
if parent.GetChild(i) == node {
return i
}
}
return 0
}

func GetLeftSibling(ctx antlr.ParseTree) antlr.Tree {
index := GetNodeIndex(ctx)
if index < 1 {
return nil
}
return ctx.GetParent().GetChild(index - 1)
}
37 changes: 28 additions & 9 deletions trial/pkg/ast/pyast/python_ident_listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ package pyast

import (
"bytes"
"fmt"
"github.com/antlr/antlr4/runtime/Go/antlr"
parser "github.com/phodal/coca/languages/python"
"github.com/phodal/coca/pkg/domain/trial"
"io"
"os"
"reflect"
)

type PythonIdentListener struct {
Expand Down Expand Up @@ -41,12 +40,10 @@ func (s *PythonIdentListener) EnterClassdef(ctx *parser.ClassdefContext) {
Properties: nil,
}

switch x := ctx.GetParent().GetChild(0).(type) {
case *parser.DecoratorContext:
decorator := BuildDecorator(x)
dataStruct.Annotations = append(dataStruct.Annotations, decorator)
default:
fmt.Fprintf(output, "EnterClassdef: %s\n", reflect.TypeOf(x))
ctxIndex := GetNodeIndex(ctx)
if ctxIndex > 0 {
decorators := BuildDecoratorsByIndex(ctx, ctxIndex)
dataStruct.Annotations = decorators
}

currentCodeFile.DataStructures = append(currentCodeFile.DataStructures, dataStruct)
Expand All @@ -57,6 +54,12 @@ func (s *PythonIdentListener) EnterFuncdef(ctx *parser.FuncdefContext) {
Name: ctx.Name().GetText(),
}

ctxIndex := GetNodeIndex(ctx)
if ctxIndex > 0 {
decorators := BuildDecoratorsByIndex(ctx, ctxIndex)
function.Annotations = decorators
}

member := &trial.CodeMember{
Name: ctx.Name().GetText(),
}
Expand All @@ -65,6 +68,22 @@ func (s *PythonIdentListener) EnterFuncdef(ctx *parser.FuncdefContext) {
currentCodeFile.Members = append(currentCodeFile.Members, member)
}

func BuildDecoratorsByIndex(node antlr.ParseTree, index int) []trial.PythonAnnotation {
var nodes []parser.DecoratorContext
for i := 0; i < index; i++ {
context := node.GetParent().GetChild(i).(*parser.DecoratorContext)
nodes = append(nodes, *context)
}

var annotations []trial.PythonAnnotation
for _, node := range nodes {
decorator := BuildDecorator(&node)
annotations = append(annotations, *decorator)
}

return annotations
}

func BuildDecorator(x *parser.DecoratorContext) *trial.PythonAnnotation {
text := x.Dotted_name().GetText()

Expand All @@ -84,7 +103,7 @@ func BuildArgList(context *parser.ArglistContext) []trial.CodeProperty {
for _, arg := range context.AllArgument() {
argContext := arg.(*parser.ArgumentContext)
argument := &trial.CodeProperty{
Name: "",
Name: "",
TypeName: argContext.GetText(),
}
arguments = append(arguments, *argument)
Expand Down

0 comments on commit 6bd5da2

Please sign in to comment.