how to get Go PSI user defined type's definition.

已回答

 

I have definied two struct as below

type BaseEntity struct {
CreatedAt sql.NullTime
CreatedBy string
UpdatedAt sql.NullTime
UpdatedBy string
}

type Order struct {
CustNo string
OrderNum string
OrderQty int32
Price float32
BaseEntity
}

right now I got the PsiElement of Order Struct, there is a embedded go struct BaseEntity in it.

I use below code to iterate all the children of Order Struct.

for (ele in struct.children) {
println(ele.text)
}

for the built-in type, it works fine. but for any user defined type I want to print it recursively. for the case here it should 

println CreatedAt,  CreatedBy, UpdatedAt, UpdatedBy.

 

0
正式评论

Hey. Your PsiElement should be a GoStructType. In that case, you can do something like this:

private void printFields(@NotNull GoStructType structType) {
for (GoFieldDeclaration declaration : structType.getFieldDeclarationList()) {
GoAnonymousFieldDefinition anonymous = declaration.getAnonymousFieldDefinition();
if (anonymous != null) {
GoTypeReferenceExpression typeRef = anonymous.getTypeReferenceExpression();
PsiElement resolve = typeRef != null ? typeRef.resolve() : null;
if (resolve instanceof GoTypeSpec) {
GoTypeSpec typeSpec = (GoTypeSpec)resolve;
GoType type = typeSpec.getSpecType().getType();
if (type instanceof GoStructType) {
printFields((GoStructType)type);
}
}
}
else {
for (GoFieldDefinition definition : declaration.getFieldDefinitionList()) {
System.out.println(definition.getName());
}
}
}
}

To better understand the structure of the PSI tree, please use PsiViewer plugin: https://plugins.jetbrains.com/plugin/227-psiviewer

It works well, thank you very much!

1

following code can execute successfully in  gradle runIde mode, but it failed in the unit test mode.

here is the struct type

type OrderHeader struct {
Sku string
BatchNo *string
Seq uint8
BaseEntity
}

type Order struct {
Id int16 `json:"id" db:"name=id, PK"`
CustNo string
BasicInfo OrderHeader `db:"join=Sku, BatchNo"`
OrderNum string
OrderQty int
Price float32
BaseEntity
}

 

for (declaration in structType.fieldDeclarationList) {
val typeRef =
declaration.type?.typeReferenceExpression
?: declaration.anonymousFieldDefinition?.typeReferenceExpression


val resolve = typeRef?.resolve()

 

from the https://plugins.jetbrains.com/plugin/227-psiviewer, I found there is always a typeReferenceExpression for both a builtin type(such as string, float32) and struct type.

 

it works well when it's executed in gradle runIde mode. but this piece of code run into error when I call method from junit.

the error thorws from there

PsiPolyVariantReferenceBase.java

@Override
@Nullable
public PsiElement resolve() {
ResolveResult[] resolveResults = multiResolve(false);
return resolveResults.length == 1 ? resolveResults[0].getElement() : null;
}

 

below call return null for a simple Type (ID)

ResolveResult[] resolveResults = multiResolve(false);

 

 

by the way I am using below BasePlatformTestCase base class from test-framework.jar (https://plugins.jetbrains.com/docs/intellij/tests-and-fixtures.html)

 

@RunWith(JUnit4::class)
class StructServiceKtTest : BasePlatformTestCase() {
0

Hm. You code looks valid, so I am not sure what could be wrong. As your plugin is managed by Gradle, could you try to execute the test using Gradle, not JUnit directly?

0

请先登录再写评论。