JavaCallListener.go 5.4 KB
Newer Older
P
Phodal HUANG 已提交
1
package call
P
Phodal HUANG 已提交
2 3

import (
P
Phodal HUANG 已提交
4
	. "../../language/java"
P
Phodal HUANG 已提交
5
	. "../models"
P
Phodal HUANG 已提交
6
	"github.com/antlr/antlr4/runtime/Go/antlr"
P
Phodal HUANG 已提交
7 8
	"reflect"
	"strings"
P
Phodal HUANG 已提交
9 10 11
)

var imports []string
P
Phodal HUANG 已提交
12
var clzs []string
P
Phodal HUANG 已提交
13 14
var currentPkg string
var currentClz string
P
Phodal HUANG 已提交
15
var methods []JMethod
P
Phodal HUANG 已提交
16
var methodCalls []JMethodCall
P
Phodal HUANG 已提交
17
var currentType string
P
Phodal HUANG 已提交
18 19 20 21

var fields = make(map[string]string)
var localVars = make(map[string]string)
var formalParameters = make(map[string]string)
P
Phodal HUANG 已提交
22

P
Phodal HUANG 已提交
23 24 25
func NewJavaCallListener() *JavaCallListener {
	currentClz = ""
	currentPkg = ""
P
Phodal HUANG 已提交
26
	methods = nil
P
Phodal HUANG 已提交
27 28 29
	return &JavaCallListener{}
}

P
Phodal HUANG 已提交
30 31 32 33
type JavaCallListener struct {
	BaseJavaParserListener
}

P
Phodal HUANG 已提交
34
func (s *JavaCallListener) getNodeInfo() *JClassNode {
P
Phodal HUANG 已提交
35
	return &JClassNode{currentPkg, currentClz, currentType, "", methods, methodCalls}
P
Phodal HUANG 已提交
36 37
}

P
Phodal HUANG 已提交
38 39 40 41 42 43 44 45 46 47
func (s *JavaCallListener) EnterPackageDeclaration(ctx *PackageDeclarationContext) {
	currentPkg = ctx.QualifiedName().GetText()
}

func (s *JavaCallListener) EnterImportDeclaration(ctx *ImportDeclarationContext) {
	importText := ctx.QualifiedName().GetText()
	imports = append(imports, importText)
}

func (s *JavaCallListener) EnterClassDeclaration(ctx *ClassDeclarationContext) {
P
Phodal HUANG 已提交
48
	currentType = "Class"
P
Phodal HUANG 已提交
49 50 51 52
	currentClz = ctx.IDENTIFIER().GetText()
}

func (s *JavaCallListener) EnterInterfaceDeclaration(ctx *InterfaceDeclarationContext) {
P
Phodal HUANG 已提交
53
	currentType = "Interface"
P
Phodal HUANG 已提交
54 55 56 57
	currentClz = ctx.IDENTIFIER().GetText()
}

func (s *JavaCallListener) EnterInterfaceMethodDeclaration(ctx *InterfaceMethodDeclarationContext) {
P
Phodal HUANG 已提交
58
	startLine := ctx.GetStart().GetLine()
P
Phodal HUANG 已提交
59
	startLinePosition := ctx.IDENTIFIER().GetSymbol().GetColumn()
P
Phodal HUANG 已提交
60 61
	stopLine := ctx.GetStop().GetLine()
	name := ctx.IDENTIFIER().GetText()
P
Phodal HUANG 已提交
62
	stopLinePosition := startLinePosition + len(name)
P
Phodal HUANG 已提交
63 64 65 66
	//XXX: find the start position of {, not public
	method := &JMethod{name, startLine, startLinePosition, stopLine, stopLinePosition}

	methods = append(methods, *method)
P
Phodal HUANG 已提交
67 68
}

P
Phodal HUANG 已提交
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
func (s *JavaCallListener) EnterFormalParameter(ctx *FormalParameterContext) {
	formalParameters[ctx.VariableDeclaratorId().GetText()] = ctx.TypeType().GetText()
}

func (s *JavaCallListener) EnterFieldDeclaration(ctx *FieldDeclarationContext) {
	declarators := ctx.VariableDeclarators()
	variableName := declarators.GetParent().GetChild(0).(antlr.ParseTree).GetText()
	fields[variableName] = ctx.TypeType().GetText()
}

func (s *JavaCallListener) EnterLocalVariableDeclaration(ctx *LocalVariableDeclarationContext) {
	typ := ctx.GetChild(0).(antlr.ParseTree).GetText()
	variableName := ctx.GetChild(1).GetChild(0).GetChild(0).(antlr.ParseTree).GetText()
	localVars[variableName] = typ
}

