关于 OpenSibyl
提示
对于他在工业领域中的应用,可以查看 QCON2023 的演讲:代码快照 x 覆盖率:洞察研发体系的最后 100 米 。
提示
OpenSibyl 是一个开箱即用的高性能代码分析服务。仅需要一次花费数秒的分析上传,即可将您的仓库源码转换为逻辑结构存储,供您在任意时刻进行读取与使用。
- 源码
- 方法
- 类
- 引用链
sandbox-agent/src/main/java/com/alibaba/jvm/sandbox/agent/SandboxClassLoader.java
package com.alibaba.jvm.sandbox.agent;
import java.io.Closeable;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Collection;
import java.util.Enumeration;
import java.util.jar.JarFile;
class SandboxClassLoader extends URLClassLoader {
// ...
@SuppressWarnings("unused")
public void closeIfPossible() {
if (this instanceof Closeable) {
try {
((Closeable) this).close();
} catch (Throwable cause) {
// ignore...
}
return;
}
try {
final Object sun_misc_URLClassPath = forceGetDeclaredFieldValue(URLClassLoader.class, "ucp", this);
final Object java_util_Collection = forceGetDeclaredFieldValue(sun_misc_URLClassPath.getClass(), "loaders", sun_misc_URLClassPath);
for (final Object sun_misc_URLClassPath_JarLoader :
((Collection) java_util_Collection).toArray()) {
try {
final JarFile java_util_jar_JarFile = forceGetDeclaredFieldValue(sun_misc_URLClassPath_JarLoader.getClass(), "jar", sun_misc_URLClassPath_JarLoader);
java_util_jar_JarFile.close();
} catch (Throwable t) {
// if we got this far, this is probably not a JAR loader so skip it
}
}
} catch (Throwable cause) {
// ignore...
}
}
// ...
}
{
"name": "closeIfPossible",
"receiver": "com.alibaba.jvm.sandbox.agent.SandboxClassLoader",
"parameters": null,
"returns": [
{
"type": "void",
"name": ""
}
],
"span": {
"start": {
"row": 88,
"column": 4
},
"end": {
"row": 122,
"column": 5
}
},
"bodySpan": {
"start": {
"row": 89,
"column": 34
},
"end": {
"row": 122,
"column": 5
}
},
"extras": {
"annotations": [
"@SuppressWarnings(\"unused\")"
],
"classInfo": {
"annotations": null,
"className": "SandboxClassLoader",
"packageName": "com.alibaba.jvm.sandbox.agent"
}
},
"lang": "JAVA",
"path": "sandbox-agent/src/main/java/com/alibaba/jvm/sandbox/agent/SandboxClassLoader.java",
"signature": "com.alibaba.jvm.sandbox.agent.SandboxClassLoader::closeIfPossible||void"
}
[
{
"name": "SandboxClassLoader",
"module": "com.alibaba.jvm.sandbox.agent",
"span": {
"start": {
"row": 16,
"column": 0
},
"end": {
"row": 130,
"column": 1
}
},
"extras": {
"annotations": null,
"fields": [
{
"annotations": null,
"modifiers": [
"private",
"final"
],
"name": "toString",
"type": "String"
},
{
"annotations": null,
"modifiers": [
"private",
"final"
],
"name": "path",
"type": "String"
}
]
},
"lang": "JAVA",
"path": "sandbox-agent/src/main/java/com/alibaba/jvm/sandbox/agent/SandboxClassLoader.java"
}
]
{
"name": "closeIfPossible",
"receiver": "com.alibaba.jvm.sandbox.agent.SandboxClassLoader",
"parameters": null,
"returns": [
{
"type": "void",
"name": ""
}
],
"span": {
"start": {
"row": 88,
"column": 4
},
"end": {
"row": 122,
"column": 5
}
},
"bodySpan": {
"start": {
"row": 89,
"column": 34
},
"end": {
"row": 122,
"column": 5
}
},
"extras": {
"annotations": [
"@SuppressWarnings(\"unused\")"
],
"classInfo": {
"annotations": null,
"className": "SandboxClassLoader",
"packageName": "com.alibaba.jvm.sandbox.agent"
}
},
"lang": "JAVA",
"path": "sandbox-agent/src/main/java/com/alibaba/jvm/sandbox/agent/SandboxClassLoader.java",
"calls": [
"com.alibaba.jvm.sandbox.api.http.printer.Printer::close||void",
"com.alibaba.jvm.sandbox.agent.SandboxClassLoader::forceGetDeclaredFieldValue|Class<?>,String,Object|<T>",
"com.alibaba.jvm.sandbox.api.http.printer.ConcurrentLinkedQueuePrinter::close||void"
],
"reverseCalls": [
"com.alibaba.jvm.sandbox.core.manager.impl.DefaultCoreModuleManager::closeModuleJarClassLoaderIfNecessary|ClassLoader|void",
"com.alibaba.jvm.sandbox.agent.AgentLauncher::uninstall|String|void",
"com.alibaba.jvm.sandbox.core.manager.impl.ModuleJarLoader::load|ModuleLoadCallback|void"
]
}
当然他是跨语言的,且无需编译。
- 源码
- 方法
- 类
- 引用链
./extract.go
package sibyl2
import (
"context"
"errors"
"fmt"
"github.com/opensibyl/sibyl2/pkg/core"
"github.com/opensibyl/sibyl2/pkg/extractor"
)
// ExtractConfig todo: should not use config ptr for parallel running
type ExtractConfig struct {
LangType core.LangType
ExtractType extractor.ExtractType
FileFilter func(path string) bool
}
func DefaultConfig() *ExtractConfig {
return &ExtractConfig{}
}
func ExtractFromString(content string, config *ExtractConfig) (*extractor.FileResult, error) {
return ExtractFromBytes([]byte(content), config)
}
// ...
[
{
"name": "DefaultConfig",
"receiver": "",
"parameters": null,
"returns": null,
"span": {
"start": {
"row": 18,
"column": 0
},
"end": {
"row": 20,
"column": 1
}
},
"bodySpan": {
"start": {
"row": 18,
"column": 36
},
"end": {
"row": 20,
"column": 1
}
},
"extras": {},
"lang": "GOLANG",
"path": "extract.go",
"signature": "::DefaultConfig||"
},
{
"name": "ExtractFromBytes",
"receiver": "",
"parameters": [
{
"type": "[]byte",
"name": "content"
},
{
"type": "*ExtractConfig",
"name": "config"
}
],
"returns": [
{
"type": "*extractor.FileResult",
"name": ""
},
{
"type": "error",
"name": ""
}
],
"span": {
"start": {
"row": 26,
"column": 0
},
"end": {
"row": 69,
"column": 1
}
},
"bodySpan": {
"start": {
"row": 26,
"column": 92
},
"end": {
"row": 69,
"column": 1
}
},
"extras": {},
"lang": "GOLANG",
"path": "extract.go",
"signature": "::ExtractFromBytes|[]byte,*ExtractConfig|*extractor.FileResult,error"
},
{
"name": "ExtractFromString",
"receiver": "",
"parameters": [
{
"type": "string",
"name": "content"
},
{
"type": "*ExtractConfig",
"name": "config"
}
],
"returns": [
{
"type": "*extractor.FileResult",
"name": ""
},
{
"type": "error",
"name": ""
}
],
"span": {
"start": {
"row": 22,
"column": 0
},
"end": {
"row": 24,
"column": 1
}
},
"bodySpan": {
"start": {
"row": 22,
"column": 93
},
"end": {
"row": 24,
"column": 1
}
},
"extras": {},
"lang": "GOLANG",
"path": "extract.go",
"signature": "::ExtractFromString|string,*ExtractConfig|*extractor.FileResult,error"
}
]
[
{
"name": "ExtractConfig",
"module": "sibyl2",
"span": {
"start": {
"row": 12,
"column": 5
},
"end": {
"row": 16,
"column": 1
}
},
"extras": {
"fields": [
{
"name": "LangType",
"type": "core.LangType"
},
{
"name": "ExtractType",
"type": "extractor.ExtractType"
},
{
"name": "FileFilter",
"type": "func(path string) bool"
}
]
},
"lang": "GOLANG",
"path": "extract.go"
}
]
[
{
"name": "DefaultConfig",
"receiver": "",
"parameters": null,
"returns": null,
"span": {
"start": {
"row": 18,
"column": 0
},
"end": {
"row": 20,
"column": 1
}
},
"bodySpan": {
"start": {
"row": 18,
"column": 36
},
"end": {
"row": 20,
"column": 1
}
},
"extras": {},
"lang": "GOLANG",
"path": "extract.go",
"calls": [],
"reverseCalls": [
"::affectedLines2Functions|string,*ext.AffectedLineMap|*ParseResult,error"
]
},
{
"name": "ExtractFromBytes",
"receiver": "",
"parameters": [
{
"type": "[]byte",
"name": "content"
},
{
"type": "*ExtractConfig",
"name": "config"
}
],
"returns": [
{
"type": "*extractor.FileResult",
"name": ""
},
{
"type": "error",
"name": ""
}
],
"span": {
"start": {
"row": 26,
"column": 0
},
"end": {
"row": 69,
"column": 1
}
},
"bodySpan": {
"start": {
"row": 26,
"column": 92
},
"end": {
"row": 69,
"column": 1
}
},
"extras": {},
"lang": "GOLANG",
"path": "extract.go",
"calls": [
"*Extractor::ExtractCalls|[]*core.Unit|[]*object.Call,error",
"*Extractor::ExtractFunctions|[]*core.Unit|[]*object.Function,error",
"*Extractor::ExtractSymbols|[]*core.Unit|[]*object.Symbol,error",
"LangType::IsSupported||bool",
"::NewParser|LangType|",
"*Extractor::ExtractFunctions|[]*core.Unit|[]*object.Function,error",
"::GetExtractor|core.LangType|Extractor",
"*Extractor::ExtractFunctions|[]*core.Unit|[]*object.Function,error",
"*Extractor::ExtractCalls|[]*core.Unit|[]*object.Call,error",
"*Parser::ParseCtx|[]byte,context.Context|[]*Unit,error",
"*Extractor::ExtractSymbols|[]*core.Unit|[]*object.Symbol,error",
"::DataTypeOf|[]T|",
"*Extractor::ExtractFunctions|[]*core.Unit|[]*object.Function,error",
"*Extractor::ExtractCalls|[]*core.Unit|[]*object.Call,error"
],
"reverseCalls": [
"::ExtractFromString|string,*ExtractConfig|*extractor.FileResult,error"
]
},
{
"name": "ExtractFromString",
"receiver": "",
"parameters": [
{
"type": "string",
"name": "content"
},
{
"type": "*ExtractConfig",
"name": "config"
}
],
"returns": [
{
"type": "*extractor.FileResult",
"name": ""
},
{
"type": "error",
"name": ""
}
],
"span": {
"start": {
"row": 22,
"column": 0
},
"end": {
"row": 24,
"column": 1
}
},
"bodySpan": {
"start": {
"row": 22,
"column": 93
},
"end": {
"row": 24,
"column": 1
}
},
"extras": {},
"lang": "GOLANG",
"path": "extract.go",
"calls": [
"::ExtractFromBytes|[]byte,*ExtractConfig|*extractor.FileResult,error"
],
"reverseCalls": [
"::extractFromTree|core.LangType,*object.Tree,func(string) bool,string|bool"
]
}
]
提示
目前我们支持的语言可见 多语言。
- 作为一个底层组件,我们提供了多种部署模式来适应不同严格程度的业务场景。
- 除此之外,我们也允许开发者单独将其当做命令行工具、golang库使用。
- 你可以用它构建各种各样神奇的功能,例如为你的git仓库历史构建动画: