codefuse-ai/CodeFuse-Query

已知对象a,查询引用了对象a的对象

Closed this issue · 3 comments

已知对象a,查询引用了对象a的对象,引用的含义包括(对象field直接引用a,对象field引用a的子类),一直向上查询,直到最上层引用对象。例如:b对象field中引用了a,c对象field引用了a的子类a1,d对象引用了b,e引用了d,最后输出b refer a,c refer a1,a1 extends a,
d refer b, e refer d,怎么写查询脚本

这个问题太宽泛了,类似于“写个淘宝”,请以 示例代码 + 需求描述 + 期望输出 来交流。社区会给出语法和API的相关知识,但不提供写脚本的服务。

代码:

public class Test {
	private int a;
	private Test1 test1;
	private List<Message> messages;
	private TestMessage<UserInfo> messageInfo;
}
public class Test2 {
	private Test test;
}
public class Message {
	private UserInfo info;
}
public class UserInfo {
	private Test1 test1;
}

需求:查询向上引用链
期望输出:先不考虑继承关系,已知Test1对象,输出

[{"className": "UserInfo", "QuoteClassName": "Test1"},
{"className": "Test", "QuoteClassName": "Test1"},
{"className": "Test2", "QuoteClassName": "Test"},
{"className": "Message", "QuoteClassName": "UserInfo"},
{"className": "Test", "QuoteClassName": "UserInfo"},
"className": "Test", "QuoteClassName": "Message"}]

首先需要明确下概念,

  1. class的field有两种类型,分别为“引用类型(reference type)”和“原始类型(primitive type)”。你的需求中,我理解应该是只关心“引用类型”。

请参考以下脚本

// script
use coref::java::*

pub fn default_java_db() -> JavaDB {
    return JavaDB::load("coref_java_src.db")
}

pub fn is_reference_type(type: Type) -> bool {
    for(r in ReferenceType(default_java_db())) {
        if (type.id = r.oid) {
            return true
        }
    }
}

// find reference_type of a class recursively
pub fn get_ref_class(class: Class) -> *string {
    for(f in Field(__all_data__)) {
        if (f in class.getAllFields() && is_reference_type(f.getType())) {
            yield f.getType().getQualifiedName()
            for (c in Class(__all_data__)) {
                if (c.getQualifiedName() = f.getType().getQualifiedName()) {
                    yield get_ref_class(c)
                }
            }
        }
    }
}

pub fn output_class_and_field(className: string, fieldType: string) -> bool {
    for(class in Class(default_java_db()), res in string::__undetermined_all__()) {
        if(res in get_ref_class(class)) {
            return className = class.getQualifiedName() && fieldType = res
        }
    }
}

pub fn main() {
    output(output_class_and_field())
}

注意:该脚本没有处理泛型,请尝试自行查询TypeElement 相关API来实现。完成脚本后,欢迎贡献回社区。