P
Phodal HUANG 已提交
85
func (s *JavaCallListener) EnterMethodDeclaration(ctx *MethodDeclarationContext) {
P
Phodal HUANG 已提交
86
	startLine := ctx.GetStart().GetLine()
P
Phodal HUANG 已提交
87
	startLinePosition := ctx.IDENTIFIER().GetSymbol().GetColumn()
P
Phodal HUANG 已提交
88 89
	stopLine := ctx.GetStop().GetLine()
	name := ctx.IDENTIFIER().GetText()
P
Phodal HUANG 已提交
90
	stopLinePosition := startLinePosition + len(name)
P
Phodal HUANG 已提交
91 92 93
	//XXX: find the start position of {, not public
	method := &JMethod{name, startLine, startLinePosition, stopLine, stopLinePosition}
	methods = append(methods, *method)
P
Phodal HUANG 已提交
94 95 96
}

func (s *JavaCallListener) EnterMethodCall(ctx *MethodCallContext) {
P
Phodal HUANG 已提交
97 98
	var targetCtx = ctx.GetParent().GetChild(0).(antlr.ParseTree).GetText()
	var targetType = parseTargetType(targetCtx)
P
Phodal HUANG 已提交
99 100 101
	callee := ctx.GetChild(0).(antlr.ParseTree).GetText()

	startLine := ctx.GetStart().GetLine()
P
Phodal HUANG 已提交
102
	startLinePosition := ctx.GetStart().GetColumn()
P
Phodal HUANG 已提交
103
	stopLine := ctx.GetStop().GetLine()
P
Phodal HUANG 已提交
104
	stopLinePosition := startLinePosition + len(callee)
P
Phodal HUANG 已提交
105

P
Phodal HUANG 已提交
106
	fullType := warpTargetFullType(targetType)
P
Phodal HUANG 已提交
107
	if fullType != "" {
P
Phodal HUANG 已提交
108
		jMethodCall := &JMethodCall{removeTarget(fullType), targetType, callee, startLine, startLinePosition, stopLine, stopLinePosition}
P
Phodal HUANG 已提交
109 110
		methodCalls = append(methodCalls, *jMethodCall)
	} else {
P
Phodal HUANG 已提交
111

P
Phodal HUANG 已提交
112 113 114
	}
}

P
Phodal HUANG 已提交
115 116 117
func (s *JavaCallListener) EnterExpression(ctx *ExpressionContext) {
	if ctx.COLONCOLON() != nil {
		text := ctx.Expression(0).GetText()
P
Phodal HUANG 已提交
118
		methodName := ctx.IDENTIFIER().GetText()
P
Phodal HUANG 已提交
119 120 121 122 123 124 125 126 127
		targetType := parseTargetType(text)
		fullType := warpTargetFullType(targetType)


		startLine := ctx.GetStart().GetLine()
		startLinePosition := ctx.GetStart().GetColumn()
		stopLine := ctx.GetStop().GetLine()
		stopLinePosition := startLinePosition + len(text)

P
Phodal HUANG 已提交
128
		jMethodCall := &JMethodCall{removeTarget(fullType), targetType, methodName, startLine, startLinePosition, stopLine, stopLinePosition}
P
Phodal HUANG 已提交
129 130 131 132
		methodCalls = append(methodCalls, *jMethodCall)
	}
}

P
Phodal HUANG 已提交
133 134 135 136
func (s *JavaCallListener) appendClasses(classes []string) {
	clzs = classes
}

P
Phodal HUANG 已提交
137 138 139 140 141
func removeTarget(fullType string) string {
	split := strings.Split(fullType, ".")
	return strings.Join(split[:len(split)-1], ".")
}

P
Phodal HUANG 已提交
142 143 144
func parseTargetType(targetCtx string) string {
	targetVar := targetCtx
	targetType := targetVar
P
Phodal HUANG 已提交
145

P
Phodal HUANG 已提交
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
	//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;
		}
	}

P
Phodal HUANG 已提交
163
	return targetType
P
Phodal HUANG 已提交
164
}
P
Phodal HUANG 已提交
165 166 167

func warpTargetFullType(targetType string) string {
	if strings.EqualFold(currentClz, targetType) {
P
Phodal HUANG 已提交
168
		return currentPkg + "." + targetType
P
Phodal HUANG 已提交
169
	}
P
Phodal HUANG 已提交
170

P
Phodal HUANG 已提交
171 172 173 174 175 176 177
	for index := range imports {
		imp := imports[index]
		if strings.HasSuffix(imp, targetType) {
			return imp
		}
	}

P
Phodal HUANG 已提交
178 179 180 181 182 183 184 185
	//maybe the same package
	for _, clz := range clzs {
		if strings.HasSuffix(clz, "." + targetType) {
			return clz
		}
	}

	//1. current package, 2. import by *
P
Phodal HUANG 已提交
186 187
	return ""
}