You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GoLand插件开发:通过GoFunctionDeclaration获取GoStructType对象

如何通过GoFunctionDeclaration获取GoStructType并读取结构体字段?

我正在开发GoLand插件,想要通过GoFunctionDeclaration获取GoStructType对象,进而获取结构体的所有字段。以下是示例Go代码:

type SiteInfo struct {
    id int64
}

type SiteResult struct {
    id int64
}

func test(info *SiteInfo) *SiteResult{
    return nil
}

我需要获取上述test函数的参数(*SiteInfo)和返回值(*SiteResult)对应的GoStructType对象,以获取结构体的所有字段(例如SiteInfo的id字段)。现有部分Java代码如下:

public class TransformAction extends AnAction {

    private Project project;

    @Override
    public void actionPerformed(@NotNull AnActionEvent e) {

        // offset is current offset
        PsiElement psiElement = PsiUtilCore.getElementAtOffset(psiFile, offset);
        GoFunctionDeclaration func = PsiTreeUtil.getParentOfType(psiElement, GoFunctionDeclaration.class);
        GoSignature signature = func.getSignature();
        signature.getResultType();// how to get GoStructType.class
        signature.getParameters(); // how to get GoStructType.class

   }
}

请问如何修改代码实现该需求?


解决方案

要获取指针类型对应的结构体类型,需要先解析指针的底层类型,再转换为GoStructType,之后即可遍历结构体字段。以下是修改后的完整代码:

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilCore;
import go.psi.*;
import org.jetbrains.annotations.NotNull;

public class TransformAction extends AnAction {

    private Project project;

    @Override
    public void actionPerformed(@NotNull AnActionEvent e) {
        // 假设psiFile和offset已正确初始化
        PsiElement psiElement = PsiUtilCore.getElementAtOffset(psiFile, offset);
        GoFunctionDeclaration func = PsiTreeUtil.getParentOfType(psiElement, GoFunctionDeclaration.class);
        if (func == null) return;

        GoSignature signature = func.getSignature();
        if (signature == null) return;

        // 处理函数返回值
        processTypeToGetStructFields(signature.getResultType());

        // 处理函数参数
        for (GoParameter param : signature.getParameters()) {
            processTypeToGetStructFields(param.getGoType());
        }
    }

    /**
     * 解析类型并提取结构体字段
     */
    private void processTypeToGetStructFields(GoType type) {
        if (type == null) return;

        // 处理指针类型,获取其指向的底层类型
        if (type instanceof GoPointerType) {
            GoPointerType pointerType = (GoPointerType) type;
            type = pointerType.getType();
        }

        // 转换为结构体类型并遍历字段
        if (type instanceof GoStructType) {
            GoStructType structType = (GoStructType) type;
            for (GoFieldDeclaration fieldDecl : structType.getFieldDeclarationList()) {
                for (GoFieldDefinition fieldDef : fieldDecl.getFieldDefinitionList()) {
                    String fieldName = fieldDef.getIdentifier().getText();
                    String fieldTypeText = fieldDef.getFieldType().getText();
                    // 这里可根据需求处理字段信息,比如打印或存储
                    System.out.printf("字段:%s,类型:%s\n", fieldName, fieldTypeText);
                }
            }
        }
    }
}

关键逻辑说明

  • 解析指针类型:当目标类型是GoPointerType时,调用getType()获取其指向的实际结构体类型,这是处理*SiteInfo这类指针类型的核心步骤。
  • 转换结构体类型:将底层类型强转为GoStructType,通过getFieldDeclarationList()获取结构体的字段声明集合。
  • 遍历字段信息:每个GoFieldDeclaration可能包含多个字段定义,遍历getFieldDefinitionList()即可拿到单个字段的名称和类型详情。

内容的提问来源于stack exchange,提问作者beer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 22:02:23