Skip to content

Commit 30575a1

Browse files
committed
orm util
1 parent 587c72e commit 30575a1

File tree

1 file changed

+146
-0
lines changed
  • src/main/kotlin/com/github/oldmegit/goframeidea/goFrame

1 file changed

+146
-0
lines changed
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
package com.github.oldmegit.goframeidea.goFrame
2+
3+
import com.goide.psi.*
4+
import com.goide.psi.impl.GoPsiUtil
5+
import com.intellij.psi.PsiComment
6+
import com.intellij.psi.PsiElement
7+
import com.intellij.psi.ResolveState
8+
import com.intellij.psi.util.PsiTreeUtil
9+
import com.intellij.util.ObjectUtils
10+
11+
object OrmUtil {
12+
// get statement contain XXXDao by given PsiElement
13+
fun getStatementContainDao(psiElement: PsiElement): GoStatement? {
14+
// get direct statement
15+
var statement = PsiTreeUtil.findFirstParent(psiElement) { e: PsiElement? ->
16+
e is GoStatement
17+
} as GoStatement?
18+
19+
if (statement is GoAssignmentStatement) {
20+
statement = doAssignmentStatement(statement)
21+
} else if (statement is GoSimpleStatement) {
22+
statement = doSimpleStatement(statement)
23+
}
24+
25+
return statement
26+
}
27+
28+
// get Xxx dao by statement
29+
fun getDaoByStatement(statement: GoStatement): GoStructType? {
30+
for (callExpr in PsiTreeUtil.findChildrenOfType(statement, GoCallExpr::class.java)) {
31+
val reference = GoPsiUtil.getCallReference(callExpr)
32+
// get the declaration of fun
33+
val declaration = ObjectUtils.tryCast(
34+
reference!!.resolve(),
35+
GoMethodDeclaration::class.java
36+
)
37+
38+
// get the return type of fun's declaration
39+
var resultType = declaration!!.resultType
40+
41+
// get the gotype if return type is gotype pointer
42+
// resultType is Model or gdb.Model
43+
if (resultType is GoPointerType) {
44+
resultType = resultType.type!!
45+
}
46+
47+
if (resultType.resolve(ResolveState.initial()) !is GoTypeSpec) {
48+
continue
49+
}
50+
51+
val pointerType = declaration.receiver!!.type
52+
if (pointerType !is GoPointerType) {
53+
continue
54+
}
55+
val type = pointerType.type ?: return null
56+
if (!type.text?.endsWith("Dao")!!) {
57+
continue
58+
}
59+
60+
val spec = type.resolve(ResolveState.initial())
61+
if (spec is GoTypeSpec) {
62+
return spec.specType.type as GoStructType
63+
}
64+
}
65+
return null
66+
}
67+
68+
// get column GoType by XxxDao of type GoStructType
69+
fun getColumnByDao(structType: GoStructType): GoType? {
70+
for (field in structType.fieldDeclarationList) {
71+
val name = field.fieldDefinitionList[0].name?.lowercase()
72+
if (name?.endsWith("columns")!!) {
73+
return field.type
74+
}
75+
}
76+
return null
77+
}
78+
79+
// get table data by XXXColumns of type GoTypeSpec
80+
fun getTableData(columnType: GoType): Map<String, String> {
81+
val typeSpec = columnType.resolve(ResolveState.initial()) as GoTypeSpec
82+
val fields = PsiTreeUtil.findChildrenOfType(typeSpec, GoFieldDeclaration::class.java)
83+
val data: MutableMap<String, String> = hashMapOf()
84+
for (field in fields) {
85+
val fieldDefinition = field.firstChild
86+
if (fieldDefinition !is GoFieldDefinition) {
87+
continue
88+
}
89+
val psiComment = field.nextSibling.nextSibling
90+
var comment = ""
91+
if (psiComment is PsiComment) {
92+
comment = extractTextFromComment(psiComment.text)
93+
}
94+
data[fieldDefinition.text.camelToSnakeCase()] = comment
95+
}
96+
return data
97+
}
98+
99+
// handle type GoAssignmentStatement
100+
// for example:
101+
// db = db.Xxx
102+
private fun doAssignmentStatement(assignmentStatement: GoAssignmentStatement): GoStatement? {
103+
for (expression in assignmentStatement.leftHandExprList.expressionList) {
104+
val psiElementRoot = expression.reference?.resolve()
105+
return getStatementContainDao(psiElementRoot!!)
106+
}
107+
return null
108+
}
109+
110+
// handle type GoSimpleStatement
111+
// for example:
112+
// db := db.Xxx
113+
// db.Xxx or dao.Xxx
114+
private fun doSimpleStatement(simpleStatement: GoSimpleStatement): GoStatement? {
115+
val declaration = simpleStatement.shortVarDeclaration
116+
// direct return if db := db.Xxx
117+
if (declaration != null) {
118+
return simpleStatement
119+
}
120+
121+
// db.Xxx
122+
val list = PsiTreeUtil.findChildrenOfType(simpleStatement, GoReferenceExpression::class.java)
123+
val last = list.last()
124+
if (last.resolve() is GoVarDefinition) {
125+
return getStatementContainDao(last.resolve() as GoVarDefinition)
126+
}
127+
128+
return null
129+
}
130+
131+
private fun extractTextFromComment(comment: String): String {
132+
if (!comment.startsWith("//")) {
133+
return comment
134+
}
135+
if (comment == "//") {
136+
return ""
137+
}
138+
return comment.drop(2)
139+
}
140+
141+
// camel to snake case
142+
private fun String.camelToSnakeCase(): String {
143+
val regex = "(?<=[a-zA-Z])[A-Z]".toRegex()
144+
return regex.replace(this) { "_${it.value}" }.lowercase()
145+
}
146+
}

0 commit comments

Comments
 (0)