diff --git a/language/java/extractor/README.md b/language/java/extractor/README.md
new file mode 100644
index 00000000..859d8070
--- /dev/null
+++ b/language/java/extractor/README.md
@@ -0,0 +1,9 @@
+# Introduction
+The codefuse-query java extractor transforms the source code of Java projects into standardized coref-java data, which is utilized for further analysis by codefuse-query.
+
+# Quick Start
+1. Set `JAVA_HOME`. Execute `echo $JAVA_HOME` to display its current setting. If it displays as empty, then it has not been configured yet.
+2. Build. Execute `mvn clean install`.
+3. Run. Execute `java -jar target/java-extractor-1.0-SNAPSHOT-jar-with-dependencies.jar ${YOUR_JAVA_REPO} ./db`.
+
+After execution, a file named coref_java_src.db will be generated in the ./db directory.
diff --git a/language/java/extractor/README_cn.md b/language/java/extractor/README_cn.md
new file mode 100644
index 00000000..ee3b09e9
--- /dev/null
+++ b/language/java/extractor/README_cn.md
@@ -0,0 +1,9 @@
+# 介绍
+codefuse-query java extractor 将 java 项目的源码转化为 coref-java 标准化数据,用于codefuse-query的进一步分析。
+
+# 快速开始
+1. 设置 JAVA_HOME。`echo $JAVA_HOME` 如果显示为空,则还没有设置好。
+2. 构建。 `mvn clean install`。
+3. 运行。 `java -jar target/java-extractor-1.0-SNAPSHOT-jar-with-dependencies.jar ${YOUR_JAVA_REPO} ./db`
+
+执行完成后,会在 ./db 目录下生成 coref_java_src.db 文件。
diff --git a/language/java/extractor/pom.xml b/language/java/extractor/pom.xml
new file mode 100644
index 00000000..ae558719
--- /dev/null
+++ b/language/java/extractor/pom.xml
@@ -0,0 +1,258 @@
+
+ 4.0.0
+
+ com.alipay.tool
+ java-extractor
+ 0.2.0
+
+ jar
+
+ coref-java-src-extractor
+ http://maven.apache.org
+
+
+ UTF-8
+ 1.5.21
+
+
+
+ org.mybatis
+ mybatis
+ 3.5.7
+
+
+ javax.annotation
+ javax.annotation-api
+ 1.3.2
+
+
+ org.mybatis.dynamic-sql
+ mybatis-dynamic-sql
+ 1.3.0
+
+
+ commons-codec
+ commons-codec
+ 1.15
+
+
+ com.ibm.icu
+ icu4j
+ 59.1
+
+
+
+ org.apache.commons
+ commons-lang3
+ 3.12.0
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.20
+ provided
+
+
+ me.tongfei
+ progressbar
+ 0.9.2
+
+
+
+ org.jetbrains
+ annotations
+ 22.0.0
+
+
+ uk.com.robust-it
+ cloning
+ 1.9.12
+
+
+
+ com.google.code.gson
+ gson
+ 2.8.8
+
+
+ com.google.guava
+ guava
+ 30.1.1-jre
+
+
+ org.hamcrest
+ hamcrest-all
+ 1.3
+
+
+ com.google.re2j
+ re2j
+ 1.6
+
+
+ org.jetbrains.kotlin
+ kotlin-compiler-embeddable
+ ${kotlin.version.coref}
+
+
+ org.jetbrains.kotlin
+ kotlin-reflect
+ ${kotlin.version.coref}
+
+
+ org.jetbrains.kotlin
+ kotlin-script-runtime
+ ${kotlin.version.coref}
+
+
+ org.jetbrains.kotlin
+ kotlin-stdlib
+ ${kotlin.version.coref}
+
+
+
+ net.java.dev.jna
+ jna
+ 4.1.0
+
+
+
+ org.xerial
+ sqlite-jdbc
+ 3.36.0.2
+
+
+
+ tk.mybatis
+ mapper
+ 4.1.5
+
+
+ org.junit.jupiter
+ junit-jupiter
+ 5.9.1
+ test
+
+
+ info.picocli
+ picocli
+ 4.6.1
+
+
+ org.apache.logging.log4j
+ log4j-core
+ 2.14.1
+
+
+ org.apache.logging.log4j
+ log4j-api
+ 2.14.1
+
+
+ org.apache.logging.log4j
+ log4j-slf4j-impl
+ 2.14.1
+
+
+
+ commons-io
+ commons-io
+ 2.8.0
+
+
+ commons-collections
+ commons-collections
+ 3.2.2
+
+
+ com.aliyun.oss
+ aliyun-sdk-oss
+ 3.10.2
+
+
+ org.apache.commons
+ commons-compress
+ 1.18
+
+
+ com.alibaba
+ fastjson
+ 1.2.72_noneautotype
+
+
+ org.ini4j
+ ini4j
+ 0.5.4
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+ 8
+ 8
+
+
+
+ org.mybatis.generator
+ mybatis-generator-maven-plugin
+ 1.4.0
+
+ false
+ true
+
+
+
+ org.xerial
+ sqlite-jdbc
+ 3.36.0.1
+
+
+ tk.mybatis
+ mapper
+ 4.1.5
+
+
+
+
+ Generate MyBatis Artifacts
+
+ generate
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 3.3.0
+
+
+
+ com.alipay.codequery.Extractor
+
+
+
+ jar-with-dependencies
+
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+
+
+
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/Configuration.java b/language/java/extractor/src/main/java/com/alipay/codequery/Configuration.java
new file mode 100644
index 00000000..37fd069c
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/Configuration.java
@@ -0,0 +1,87 @@
+package com.alipay.codequery;
+
+import com.alipay.codequery.project.ProjectUtil;
+import com.alipay.codequery.util.PathUtil;
+import lombok.Getter;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.util.*;
+
+
+public class Configuration implements Cloneable {
+
+ public final String commitId = "init";
+ public final String repository = "Not Specified";
+ public List sourcepath = new ArrayList<>();
+ public String javaHome = null;
+ public List classpath = new ArrayList<>();
+
+ @Getter
+ private final @NotNull Collection kotlinFiles = new HashSet<>();
+ @Getter
+ private final @NotNull Collection javaFiles = new HashSet<>();
+ @Getter
+ private final @NotNull Set javaDirs = new HashSet<>();
+ @Getter
+ private final List classFiles = new ArrayList<>();
+
+ /**
+ * MENTION: we allow multiple source paths exist but we ONLY use the first one as root
+ */
+ public String getSourcePath() {
+ return sourcepath.get(0);
+ }
+
+ public void prepareFile() {
+ clearExistedFiles();
+
+ // jar class path
+ ProjectUtil.getClassPaths(this.classpath).stream().map(File::new).forEach(classFiles::add);
+
+ // source file path
+ for (String sourceRoot : sourcepath) {
+ File file = new File(sourceRoot).getAbsoluteFile();
+ withJavaSrc(file);
+ withKotlinSrc(file);
+ }
+ }
+
+ public void withKotlinSrc(File root) {
+ ArrayList results = new ArrayList<>();
+
+ PathUtil.TraverseBuilder traversal = new PathUtil.TraverseBuilder()
+ .withSymbol(false)
+ .withDirInResult(false)
+ .withSuffix(".kt");
+ traversal.traverse(root, results);
+
+ kotlinFiles.addAll(results);
+ }
+
+
+ public void withJavaSrc(File root) {
+ ArrayList results = new ArrayList<>();
+ PathUtil.TraverseBuilder traversal = new PathUtil.TraverseBuilder()
+ .withSymbol(false)
+ .withDirInResult(true)
+ .withSuffix(".java");
+ traversal.traverse(root, results);
+
+ for (File file : results) {
+ if (file.isDirectory()) {
+ javaDirs.add(file);
+ } else {
+ javaFiles.add(file);
+ }
+ }
+ }
+
+ private void clearExistedFiles() {
+ javaFiles.clear();
+ javaDirs.clear();
+ kotlinFiles.clear();
+ classFiles.clear();
+ }
+
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/Extractor.java b/language/java/extractor/src/main/java/com/alipay/codequery/Extractor.java
new file mode 100644
index 00000000..9f9ed712
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/Extractor.java
@@ -0,0 +1,245 @@
+package com.alipay.codequery;
+
+import com.alipay.codequery.coref.storage.CorefCache;
+import com.alipay.codequery.coref.storage.LocalCorefCache;
+import com.alipay.codequery.coref.storage.OssCorefCache;
+import com.alipay.codequery.coref.storage.RemoteCacheType;
+import com.alipay.codequery.coref.util.ConvertCodeUtil;
+import com.alipay.codequery.project.PsiProject;
+import com.alipay.codequery.project.ProjectBuilder;
+import com.alipay.codequery.util.LoggerUtil;
+import com.alipay.codequery.coref.core.Runner;
+import com.alipay.codequery.coref.core.SharedManager;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.kotlin.com.intellij.openapi.util.io.FileUtil;
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Parameters;
+
+import java.io.*;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.Callable;
+import java.util.stream.Collectors;
+
+@Command(name = "extract", mixinStandardHelpOptions = true, version = "extract 1.0",
+ description = "extract COREF-Java db from a src directory.")
+@Slf4j
+public class Extractor implements Callable {
+ private static final Logger logger = LogManager.getLogger(Extractor.class);
+
+ public static final int DEFAULT_WORKER_COUNT = Integer.min(Runtime.getRuntime().availableProcessors(), 8);
+
+ public static Configuration configuration = new Configuration();
+
+ // Arguments and Options
+ @Parameters(index = "0", description = "The source directory to extract.")
+ private File srcRootDir;
+
+ @Parameters(index = "1", description = "The output directory for the DB file.")
+ private File dbDir;
+
+ @CommandLine.Option(names = {"-w", "--white-list"}, description = "The white list to extract.", required = false)
+ private File whiteList;
+
+ @CommandLine.Option(names = {"-p", "--parallel"}, description = "Set run in parallel (threads)")
+ public boolean parallelRequested = false;
+
+ @CommandLine.Option(names = {"--commit"}, description = "current repo's commit")
+ public String commitId;
+
+ @CommandLine.Option(names = {"--incremental"}, description = "enable incremental extract")
+ public boolean incremental = false;
+
+ @CommandLine.Option(names = {"--cache-dir"}, description = "cache dir")
+ public String cacheDir;
+
+ @CommandLine.Option(names = {"--remote-cache-type"}, description = "remote cache type. eg. oss")
+ public String remoteCacheTypeName;
+
+ @CommandLine.Option(names = {"--oss-bucket"}, description = "oss bucket")
+ public String ossBucket;
+
+ @CommandLine.Option(names = {"--oss-config-file"}, description = "oss config file")
+ public File ossConfigFile;
+
+ @CommandLine.Option(names = {"--oss-path-prefix"}, description = "oss path prefix, should end with '/'.")
+ public String ossPathPrefix;
+
+ @CommandLine.Option(names = {"--verbose"}, description = "Set run with verbose")
+ public boolean verbose = false;
+
+ @CommandLine.Option(names = {"-j", "--workers"}, description = "Set run worker limit")
+ public int workerCount = DEFAULT_WORKER_COUNT;
+
+ @CommandLine.Option(names = {"--java-home"}, description = "JDK Home")
+ public String javaHome = System.getenv("JAVA_HOME");
+
+ @CommandLine.Option(names = {"-cp", "--classpath"}, description = "PSI class path")
+ public String classPath;
+
+ @CommandLine.Option(names = {"--dump-coref-ast-path"}, description = "The path of dumped coref ast")
+ public String corefASTPath;
+
+ @Override
+ public Integer call() throws Exception { // your business logic goes here...
+ long start = System.currentTimeMillis();
+ if (verbose) {
+ LoggerUtil.initLogger(Level.DEBUG);
+ } else {
+ LoggerUtil.initLogger(Level.INFO);
+ }
+
+ // Exit if JAVA_HOME is not set
+ if (javaHome == null) {
+ logger.error("Missing JAVA_HOME!");
+ return 3;
+ }
+
+ log.info("start extracting with root: {}", srcRootDir.getAbsolutePath());
+ log.info("java home: {}", javaHome);
+
+ // Why set configuration here but use configuration.sourcePath later?
+ configuration.sourcepath = Collections.singletonList(srcRootDir.getAbsolutePath());
+ configuration.javaHome = javaHome;
+ configuration.classpath = parseClassPath(classPath);
+ // must do this prepare
+ configuration.prepareFile();
+
+ // Regular the file codec
+ configuration.getJavaFiles().forEach(file -> {
+ try {
+ ConvertCodeUtil.normCodecToUTF8ForFile(file);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ });
+
+ // Make a builder
+ // The inner will scan and include all Java Src files and so on
+ ProjectBuilder projectBuilder = ProjectBuilder.getInstance(configuration, false);
+ projectBuilder.shouldBuildResolveInfo(true);
+
+ // Build the project
+ PsiProject basicProject = projectBuilder.createProject();
+ SharedManager.clear();
+
+ List whiteFiles = null;
+ if (whiteList != null) {
+ whiteFiles = getWhiteList(whiteList).stream()
+ .map(file -> Paths.get(file).toFile()).collect(Collectors.toList());
+ }
+
+ // Create dbDir if it not exists
+ if (this.corefASTPath == null){
+ FileUtil.createDirectory(dbDir);
+ }
+
+ // Run to analyse
+ try {
+ if (this.corefASTPath != null){
+ // corefASTPath抽取只使用sequenceAnalyse,其他的分析方式不支持
+ Runner runner = new Runner(configuration, basicProject, whiteFiles, srcRootDir);
+ runner.sequenceDumpCorefAST(this.corefASTPath);
+ }
+ else if (whiteFiles != null ) {
+ Runner runner = new Runner(configuration, basicProject, whiteFiles, srcRootDir);
+ runner.sequenceAnalyse(dbDir.toString(), "coref_java_src.db");
+ } else {
+ List allFiles = basicProject.allJavaPaths().collect(Collectors.toList());
+ Runner runner = new Runner(configuration, basicProject, allFiles, srcRootDir);
+ if (incremental) {
+ if (StringUtils.isBlank(cacheDir) || "null".equals(cacheDir)) {
+ throw new IllegalArgumentException("please specify cacheDir when incremental analyse.");
+ }
+ if (StringUtils.isBlank(commitId) || "null".equals(commitId)) {
+ throw new IllegalArgumentException("please specify commitId when incremental analyse.");
+ }
+ File cacheDirFile = new File(cacheDir);
+ if (!cacheDirFile.exists()) {
+ cacheDirFile.mkdirs();
+ }
+ CorefCache remoteCorefCache = null;
+ if (RemoteCacheType.oss.name().equals(remoteCacheTypeName)) {
+ remoteCorefCache = new OssCorefCache(ossPathPrefix, cacheDirFile, ossBucket, ossConfigFile);
+ }
+ CorefCache corefCache = new LocalCorefCache(cacheDirFile, remoteCorefCache);
+ runner.incrementalAnalyse(dbDir.toString(), "coref_java_src.db", corefCache, commitId);
+ } else if (parallelRequested) {
+ String uuid = UUID.randomUUID().toString();
+ Path pathPrefix = Paths.get(dbDir.getAbsolutePath(), uuid).toAbsolutePath();
+ FileUtil.createDirectory(pathPrefix.toFile());
+ runner.parallelAnalyse(pathPrefix.toString(), workerCount, dbDir.toString(), "coref_java_src.db");
+ } else {
+ runner.sequenceAnalyse(dbDir.toString(), "coref_java_src.db");
+ }
+ }
+ } catch (Exception e) {
+ log.error("extracting get error!", e);
+ return 1;
+ }
+
+
+ log.info("Time to completion (TTC): {}", (System.currentTimeMillis() - start)/1000 + "s");
+ return 0;
+ }
+
+ public static void main(String... args) {
+ int exitCode = new CommandLine(new Extractor()).execute(args);
+ System.exit(exitCode);
+ }
+
+ // Get the white list from the #2 command parameter
+ private static List getWhiteList(@NotNull File whiteList) {
+ List whiteListFiles = new ArrayList<>();
+
+ try {
+ // Read the input file.
+ FileInputStream inputStream = new FileInputStream(whiteList);
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
+
+ String relativePath = null;
+
+ // Read the file line by line and insert it into the list.
+ while ((relativePath = bufferedReader.readLine()) != null) {
+ whiteListFiles.add(relativePath);
+ }
+ // Close inputStream and bufferedReader.
+ inputStream.close();
+ bufferedReader.close();
+
+ } catch (IOException e) {
+ System.err.println(e);
+ }
+ // Return the white list.
+ return whiteListFiles;
+ }
+
+
+ private List parseClassPath(String classPath) {
+ List classPathList = new ArrayList<>();
+ if (classPath == null || classPath.isEmpty()) {
+ return classPathList;
+ }
+ String[] classPathArr = classPath.split(":");
+ for (String singleClassPath: classPathArr) {
+ if (singleClassPath.isEmpty()) {
+ continue;
+ }
+ if (!(new File(singleClassPath)).exists()) {
+ continue;
+ }
+ classPathList.add(singleClassPath);
+ }
+ return classPathList;
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/core/CorefDepExtractor.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/core/CorefDepExtractor.java
new file mode 100644
index 00000000..b650b996
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/core/CorefDepExtractor.java
@@ -0,0 +1,207 @@
+package com.alipay.codequery.coref.core;
+
+import com.alipay.codequery.coref.model.*;
+import com.alipay.codequery.coref.storage.IStorage;
+import com.alipay.codequery.coref.util.HashUtil;
+import com.alipay.codequery.coref.model.*;
+import com.alipay.codequery.util.PsiUtil;
+import com.alipay.codequery.coref.model.*;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.kotlin.com.intellij.psi.*;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class CorefDepExtractor {
+ private static final ConcurrentHashMap NP_PROJECT_ID_MAP = new ConcurrentHashMap<>();
+ // ATTENTION: PSI resolve dependencies in different thread independently
+ // so multi psi objects may represent same element
+ // we should create two cache for each category psi object
+ // the first cache save psi object and its hash id
+ // the second cache save hash id present or not
+ private static final ConcurrentHashMap PSI_FILE_NP_FILE_ID_MAP = new ConcurrentHashMap<>();
+ private static final ConcurrentHashMap NP_FILE_ID_MAP = new ConcurrentHashMap<>();
+ private static final ConcurrentHashMap PSI_CLASS_NP_CLASS_ID_MAP = new ConcurrentHashMap<>();
+ private static final ConcurrentHashMap NP_CLASS_ID_MAP = new ConcurrentHashMap<>();
+ private static final ConcurrentHashMap PSI_METHOD_NP_METHOD_ID_MAP = new ConcurrentHashMap<>();
+ private static final ConcurrentHashMap NP_METHOD_ID_MAP = new ConcurrentHashMap<>();
+ private static final ConcurrentHashMap PARENT_MAP = new ConcurrentHashMap<>();
+
+ /*
+ string: com/google/code/gson/gson/2.10/gson-2.10.jar!/com/google/gson/Gson.class
+ matching result: gson-2.10.jar
+ the regular expression match string with pattern:
+ 1. start with a '/' char, not included, just match position (零宽正回顾后发断言)
+ 2. followed by char sequence, contains at least one char, the char can't be '/'
+ 3. end with a '!' char, not included, just match position (零宽正向先行断言)
+ */
+ private static final Pattern DEP_NAME_PATTERN = Pattern.compile("(?<=/)[^/]+?(?=!)");
+
+ public static Long extractNpProject(IStorage storage, String project) {
+ return NP_PROJECT_ID_MAP.computeIfAbsent(project, (k) -> {
+ String corefURI = CorefURI.generate("depedency", "java", project);
+ Long hashId = HashUtil.hashString(corefURI);
+ NpProject npProject = new NpProject(hashId);
+ npProject.name = project;
+ int dotPos = project.lastIndexOf('.');
+ if (dotPos != -1 && (dotPos + 1) < project.length()) {
+ npProject.extension = project.substring(dotPos + 1);
+ } else {
+ npProject.extension = "default";
+ }
+ storage.storeNpProject(npProject);
+ return hashId;
+ });
+ }
+
+ public static Long extractNpFile(IStorage storage, PsiFile file) {
+ return PSI_FILE_NP_FILE_ID_MAP.computeIfAbsent(file, (k) -> {
+ Long hashId = getHashId(file);
+ AtomicBoolean contains = new AtomicBoolean(true);
+ NP_FILE_ID_MAP.computeIfAbsent(hashId, (id) -> {
+ contains.set(false);
+ return Boolean.TRUE;
+ });
+ if (!contains.get()) {
+ NpFile npFile = new NpFile(hashId);
+ npFile.name = file.getName();
+ String[] depNameAndFilePath = getDepNameAndFilePath(file);
+ if (depNameAndFilePath != null) {
+ npFile.qualifiedName = depNameAndFilePath[1];
+ int slashPos = npFile.qualifiedName.lastIndexOf('/');
+ if (slashPos != -1 && (slashPos + 1) < npFile.qualifiedName.length()) {
+ npFile.name = npFile.qualifiedName.substring(slashPos + 1);
+ } else {
+ npFile.name = npFile.qualifiedName;
+ }
+
+ npFile.projectId = extractNpProject(storage, depNameAndFilePath[0]);
+ } else {
+ npFile.qualifiedName = "default";
+ npFile.name = "default";
+ npFile.projectId = (long) -1;
+ }
+ storage.storeNpFile(npFile);
+ }
+ return hashId;
+ });
+ }
+
+ public static Long extractNpClass(IStorage storage, PsiClass clazz) {
+ return PSI_CLASS_NP_CLASS_ID_MAP.computeIfAbsent(clazz, (k) -> {
+ Long hashId = getHashId(clazz);
+ AtomicBoolean contains = new AtomicBoolean(true);
+ NP_CLASS_ID_MAP.computeIfAbsent(hashId, (id) -> {
+ contains.set(false);
+ return Boolean.TRUE;
+ });
+ if (!contains.get()) {
+ extractNpElement(storage, clazz.getParent());
+ if (clazz.isInterface()) {
+ NpInterface npInterface = new NpInterface(hashId);
+ npInterface.name = clazz.getName();
+ npInterface.qualifiedName = clazz.getQualifiedName();
+ npInterface.parent = getParent(clazz);
+ storage.storeNpInterface(npInterface);
+ } else {
+ NpClass npClass = new NpClass(hashId);
+ npClass.name = clazz.getName();
+ npClass.qualifiedName = clazz.getQualifiedName();
+ npClass.parent = getParent(clazz);
+ storage.storeNpClass(npClass);
+ }
+ }
+ return hashId;
+ });
+ }
+
+ public static Long extractNpMethod(IStorage storage, PsiMethod method) {
+ return PSI_METHOD_NP_METHOD_ID_MAP.computeIfAbsent(method, (k) -> {
+ Long hashId = getHashId(k);
+ AtomicBoolean contains = new AtomicBoolean(true);
+ NP_METHOD_ID_MAP.computeIfAbsent(hashId, (id) -> {
+ contains.set(false);
+ return Boolean.TRUE;
+ });
+ // hash id does not exist
+ if (!contains.get()) {
+ extractNpElement(storage, method.getParent());
+ NpMethod npMethod = new NpMethod(hashId);
+ npMethod.name = method.getName();
+ npMethod.signature = PsiUtil.mangleMethodName(method);
+ npMethod.returnType = SharedManager.getType(storage, method.getReturnType());
+ npMethod.parent = getParent(method);
+ storage.storeNpMethod(npMethod);
+ }
+ return hashId;
+ });
+ }
+
+ public static Long extractNpElement(IStorage storage, PsiElement element) {
+ if (element instanceof PsiFile) {
+ return extractNpFile(storage, (PsiFile) element);
+ } else if (element instanceof PsiClass) {
+ return extractNpClass(storage, (PsiClass) element);
+ } else if (element instanceof PsiMethod) {
+ return extractNpMethod(storage, (PsiMethod) element);
+ }
+ assert false: "Element's type: " + element.getClass().toString();
+ return Long.valueOf(-1);
+ }
+
+ /**
+ * Get dependency name and psi file path.
+ * psi virtual file path: "com/google/code/gson/gson/2.10/gson-2.10.jar!/com/google/gson/Gson.class"
+ * return value: ["gson-2.10.jar", "/com/google/gson/Gson.class"]
+ * @param psiFile
+ * @return null or an array with 2 elements [dependency name, psi file path]
+ */
+ private static String[] getDepNameAndFilePath(@NotNull PsiFile psiFile) {
+ assert psiFile != null;
+ String[] depNameAndFilePath = null;
+ if (psiFile != null && psiFile.getVirtualFile() != null) {
+ String virtualPath = psiFile.getVirtualFile().getPath();
+ Matcher matcher = DEP_NAME_PATTERN.matcher(virtualPath);
+ if (matcher.find() && (matcher.end(0) + 1) < virtualPath.length()) {
+ depNameAndFilePath = new String[2];
+ depNameAndFilePath[0] = matcher.group();
+ depNameAndFilePath[1] = virtualPath.substring(matcher.end(0) + 1);
+ }
+ }
+ return depNameAndFilePath;
+ }
+
+ private static Long getHashId(PsiElement element) {
+ if (element == null) {
+ return Long.valueOf(-1);
+ }
+ String signature = SignatureGenerator.generate(element);
+ String repo = "default";
+ String path = "default";
+ PsiFile psiFile = element.getContainingFile();
+ String[] depNameAndFilePath = getDepNameAndFilePath(psiFile);
+ if (depNameAndFilePath != null) {
+ repo = depNameAndFilePath[0];
+ path = depNameAndFilePath[1];
+ }
+ String corefURIString = CorefURI.generate(repo, path, signature);
+ return HashUtil.hashString(corefURIString);
+ }
+
+ private static Parent getParent(PsiElement element) {
+ return PARENT_MAP.computeIfAbsent(element, (k) -> {
+ PsiElement psiParent = PsiUtil.getPsiParent(element);
+ Parent parent = new Parent(getHashId(psiParent));
+ if (psiParent != null) {
+ String temp = psiParent.toString();
+ temp = temp.startsWith("Psi") ? temp.substring(3) : temp;
+ parent.parentType = temp.contains(":") ? temp.substring(0, temp.indexOf(":")) : temp;
+ } else {
+ parent.parentType = "";
+ }
+ return parent;
+ });
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/core/CorefExtractor.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/core/CorefExtractor.java
new file mode 100644
index 00000000..1b8ecc75
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/core/CorefExtractor.java
@@ -0,0 +1,1610 @@
+package com.alipay.codequery.coref.core;
+
+import com.alipay.codequery.coref.model.*;
+import com.alipay.codequery.coref.model.Class;
+import com.alipay.codequery.coref.model.Comment;
+import com.alipay.codequery.coref.model.Expression;
+import com.alipay.codequery.coref.model.Identifier;
+import com.alipay.codequery.coref.model.Location;
+import com.alipay.codequery.coref.model.Method;
+import com.alipay.codequery.coref.model.Modifier;
+import com.alipay.codequery.coref.model.Package;
+import com.alipay.codequery.coref.model.Parameter;
+import com.alipay.codequery.coref.model.Statement;
+import com.alipay.codequery.coref.storage.IStorage;
+import com.alipay.codequery.coref.util.HashUtil;
+import com.alipay.codequery.dal.mybatis.domain.*;
+import com.alipay.codequery.project.PsiProject;
+import com.alipay.codequery.util.PathUtil;
+import com.alipay.codequery.util.PsiUtil;
+import com.alipay.codequery.coref.model.Annotation;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.kotlin.com.intellij.openapi.editor.Document;
+import org.jetbrains.kotlin.com.intellij.openapi.util.TextRange;
+import org.jetbrains.kotlin.com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.kotlin.com.intellij.psi.*;
+import org.jetbrains.kotlin.com.intellij.psi.impl.source.PsiClassReferenceType;
+import org.jetbrains.kotlin.com.intellij.psi.javadoc.*;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class CorefExtractor extends JavaRecursiveElementVisitor {
+ private static final Logger logger = LogManager.getLogger(CorefExtractor.class);
+
+ // TODO hold PSI File may cause high memory usage
+ private final PsiFile file;
+ private final Document document;
+ private final String repoDir;
+ private final PsiProject project;
+ private final com.alipay.codequery.coref.model.Program program;
+ private final IStorage corefStorage;
+ public String fileMD5cached;
+ public String fileSHA256cached;
+ final Map locationMap = new HashMap<>();
+ final Map parentMap = new HashMap<>();
+ final HashMap lineTag = new HashMap<>();
+ private CorefURI corefURI;
+
+ public CorefExtractor(PsiProject project, String repoDir, PsiFile file, IStorage corefStorage, com.alipay.codequery.coref.model.Program program, CorefURI corefURI) {
+ this.project = project;
+ this.repoDir = repoDir;
+ this.file = file;
+ this.document = project.documentOf(file);
+ this.corefStorage = corefStorage;
+ this.program = program;
+ fileSHA256cached = HashUtil.getFileSHA1(file.getVirtualFile().getCanonicalPath());
+ fileMD5cached = HashUtil.getFileMD5(file.getVirtualFile().getCanonicalPath());
+ classifyJavaLines(file);
+ this.corefURI = corefURI;
+ String relativePath = PathUtil.getRelPath(repoDir, file.getVirtualFile().getPath());
+ this.corefURI.setPath(relativePath);
+ }
+
+ public void classifyJavaLines(PsiFile file) {
+ BufferedReader reader = null;
+ FileReader fileReader = null;
+ try {
+ fileReader = new FileReader(file.getVirtualFile().getCanonicalPath());
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ reader = new BufferedReader(fileReader);
+ String line = null;
+ int count = 1;
+ try {
+ while ((line = reader.readLine()) != null) {
+ line = line.trim();
+ if (line.isEmpty()) {
+ lineTag.put(count, "Empty");
+ } else if (line.startsWith("//") || (line.startsWith("/*")) || (line.startsWith("*")) || (line.endsWith("*/"))) {
+ lineTag.put(count, "Comment");
+ }
+ count++;
+ }
+ if (file.getText().endsWith("")) {
+ lineTag.put(count, "Empty");
+ }
+ reader.close();
+ fileReader.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void getValidJavaLines(Location.LocalLocation location, long id) {
+ int startLineNumber = location.startLineNumber;
+ int endLineNumber = location.endLineNumber;
+ int numberOfEmptyLines = 0;
+ int numberOfCommentLines = 0;
+ int totalLines = endLineNumber - startLineNumber + 1;
+ for (int i = startLineNumber; i <= endLineNumber; i++) {
+ if (lineTag.containsKey(i)) {
+ if (lineTag.get(i).equals("Empty")) {
+ numberOfEmptyLines++;
+ } else if (lineTag.get(i).equals("Comment")) {
+ numberOfCommentLines++;
+ }
+ }
+ }
+ Location.NumberOfLines numberOfLines = new Location.NumberOfLines(id);
+ numberOfLines.numberOfLines = totalLines;
+ numberOfLines.numberOfCodeLines = totalLines - numberOfEmptyLines - numberOfCommentLines;
+ numberOfLines.numberOfCommentLines = numberOfCommentLines;
+ corefStorage.storeNumberOfLines(numberOfLines);
+ }
+
+ public Long getHashId(PsiElement element) {
+ if( element != null) {
+ String signature = SignatureGenerator.generate(element);
+ String path = corefURI.getPath();
+
+ //when a resolved element is from another file, needs to use its real file path.
+ if(element.getContainingFile() != null && element.getContainingFile().getVirtualFile() != null) {
+ if(!(element.getContainingFile().equals(file))){
+ path = PathUtil.getRelPath(repoDir, element.getContainingFile().getVirtualFile().getPath());
+ }
+ }
+
+ String corefURIString = CorefURI.generate(corefURI.getRepository(), path, signature);
+ return HashUtil.hashString(corefURIString);
+ } else {
+ return Long.valueOf(-1);
+ }
+ }
+
+ //subclass of reference expression.
+ @Override
+ public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) {
+ super.visitMethodReferenceExpression(expression);
+ com.alipay.codequery.coref.model.Expression.MethodCallExpression methodReferenceExpression = new com.alipay.codequery.coref.model.Expression.MethodCallExpression(getHashId(expression));
+
+ PsiElement resolvedMethod = expression.getPotentiallyApplicableMember();
+ Long calleeId = null;
+ if(isPhysicalValidElement(resolvedMethod)) {
+ calleeId = getHashId(resolvedMethod);
+ }
+ // else if (resolvedMethod != null) {
+ // calleeId = CorefDepExtractor.extractNpElement(corefStorage, resolvedMethod);
+ // }
+ if (calleeId != null) {
+ CallableBinding callableBinding = new CallableBinding(methodReferenceExpression.hashId, calleeId);
+ corefStorage.storeCallableBinding(callableBinding);
+ }
+
+ methodReferenceExpression.isConstructor = expression.isConstructor() ? 1 : 0;
+ corefStorage.storeMethodReferenceExpression(methodReferenceExpression);
+ }
+
+ public Location.LocalLocation calculateLocalLocation(Document document, PsiElement element) {
+ TextRange textRange = element.getTextRange();
+ int startOffset = textRange.getStartOffset();
+ int startLineNumber = document.getLineNumber(startOffset);
+ int startColumnNumber = startOffset - document.getLineStartOffset(startLineNumber);
+ if (element instanceof PsiClass && ((PsiClass) element).getNameIdentifier() != null) {
+ TextRange textRange1 = ((PsiClass) element).getNameIdentifier().getTextRange();
+ startOffset = textRange1.getStartOffset();
+ startLineNumber = document.getLineNumber(startOffset);
+ }
+ int endOffset = textRange.getEndOffset();
+ int endLineNumber = document.getLineNumber(endOffset);
+ int endColumnNumber = endOffset - document.getLineStartOffset(endLineNumber);
+ return new Location.LocalLocation(startLineNumber + 1, startColumnNumber + 1, endLineNumber + 1, endColumnNumber + 1);
+ }
+
+ public Location calculateLocation(Document document, PsiElement element) {
+ if (element instanceof PsiFile) {
+ return null;
+ } else {
+ // If the Location has been calculated before, return it directly.
+ if (locationMap.containsKey(element.getTextRange())) {
+ return new Location(locationMap.get(element.getTextRange()));
+ } else {
+ PsiFile containingFile = element.getContainingFile();
+ com.alipay.codequery.coref.model.File file1 = new com.alipay.codequery.coref.model.File(getHashId(containingFile));
+
+ // Generate the element's location hash id if not exists.
+ Long hashId = getLocationHashId(element);
+ locationMap.put(element.getTextRange(), hashId);
+
+ // If the element is resolved, the document should be generated again.
+ if (!(element.getContainingFile().equals(file))) {
+ document = project.documentOf(containingFile);
+ }
+ Location.LocalLocation localLocation = calculateLocalLocation(document, element);
+ getValidJavaLines(localLocation, hashId);
+ Location location = new Location(hashId, file1, localLocation);
+ corefStorage.storeLocation(location);
+ return location;
+ }
+ }
+ }
+
+ // Generate location hash id.
+ public Long getLocationHashId(PsiElement element) {
+ return CorefURI.generateHashId(corefURI.getRepository(), corefURI.getPath(), SignatureGenerator.generate(element));
+ }
+
+ @Override
+ public void visitInstanceOfExpression(PsiInstanceOfExpression expression) {
+ super.visitInstanceOfExpression(expression);
+ com.alipay.codequery.coref.model.Expression.InstanceOfExpression instanceOfExpression = new com.alipay.codequery.coref.model.Expression.InstanceOfExpression(getHashId(expression));
+ //type element
+ instanceOfExpression.checkType = expression.getCheckType() != null ?
+ new com.alipay.codequery.coref.model.Expression(getHashId(expression.getCheckType())) : new com.alipay.codequery.coref.model.Expression((long) -1);
+ //expression
+ instanceOfExpression.operand = new com.alipay.codequery.coref.model.Expression(getHashId(expression.getOperand()));
+ //typetestpattern, parent of checktype
+ instanceOfExpression.pattern = expression.getPattern() != null ?
+ new com.alipay.codequery.coref.model.Expression(getHashId(expression.getPattern())) : new com.alipay.codequery.coref.model.Expression((long) -1);
+ instanceOfExpression.location = calculateLocation(document, expression);
+ corefStorage.storeInstanceOfExpression(instanceOfExpression);
+ }
+
+ @Override
+ public void visitAnnotationArrayInitializer(PsiArrayInitializerMemberValue initializer) {
+ super.visitAnnotationArrayInitializer(initializer);
+ com.alipay.codequery.coref.model.Expression.ArrayInitializationExpression aExpression = new com.alipay.codequery.coref.model.Expression.ArrayInitializationExpression(getHashId(initializer));
+ aExpression.debug_message = initializer.getText();
+ aExpression.parent = getParent(initializer); //PsiArrayInitializerMemberValue element.
+ aExpression.location = calculateLocation(document, initializer);
+ corefStorage.storeAnnotationArrayInitializer(aExpression);
+ }
+
+ //PsiImportStaticStatement extends PsiImportStatementBase extends PsiElement
+ @Override
+ public void visitImportStaticStatement(PsiImportStaticStatement statement) {
+ super.visitImportStaticStatement(statement);
+ com.alipay.codequery.coref.model.Statement.ImportStatement importStatement = new com.alipay.codequery.coref.model.Statement.ImportStatement(getHashId(statement));
+ importStatement.reference = new com.alipay.codequery.coref.model.Statement(getHashId(statement.getImportReference()));
+ importStatement.debug_message = statement.getText();
+ importStatement.parent = getParent(statement);
+ importStatement.location = calculateLocation(document, statement);
+ corefStorage.storeImportStaticStatement(importStatement);
+ }
+
+ @Override
+ public void visitImportStaticReferenceElement(PsiImportStaticReferenceElement reference) {
+ super.visitImportStaticReferenceElement(reference);
+ com.alipay.codequery.coref.model.Expression importReference = new com.alipay.codequery.coref.model.Expression(getHashId(reference));
+ importReference.debug_message = reference.getQualifiedName();
+ importReference.parent = getParent(reference);
+ importReference.location = calculateLocation(document, reference);
+ corefStorage.storeImportStaticReferenceElement(importReference);
+ if (isPhysicalValidElement(reference.resolve())) {
+ PsiElement definition = reference.resolve();
+ ReferenceRelation referenceRelation = new ReferenceRelation(getHashId(reference), getHashId(definition));
+ corefStorage.storeReferenceRelation(referenceRelation);
+ }
+ }
+
+ @Override
+ public void visitAnnotation(PsiAnnotation annotation) {
+ super.visitAnnotation(annotation);
+ Annotation.AnnotationModel annotations = new Annotation.AnnotationModel(getHashId(annotation));
+ annotations.name = new com.alipay.codequery.coref.model.Identifier(annotation.getNameReferenceElement().getText(), getHashId(annotation.getNameReferenceElement()));
+ annotations.qualifiedName = annotation.getQualifiedName() != null ? annotation.getQualifiedName() : "-1";
+ annotations.location = calculateLocation(document, annotation);
+ annotations.parent = getParent(annotation);
+ annotations.debug_message = annotation.getText();
+
+ if (isPhysicalValidElement(annotation.resolveAnnotationType())) {
+ annotations.resolveAnnotationType = new Node(getHashId(annotation.resolveAnnotationType()));
+ corefStorage.storeAnnotationCanResolved(annotations);
+ } else {
+ corefStorage.storeAnnotationCanNotResolved(annotations);
+ }
+
+ if (annotation.getParent() instanceof PsiModifierList) {
+ AnnotatedRelation annoRelation = new AnnotatedRelation();
+ annoRelation.setAnnotationHashId(annotations.hashId);
+ annoRelation.setAnnotatedItemHashId(getHashId(annotation.getParent().getParent()));
+ corefStorage.storeAnnotatedRelation(annoRelation);
+ }
+
+ }
+
+ @Deprecated
+ private void processAnnotationType(PsiClass annotationType) {
+ boolean shouldVisit = false;
+ synchronized (SharedManager.RESOLVED_ANNOTATION_SET) {
+ @Nullable String name = annotationType.getQualifiedName();
+ if (SharedManager.RESOLVED_ANNOTATION_SET.contains(name)) {
+ shouldVisit = false;
+ } else {
+ SharedManager.RESOLVED_ANNOTATION_SET.add(name);
+ shouldVisit = true;
+ }
+ }
+ if (shouldVisit) {
+ visitAnnotationDeclaration(annotationType);
+ }
+ }
+
+ @Override
+ public void visitAnnotationMethod(PsiAnnotationMethod method) {
+ super.visitAnnotationMethod(method);
+ Annotation.AnnotationParameter parameter = new Annotation.AnnotationParameter(getHashId(method));
+ parameter.debug_message = method.getText();
+ parameter.location = calculateLocation(document, method);
+ parameter.type = getType(method.getReturnType());
+ parameter.parent = getParent(method);
+ parameter.name = new com.alipay.codequery.coref.model.Identifier(method.getName(), getHashId(method.getNameIdentifier()));
+ corefStorage.storeAnnotationDeclarationParameter(parameter);
+
+ if (method.getDefaultValue() != null) {
+ AnnotationDeclarationParameterDefaultValue parameterDefaultValue = new AnnotationDeclarationParameterDefaultValue();
+ parameterDefaultValue.setDefaultValue(method.getDefaultValue().getText());
+ parameterDefaultValue.setElementHashId(parameter.hashId);
+ corefStorage.storeAnnotationDeclarationParameterDefaultValue(parameterDefaultValue);
+ }
+ }
+
+ public void generateFileCache(com.alipay.codequery.coref.model.File file) {
+ FileMd5Sum fileMd5 = new FileMd5Sum();
+ fileMd5.setFileHashId(file.hashId);
+ fileMd5.setValue(fileMD5cached);
+ corefStorage.storeFileMd5Sum(fileMd5);
+
+ FileSha256Sum fileSha256Sum = new FileSha256Sum();
+ fileSha256Sum.setFileHashId(file.hashId);
+ fileSha256Sum.setValue(fileSHA256cached);
+ corefStorage.storeFileSHA256Sum(fileSha256Sum);
+ }
+
+ @Override
+ public void visitReferenceParameterList(PsiReferenceParameterList list) {
+ super.visitReferenceParameterList(list);
+ if (!(list.getText().isEmpty())) {
+ ParameterList.ReferenceParameterList referenceParameterList = new ParameterList.ReferenceParameterList(getHashId(list));
+ referenceParameterList.parent = getParent(list);
+ referenceParameterList.location = calculateLocation(document, list);
+ referenceParameterList.debug_message = list.getText();
+
+ if(referenceParameterList.debug_message.equals("<>")){
+ // The list is "<>".
+ corefStorage.storeEmptyReferenceParameterlist(referenceParameterList);
+ } else {
+ referenceParameterList.types = new Type[list.getTypeParameterElements().length];
+ for (int i = 0; i < list.getTypeParameterElements().length; i++) {
+ referenceParameterList.types[i] = new Type(getHashId(list.getTypeParameterElements()[i]));
+ corefStorage.storeReferenceParameterlist(referenceParameterList, i);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void visitFile(@NotNull PsiFile file) {
+ super.visitFile(file);
+ String absolutePath = file.getVirtualFile().getCanonicalPath();
+ com.alipay.codequery.coref.model.File files = new com.alipay.codequery.coref.model.File(getHashId(file));
+ generateFileCache(files);
+ char head = repoDir.charAt(0);
+ String relativePath;
+ switch (head) {
+ case '/':
+ relativePath = absolutePath.substring(repoDir.length() + 1);
+ break;
+ case '.':
+ relativePath = absolutePath.substring(absolutePath.indexOf(repoDir) + 2);
+ break;
+ default:
+ relativePath = absolutePath.substring(absolutePath.indexOf(repoDir));
+ }
+ files.qualifiedName = relativePath;
+ files.name = file.getName();
+ files.extension = file.getLanguage().getDisplayName();
+ files.program = program;
+ files.numberOfLines = new Location.NumberOfLines(getLocationHashId(file));
+ getValidJavaLines(calculateLocalLocation(document, file), files.numberOfLines.hashId);
+ if (SharedManager.FILE_MAP.containsKey(absolutePath)) {
+ ContainerParent containerParent = new ContainerParent(files.hashId, SharedManager.FILE_MAP.get(absolutePath));
+ corefStorage.storeContainerParent(containerParent);
+ }
+ corefStorage.storeFile(files);
+ }
+
+ //PsiPackageStatement extends PsiElement, not a statement, actually.
+ @Override
+ public void visitPackageStatement(PsiPackageStatement statement) {
+ super.visitPackageStatement(statement);
+ com.alipay.codequery.coref.model.Statement.PackageStatement packages = new com.alipay.codequery.coref.model.Statement.PackageStatement(getHashId(statement));
+ packages.debug_message = statement.getPackageName();
+ packages.location = calculateLocation(document, statement);
+ packages.parent = getParent(statement);
+
+ @Nullable PsiElement resolved;
+ resolved = statement.getPackageReference().resolve();
+
+ if (resolved != null) {
+ packages.referencePackage = new Package(getHashId(resolved));
+ } else {
+ packages.referencePackage = new Package((long) -1);
+ }
+ Cupackage cupackage = new Cupackage();
+ cupackage.setFileHashId(getHashId(file));
+ cupackage.setPackageHashId(packages.referencePackage.hashId);
+ corefStorage.storeCuPackage(cupackage);
+ corefStorage.storePackageStatement(packages);
+ }
+
+ public String mangleFieldName(PsiField field) {
+ PsiClass parent = field.getContainingClass();
+ PsiIdentifier ident = field.getNameIdentifier();
+ PsiType type = field.getType();
+ String typedString = null;
+ if (type instanceof PsiPrimitiveType) {
+ typedString = type.getPresentableText();
+ }
+ if (type instanceof PsiClassReferenceType) {
+ PsiClassReferenceType psiClassReferenceType = (PsiClassReferenceType) type;
+ typedString = psiClassReferenceType.getPresentableText();
+ }
+ if (parent.getQualifiedName() != null) {
+ return parent.getQualifiedName() + "." + ident.getText() + ":" + typedString;
+ }
+ if (parent.getNameIdentifier() != null) {
+ return parent.getNameIdentifier().getText() + "." + ident.getText() + ":" + typedString;
+ }
+ return ident.getText() + ":" + typedString;
+ }
+
+ private Type getType(PsiType type) {
+ return SharedManager.getType(corefStorage, type);
+ }
+
+ @Deprecated
+ public void generateCallableEnclosingElement(PsiElement element, Node node) {
+ Long elementId;
+ if (!(element instanceof PsiJavaToken) && !(element instanceof PsiWhiteSpace)) {
+ for (PsiElement e : element.getChildren()) {
+ if (!(e instanceof PsiMethod)) {
+ elementId = getHashId(e);
+ if (e instanceof PsiExpression) {
+ CallableEnclosingExpression callableEnclosingExpression = new CallableEnclosingExpression(elementId, node.hashId);
+ corefStorage.storeCallableEnclosingExpression(callableEnclosingExpression);
+ } else if (e instanceof PsiStatement) {
+ com.alipay.codequery.coref.model.Statement s = new com.alipay.codequery.coref.model.Statement(getHashId(e));
+ CallableEnclosingStatement callableEnclosingStatement = new CallableEnclosingStatement(elementId, node.hashId);
+ corefStorage.storeCallableEnclosingStatement(callableEnclosingStatement);
+ generateStatementEnclosingExpression(e, s);
+ }
+ generateCallableEnclosingElement(e, node);
+ }
+ }
+ }
+ }
+
+ @Deprecated
+ public void generateStatementEnclosingExpressionLegacy(PsiElement element, Node node) {
+ if (element instanceof PsiJavaToken || element instanceof PsiWhiteSpace) {
+ return;
+ } else {
+ for (PsiElement e : element.getChildren()) {
+ if (e instanceof PsiStatement) {
+ continue;
+ }
+ if (e instanceof PsiExpression) {
+ StatementEnclosingExpression statementEnclosingExpression = new StatementEnclosingExpression(node.hashId, getHashId(element));
+ corefStorage.storeStatementEnclosingExpression(statementEnclosingExpression);
+ }
+ generateStatementEnclosingExpressionLegacy(e, node);
+ }
+ }
+ }
+ // Iterates to find any expression in a statement element.
+ public void generateStatementEnclosingExpression(PsiElement element, Node node) {
+ ArrayList pending = new ArrayList<>();
+ List children = new ArrayList<>();
+
+ // ready to expand the element (from current)
+ pending.add(element);
+
+ // loop to expand
+ while (!pending.isEmpty()) {
+ // get and remove
+ PsiElement item = pending.get(0);
+ pending.remove(0);
+
+ // ignore them
+ if (item instanceof PsiJavaToken || item instanceof PsiWhiteSpace) {
+ continue;
+ } else {
+ for (PsiElement child : item.getChildren()) {
+ if (child instanceof PsiStatement) {
+ continue;
+ }
+ if (child instanceof PsiExpression) {
+ children.add(child);
+ }
+ // continue to expand the element
+ pending.add(child);
+ }
+ }
+ }
+
+ for (PsiElement child : children) {
+ StatementEnclosingExpression statementEnclosingExpression = new StatementEnclosingExpression(getHashId(child), node.hashId);
+ corefStorage.storeStatementEnclosingExpression(statementEnclosingExpression);
+ }
+ }
+
+ // Iterates to find any statements or expressions in a callable element.
+ public void generateCallableEnclosingNode(PsiElement element, Node node) {
+ ArrayList pending = new ArrayList<>();
+ List statementChildren = new ArrayList<>();
+ List expressionChildren = new ArrayList<>();
+
+ // ready to expand the element (from current)
+ pending.add(element);
+
+ // loop to expand
+ while (!pending.isEmpty()) {
+ // get and remove
+ PsiElement item = pending.get(0);
+ pending.remove(0);
+
+ // ignore them
+ if (item instanceof PsiJavaToken || item instanceof PsiWhiteSpace) {
+ continue;
+ } else {
+ for (PsiElement child : item.getChildren()) {
+ if(child instanceof PsiMethod) {
+ continue;
+ }
+ if (child instanceof PsiStatement) {
+ statementChildren.add(child);
+ }
+ if (child instanceof PsiExpression) {
+ expressionChildren.add(child);
+ }
+ // continue to expand the element
+ pending.add(child);
+ }
+ }
+ }
+
+ for (PsiElement child : statementChildren) {
+ CallableEnclosingStatement callableEnclosingStatement = new CallableEnclosingStatement(getHashId(child), node.hashId);
+ corefStorage.storeCallableEnclosingStatement(callableEnclosingStatement);
+ }
+
+ for (PsiElement child : expressionChildren) {
+ CallableEnclosingExpression callableEnclosingExpression = new CallableEnclosingExpression(getHashId(child), node.hashId);
+ corefStorage.storeCallableEnclosingExpression(callableEnclosingExpression);
+ }
+ }
+
+ @Override
+ public void visitTypeElement(PsiTypeElement type) {
+ super.visitTypeElement(type);
+ if(!type.getText().isEmpty()){
+ Type typeElement = new Type(getHashId(type));
+ typeElement.debug_message = type.getText();
+ typeElement.type = getType(type.getType());
+ typeElement.parent = getParent(type);
+ typeElement.location = calculateLocation(document, type);
+ corefStorage.storeTypeElement(typeElement);
+ }
+ }
+
+ @Override
+ public void visitSuperExpression(PsiSuperExpression expression) {
+ super.visitSuperExpression(expression);
+ com.alipay.codequery.coref.model.Expression.SuperExpression superExpression = new com.alipay.codequery.coref.model.Expression.SuperExpression(getHashId(expression));
+
+ //qualifier always is null
+ if(expression.getQualifier() != null) {
+ superExpression.qualifier = new com.alipay.codequery.coref.model.Expression(getHashId(expression.getQualifier()));
+ corefStorage.storeSuperExpressionWithQualifier(superExpression);
+ }
+
+ corefStorage.storeSuperExpression(superExpression);
+ }
+
+ @Override
+ // PsiTypeParameter extends PsiClass
+ public void visitTypeParameter(PsiTypeParameter classParameter) {
+ super.visitTypeParameter(classParameter);
+ Type.TypeParameter parameter = new Type.TypeParameter(getHashId(classParameter));
+ parameter.index = classParameter.getIndex();
+ parameter.owner = classParameter.getOwner() != null ?
+ new Node(getHashId(classParameter.getOwner())) : new Node((long) -1);
+ parameter.parent = getParent(classParameter);
+ parameter.location = calculateLocation(document, classParameter);
+ parameter.debug_message = classParameter.getText();
+ //extendsList is a reference list.
+ parameter.extendsList = new Node(getHashId(classParameter.getExtendsList()));
+ corefStorage.storeTypeParameter(parameter);
+ }
+
+ // store implements relation.
+ private void generateImplementsRelation(Long oid, PsiClass psiClass) {
+ for (PsiType t : psiClass.getImplementsListTypes()) {
+ ClassImplementList list = new ClassImplementList(oid, getType(t).hashId);
+ corefStorage.storeImplementlist(list);
+ }
+ }
+
+ // store extends relation (class hierarchy).
+ private void generateExtendsRelation(Long oid, PsiClass psiClass) {
+ for (PsiClass c : psiClass.getSupers()) {
+ // TODO: when JAVA_HOME is specified, PSI can resolve extends relation from java.lang package. But extractor couldn't resolve other relevant info from jar currently, so excludes this kind of relation from class hierarchy temporally.
+ if(c.getQualifiedName() != null ){
+ if (!(StringUtil.startsWith(c.getQualifiedName(), "java.lang."))) {
+ com.alipay.codequery.coref.model.Class.ClassHierarchy classHierarchy = new com.alipay.codequery.coref.model.Class.ClassHierarchy(oid, getHashId(c));
+ corefStorage.storeClassHierarchy(classHierarchy);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void visitClass(PsiClass aClass) {
+ super.visitClass(aClass);
+
+ // class extracting, firstly exclude anonymous class and type parameter elements.
+ if( !(aClass instanceof PsiTypeParameter) && !(aClass instanceof PsiAnonymousClass)) {
+ com.alipay.codequery.coref.model.Class.ClassDefinition class1 = new com.alipay.codequery.coref.model.Class.ClassDefinition(getHashId(aClass));
+ class1.parent = getParent(aClass);
+ class1.identifier = new com.alipay.codequery.coref.model.Identifier(aClass.getName(), getHashId(aClass.getNameIdentifier()));
+ class1.location = calculateLocation(document, aClass);
+ class1.qualifiedName = aClass.getQualifiedName() != null ? aClass.getQualifiedName() : aClass.getName();
+
+ if(aClass.getQualifiedName() == null) {
+ class1.debug_message = aClass.getText();
+ // store null qualified name local class in local class declaration table.
+ corefStorage.storeLocalClass(class1);
+
+ } else if(aClass.isInterface()){
+ // store interface into interface table.
+ corefStorage.storeInterface(class1);
+
+ // if the class is annotation class, also save it in the annotation declaration table.
+ if (aClass.isAnnotationType()) {
+ visitAnnotationDeclaration(aClass);
+ }
+
+ } else {
+ generateImplementsRelation(class1.hashId, aClass);
+
+ // store normal class.
+ corefStorage.storeClass(class1);
+ }
+ generateExtendsRelation(class1.hashId, aClass);
+ }
+
+ }
+
+ @Override
+ public void visitAnnotationParameterList(PsiAnnotationParameterList list) {
+ super.visitAnnotationParameterList(list);
+ int index = 0;
+ for (PsiNameValuePair var : list.getAttributes()) {
+ Annotation.AnnotationArgument annoParam = new Annotation.AnnotationArgument(getHashId(var));
+ annoParam.value = var.getDetachedValue() != null ?
+ new com.alipay.codequery.coref.model.Expression(getHashId(var.getDetachedValue())) : new com.alipay.codequery.coref.model.Expression((long) -1);
+ annoParam.location = calculateLocation(document, var);
+ annoParam.parent = getParent(var); //ignore PsiAnnotationParameterList element.
+ annoParam.debug_message = var.getText();
+ annoParam.index = index;
+ index++;
+ //If the parameter has no name, the default name is "value".
+ if(var.getNameIdentifier() != null) {
+ annoParam.kind = new com.alipay.codequery.coref.model.Expression(getHashId(var.getNameIdentifier()));
+ corefStorage.storeAnnotationArgumentWithName(annoParam);
+ } else {
+ corefStorage.storeAnnotationArgumentWithoutName(annoParam);
+ }
+ }
+ }
+
+ public void visitAnnotationDeclaration(PsiClass aclass) {
+ Annotation.AnnotationModel annotationDeclaration = new Annotation.AnnotationModel(getHashId(aclass));
+ annotationDeclaration.qualifiedName = aclass.getQualifiedName();
+ corefStorage.storeAnnotationDeclaration(annotationDeclaration);
+ }
+
+ public void visitProgram() {
+ corefStorage.storeProgram(program);
+ }
+
+ @Override
+ public void visitWhileStatement(PsiWhileStatement statement) {
+ super.visitWhileStatement(statement);
+ com.alipay.codequery.coref.model.Statement.WhileStatement whileStatement = new com.alipay.codequery.coref.model.Statement.WhileStatement(getHashId(statement));
+ whileStatement.condition = statement.getCondition() != null ?
+ new com.alipay.codequery.coref.model.Expression(getHashId(statement.getCondition())) : new com.alipay.codequery.coref.model.Expression((long) -1);
+ whileStatement.body = statement.getBody() != null ?
+ new com.alipay.codequery.coref.model.Statement(getHashId(statement.getBody())) : new com.alipay.codequery.coref.model.Statement((long) -1);
+ corefStorage.storeWhileStatement(whileStatement);
+ }
+
+ @Override
+ public void visitDoWhileStatement(PsiDoWhileStatement statement) {
+ super.visitDoWhileStatement(statement);
+ com.alipay.codequery.coref.model.Statement.DoWhileStatement doWhileStatement = new com.alipay.codequery.coref.model.Statement.DoWhileStatement(getHashId(statement));
+ doWhileStatement.condition = statement.getCondition() != null ?
+ new com.alipay.codequery.coref.model.Expression(getHashId(statement.getCondition())) : new com.alipay.codequery.coref.model.Expression((long) -1);
+ doWhileStatement.keyword = statement.getWhileKeyword().getText();
+ doWhileStatement.body = statement.getBody() != null ?
+ new com.alipay.codequery.coref.model.Statement(getHashId(statement.getBody())) : new com.alipay.codequery.coref.model.Statement((long) -1);
+ corefStorage.storeDoWhileStatement(doWhileStatement);
+ }
+
+ @Override
+ public void visitBlockStatement(PsiBlockStatement statement) {
+ super.visitBlockStatement(statement);
+ com.alipay.codequery.coref.model.Statement.BlockStatement blockStatement = new com.alipay.codequery.coref.model.Statement.BlockStatement(getHashId(statement));
+ blockStatement.codeBlock = new com.alipay.codequery.coref.model.Statement.CodeBlock(getHashId(statement.getCodeBlock()));
+ corefStorage.storeBlockStatement(blockStatement);
+ }
+ //PsiCodeBlock extends PsiElement, not a statement.
+ @Override
+ public void visitCodeBlock(PsiCodeBlock block) {
+ super.visitCodeBlock(block);
+ com.alipay.codequery.coref.model.Statement.CodeBlock codeBlock = new com.alipay.codequery.coref.model.Statement.CodeBlock(getHashId(block));
+ codeBlock.count = block.getStatementCount();
+ codeBlock.isEmpty = block.isEmpty() ? 1 : 0;
+ codeBlock.parent = getParent(block);
+ codeBlock.location = calculateLocation(document, block);
+ codeBlock.debug_message = block.getText();
+ corefStorage.storeCodeBlock(codeBlock);
+ }
+ //PsiModifierList extends PsiAnnotationOwner
+ @Override
+ public void visitModifierList(PsiModifierList list) {
+ super.visitModifierList(list);
+ if (!(list.getText().isEmpty())) {
+ com.alipay.codequery.coref.model.Modifier modifierlist = new com.alipay.codequery.coref.model.Modifier(getHashId(list));
+ modifierlist.parent = getParent(list);
+ modifierlist.location = calculateLocation(document, list);
+ corefStorage.storeModifierList(modifierlist);
+ }
+ }
+ // TODO: filter the resolved element not in the source code, including the following condition, the design may be reviewed later.
+ // 1. if the resolved element is null.
+ // 2. if the resolved element is not physical, like "DummyMethod" will be generated during psi parsing.
+ // 3. if the resolved element belongs to a virtual file's extension is class.
+ // 4. if the resolved element belongs to a virtual file's path not starts with the repo dir, aka the absolute path of the src root.
+ private boolean isPhysicalValidElement(PsiElement element) {
+ if (element == null) {
+ return false;
+ } else if (!element.isPhysical()) {
+ return false;
+ } else {
+ PsiFile file = element.getContainingFile();
+ if (file == null || file.getVirtualFile().getExtension().equals("class")) {
+ return false;
+ } else if (!file.getVirtualFile().getPath().startsWith(repoDir)) {
+ return false;
+ }
+ return true;
+ }
+ }
+
+ @Override
+ public void visitMethodCallExpression(PsiMethodCallExpression expression) {
+ super.visitMethodCallExpression(expression);
+ com.alipay.codequery.coref.model.Expression.MethodCallExpression methodCallExpression = new com.alipay.codequery.coref.model.Expression.MethodCallExpression(getHashId(expression));
+ methodCallExpression.reference = new com.alipay.codequery.coref.model.Expression(getHashId(expression.getMethodExpression()));
+ methodCallExpression.argumentList = new com.alipay.codequery.coref.model.Expression.ReferenceList(getHashId(expression.getArgumentList()));
+ //add try/catch protection for resolveMethod() in case cannot resolve it.
+ try {
+ PsiMethod psiMethod = expression.resolveMethod();
+ Long calleeId = null;
+ if (isPhysicalValidElement(psiMethod)) {
+ calleeId = getHashId(psiMethod);
+ methodCallExpression.callee = new com.alipay.codequery.coref.model.Expression(calleeId);
+ }
+ // else if (psiMethod != null) {
+ // calleeId = CorefDepExtractor.extractNpMethod(corefStorage, psiMethod);
+ // }
+ if (calleeId != null) {
+ CallableBinding callableBinding = new CallableBinding(methodCallExpression.hashId, calleeId);
+ corefStorage.storeCallableBinding(callableBinding);
+ }
+
+ methodCallExpression.type = expression.getType() != null ? getType(expression.getType()) : new Type((long) -1);
+
+ } catch (IllegalArgumentException illegalArgumentException) {
+ // avoid too many Missing extension point exception stacktrace
+ if (illegalArgumentException.getMessage().contains("Missing extension point")) {
+ methodCallExpression.type = new Type((long) -1);
+ logger.error("error message: {}, element text: {}", illegalArgumentException.getMessage(), expression.getText());
+ } else {
+ logger.error("error message: {}, element text: {}", illegalArgumentException.getMessage(), expression.getText(), illegalArgumentException);
+ }
+ } catch (Throwable e) {
+ PsiFile psiFile = expression.getContainingFile();
+ if (psiFile != null) {
+ logger.error("unknown error, file: {}, element text: {}", psiFile.getVirtualFile().getCanonicalPath(), expression.getText(), e);
+ } else {
+ logger.error("unknown error, element text: {}", expression.getText(), e);
+ }
+ }
+
+ String name = expression.getMethodExpression().getText();
+ if (name.contains("super")) {
+ if (name.equals("super")) {
+ corefStorage.storeSuperConstructorInvocation(methodCallExpression);
+ } else {
+ corefStorage.storeSuperAccessExpression(methodCallExpression);
+ }
+ } else if(methodCallExpression.type.hashId != -1) {
+ corefStorage.storeMethodAccessExpressionWithType(methodCallExpression);
+ } else {
+ corefStorage.storeMethodAccessExpressionWithoutType(methodCallExpression);
+ }
+ }
+
+ @Override
+ public void visitCallExpression(PsiCallExpression callExpression) {
+ super.visitCallExpression(callExpression);
+ }
+
+ @Override
+ public void visitConditionalExpression(PsiConditionalExpression expression) {
+ super.visitConditionalExpression(expression);
+ com.alipay.codequery.coref.model.Expression.ConditionalExpression conditionalExpression = new com.alipay.codequery.coref.model.Expression.ConditionalExpression(getHashId(expression));
+ conditionalExpression.condition = new com.alipay.codequery.coref.model.Expression(getHashId(expression.getCondition()));
+ conditionalExpression.thenExpression = expression.getThenExpression() != null ?
+ new com.alipay.codequery.coref.model.Expression(getHashId(expression.getThenExpression())) : new com.alipay.codequery.coref.model.Expression((long) -1);
+ conditionalExpression.elseExpression = expression.getElseExpression() != null ?
+ new com.alipay.codequery.coref.model.Expression(getHashId(expression.getElseExpression())) : new com.alipay.codequery.coref.model.Expression((long) -1);
+ corefStorage.storeConditionalExpression(conditionalExpression);
+ }
+
+ @Override
+ public void visitContinueStatement(PsiContinueStatement statement) {
+ super.visitContinueStatement(statement);
+ com.alipay.codequery.coref.model.Statement.ContinueStatement continueStatement = new com.alipay.codequery.coref.model.Statement.ContinueStatement(getHashId(statement));
+ continueStatement.continuedStatement = statement.findContinuedStatement() != null ?
+ new com.alipay.codequery.coref.model.Statement(getHashId(statement.findContinuedStatement())) : new com.alipay.codequery.coref.model.Statement((long) -1);
+ if (statement.getLabelIdentifier() != null) {
+ continueStatement.discriminant = new com.alipay.codequery.coref.model.Identifier(statement.getLabelIdentifier().getText(), getHashId(statement.getLabelIdentifier()));
+ NameString nameString = new NameString(continueStatement.hashId, continueStatement.discriminant.hashId, continueStatement.continuedStatement.hashId);
+ corefStorage.storeNameStrings(nameString);
+ }
+ corefStorage.storeContinueStatement(continueStatement);
+ }
+
+ @Override
+ public void visitArrayInitializerExpression(PsiArrayInitializerExpression expression) {
+ super.visitArrayInitializerExpression(expression);
+ com.alipay.codequery.coref.model.Expression.ArrayInitializationExpression aExpression = new com.alipay.codequery.coref.model.Expression.ArrayInitializationExpression(getHashId(expression));
+ aExpression.type = getType(expression.getType());
+ corefStorage.storeArrayInitializerExpression(aExpression);
+ }
+
+ //PsiClassInitializer extends PsiMember
+ @Override
+ public void visitClassInitializer(PsiClassInitializer initializer) {
+ super.visitClassInitializer(initializer);
+ com.alipay.codequery.coref.model.Expression classInitializer = new com.alipay.codequery.coref.model.Expression(getHashId(initializer));
+ classInitializer.debug_message = initializer.getText();
+ classInitializer.parent = getParent(initializer);
+ classInitializer.location = calculateLocation(document, initializer);
+ corefStorage.storeClassInitializer(classInitializer);
+ }
+
+ @Override
+ public void visitBreakStatement(PsiBreakStatement statement) {
+ super.visitBreakStatement(statement);
+ com.alipay.codequery.coref.model.Statement.BreakStatement breakStatement = new com.alipay.codequery.coref.model.Statement.BreakStatement(getHashId(statement));
+ breakStatement.exitedStatemnt = statement.findExitedStatement() != null ?
+ new com.alipay.codequery.coref.model.Statement(getHashId(statement.findExitedStatement())) : new com.alipay.codequery.coref.model.Statement((long) -1);
+ if (statement.getLabelIdentifier() != null) {
+ breakStatement.discriminant = new com.alipay.codequery.coref.model.Identifier(statement.getLabelIdentifier().getText(), getHashId(statement.getLabelIdentifier()));
+ NameString nameString = new NameString(breakStatement.hashId, breakStatement.discriminant.hashId, breakStatement.exitedStatemnt.hashId);
+ corefStorage.storeNameStrings(nameString);
+ }
+ corefStorage.storeBreakStatement(breakStatement);
+ }
+
+ @Override
+ public void visitNewExpression(PsiNewExpression expression) {
+ super.visitNewExpression(expression);
+ com.alipay.codequery.coref.model.Expression.NewExpression newExpression = new com.alipay.codequery.coref.model.Expression.NewExpression(getHashId(expression));
+ newExpression.type = getType(expression.getType());
+
+ if (expression.isArrayCreation()) {
+ newExpression.dimension = expression.getArrayDimensions().length;
+ corefStorage.storeArrayCreationExpression(newExpression);
+ } else {
+ newExpression.reference = expression.getClassReference() != null ?
+ new com.alipay.codequery.coref.model.Expression(getHashId(expression.getClassReference())) : new com.alipay.codequery.coref.model.Expression(getHashId(expression.getAnonymousClass()));
+
+ if (newExpression.type.hashId != -1 && !(newExpression.type.qualifiedName.startsWith("java"))) {
+ corefStorage.storeConstructorInvocation(newExpression);
+
+ try {
+ PsiMethod psiMethod = expression.resolveConstructor();
+ Long calleeId = null;
+ if(isPhysicalValidElement(psiMethod)) {
+ calleeId = getHashId(psiMethod);
+ }
+ // else if (psiMethod != null) {
+ // calleeId = CorefDepExtractor.extractNpMethod(corefStorage, psiMethod);
+ // }
+ if (calleeId != null) {
+ CallableBinding callableBinding = new CallableBinding(newExpression.hashId, calleeId);
+ corefStorage.storeCallableBinding(callableBinding);
+ }
+ } catch (Throwable e) {
+ logger.error("{} {}", this.project, e);
+ }
+
+ } else {
+ corefStorage.storeNewExpression(newExpression);
+ }
+ }
+ }
+
+ @Override
+ public void visitDeclarationStatement(PsiDeclarationStatement statement) {
+ super.visitDeclarationStatement(statement);
+ int i = 0;
+ // s is a local variable or a local class.
+ for (PsiElement s : statement.getDeclaredElements()) {
+ com.alipay.codequery.coref.model.Statement.DeclarationStatement declarationStatement = new com.alipay.codequery.coref.model.Statement.DeclarationStatement(getHashId(s));
+ declarationStatement.index = i;
+ declarationStatement.parent = getParent(s);
+ corefStorage.storeDeclarationElement(declarationStatement);
+ i++;
+ }
+ }
+
+ @Override
+ public void visitExpressionList(PsiExpressionList list) {
+ super.visitExpressionList(list);
+ if (!(list.getText().isEmpty())) {
+ com.alipay.codequery.coref.model.Expression.ExpressionList expressionList = new com.alipay.codequery.coref.model.Expression.ExpressionList(getHashId(list));
+ expressionList.location = calculateLocation(document, list);
+ expressionList.parent = getParent(list);
+ expressionList.debug_message = list.getText();
+ expressionList.size = list.getExpressionCount();
+ corefStorage.storeExpressionList(expressionList);
+ for (int i = 0; i < list.getExpressionCount(); i++) {
+ PsiExpression expression = list.getExpressions()[i];
+ Long expressionHashId = getHashId(expression);
+ ExpressionListExpressionRelation expressionListRelation = new ExpressionListExpressionRelation(expressionList.hashId, expressionHashId, i);
+ corefStorage.storeExpressionListExpressionRelation(expressionListRelation);
+ }
+ }
+ }
+
+ @Override
+ public void visitExpressionStatement(PsiExpressionStatement statement) {
+ super.visitExpressionStatement(statement);
+ com.alipay.codequery.coref.model.Statement.ExpressionStatement expressionStatement = new com.alipay.codequery.coref.model.Statement.ExpressionStatement(getHashId(statement));
+ expressionStatement.expr = new com.alipay.codequery.coref.model.Expression(getHashId(statement.getExpression()));
+ corefStorage.storeExpressionStatement(expressionStatement);
+ }
+
+ //not a statement, actually.
+ @Override
+ public void visitImportStatement(PsiImportStatement statement) {
+ // TODO: we have no need to call super
+ super.visitImportStatement(statement);
+
+ com.alipay.codequery.coref.model.Statement.ImportStatement importStatement = new com.alipay.codequery.coref.model.Statement.ImportStatement(getHashId(statement));
+ importStatement.reference = new com.alipay.codequery.coref.model.Statement(getHashId(statement.getImportReference()));
+ importStatement.debug_message = statement.getText();//statement.getQualifiedName();
+ importStatement.parent = getParent(statement); //skip import list
+ importStatement.location = calculateLocation(document, statement);
+ importStatement.isForeignImport = statement.isForeignFileImport() ? 1 : 0;
+
+ corefStorage.storeImport(importStatement);
+ }
+
+ @Override
+ public void visitTypeCastExpression(PsiTypeCastExpression expression) {
+ super.visitTypeCastExpression(expression);
+ com.alipay.codequery.coref.model.Expression.CastExpression castExpression = new com.alipay.codequery.coref.model.Expression.CastExpression(getHashId(expression));
+ castExpression.operand = new com.alipay.codequery.coref.model.Expression(getHashId(expression.getOperand()));
+ corefStorage.storeCastExpression(castExpression);
+ }
+
+ public HashMap elementIndex = new HashMap<>();
+
+ public void getIndex(PsiElement element) {
+ int i = 0;
+ for (PsiElement e : element.getChildren()) {
+ if (!(e instanceof PsiWhiteSpace) && !(e instanceof PsiJavaToken) && !(e instanceof PsiComment)) {
+ elementIndex.put(e, i);
+ i++;
+ }
+ }
+ }
+
+ public com.alipay.codequery.coref.model.Parent getParent(PsiElement element) {
+ PsiElement psiParent = PsiUtil.getPsiParent(element);
+ if (element instanceof PsiStatement || element instanceof PsiExpression || element instanceof PsiVariable || element instanceof PsiCatchSection) {
+ if (!(elementIndex.containsKey(element))) {
+ getIndex(psiParent);
+ }
+ }
+ com.alipay.codequery.coref.model.Parent parent = new com.alipay.codequery.coref.model.Parent(getHashId(psiParent));
+
+ if (parentMap.containsKey(psiParent)) {
+ return parentMap.get(psiParent);
+ } else {
+ parentMap.put(psiParent, parent);
+ String temp = psiParent.toString();
+ parent.parentType = temp.contains(":") ? temp.substring(3, temp.indexOf(":")) : temp.substring(3);
+ // Save parent info usually for debug usage.
+ //corefStorage.storeParent(parent);
+ return parent;
+ }
+ }
+
+ @Override
+ public void visitStatement(PsiStatement statement) {
+ super.visitStatement(statement);
+ com.alipay.codequery.coref.model.Statement corefStatement = new com.alipay.codequery.coref.model.Statement(getHashId(statement));
+
+ corefStatement.parent = getParent(statement);
+ corefStatement.index = elementIndex.get(statement);
+
+ corefStatement.debug_message = statement.getText();
+ corefStatement.location = calculateLocation(document, statement);
+ String temp = statement.toString();
+ corefStatement.baseName = temp.contains(":") ? temp.substring(3, temp.indexOf(":")) : temp.substring(3);
+ corefStorage.storeStatement(corefStatement);
+ //generateCallableEnclosingStatement(statement.getParent(), corefStatement);
+ generateStatementEnclosingExpression(statement, corefStatement);
+ }
+
+ @Override
+ public void visitExpression(PsiExpression expression) {
+ super.visitExpression(expression);
+ com.alipay.codequery.coref.model.Expression corefExpression = new com.alipay.codequery.coref.model.Expression(getHashId(expression));
+ corefExpression.debug_message = expression.getText();
+
+ corefExpression.parent = getParent(expression);
+ corefExpression.index = elementIndex.get(expression);
+
+ corefExpression.location = calculateLocation(document, expression);
+
+ String temp = expression.toString();
+ corefExpression.baseName = temp.contains(":") ? temp.substring(3, temp.indexOf(":")) : temp.substring(3);
+ corefStorage.storeExpression(corefExpression);
+ }
+
+ @Override
+ public void visitSwitchStatement(PsiSwitchStatement statement) {
+ super.visitSwitchStatement(statement);
+ com.alipay.codequery.coref.model.Statement.SwitchStatement switchStatement = new com.alipay.codequery.coref.model.Statement.SwitchStatement(getHashId(statement));
+ switchStatement.discriminant = new com.alipay.codequery.coref.model.Expression(getHashId(statement.getExpression()));
+ switchStatement.body = new com.alipay.codequery.coref.model.Statement.BlockStatement(getHashId(statement.getBody()));
+ corefStorage.storeSwitchStatement(switchStatement);
+ }
+
+ @Override
+ public void visitSwitchLabelStatement(PsiSwitchLabelStatement statement) {
+ super.visitSwitchLabelStatement(statement);
+ com.alipay.codequery.coref.model.Statement.SwitchLabelStatement labelStatement = new com.alipay.codequery.coref.model.Statement.SwitchLabelStatement(getHashId(statement));
+ labelStatement.caseValue = statement.getCaseValues() != null ?
+ new com.alipay.codequery.coref.model.Expression(getHashId(statement.getCaseValues())) : new com.alipay.codequery.coref.model.Expression((long) -1);
+ labelStatement.enclosingSwitchBlock = new com.alipay.codequery.coref.model.Statement.BlockStatement(getHashId(statement.getEnclosingSwitchBlock()));
+ PsiElement sibling = statement.getNextSibling();
+ while (sibling != null) {
+ if (sibling instanceof PsiSwitchLabelStatement) {
+ labelStatement.nextSwitchCashHashId = getHashId(sibling);
+ break;
+ } else {
+ sibling = sibling.getNextSibling();
+ }
+ }
+ // labelStatement.isDefaultValue = statement.isDefaultCase() ? 1 : 0;
+ corefStorage.storeSwitchLabelStatement(labelStatement);
+ }
+
+ @Override
+ public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression expression) {
+ super.visitClassObjectAccessExpression(expression);
+ try {
+ Type.TypeLiteral literal = new Type.TypeLiteral(getHashId(expression));
+ literal.type = getType(expression.getType());
+ literal.typeElement = new Type(getHashId(expression.getOperand()));
+ corefStorage.storeTypeLiteral(literal);
+ } catch (Throwable e) {
+ logger.error("{} {}", this.project, e);
+ }
+ }
+
+ @Override
+ public void visitSynchronizedStatement(PsiSynchronizedStatement statement) {
+ super.visitSynchronizedStatement(statement);
+ com.alipay.codequery.coref.model.Statement.SynchronizedStatement synchronizedStatement = new com.alipay.codequery.coref.model.Statement.SynchronizedStatement(getHashId(statement));
+ synchronizedStatement.lockExpression = statement.getLockExpression() != null ?
+ new com.alipay.codequery.coref.model.Expression(getHashId(statement.getLockExpression())) : new com.alipay.codequery.coref.model.Expression((long) -1);
+ synchronizedStatement.body = statement.getBody() != null ?
+ new com.alipay.codequery.coref.model.Statement(getHashId(statement.getBody())) : new com.alipay.codequery.coref.model.Statement((long) -1);
+ corefStorage.storeSynchronizedStatement(synchronizedStatement);
+ }
+
+ @Override
+ public void visitTryStatement(PsiTryStatement statement) {
+ super.visitTryStatement(statement);
+ com.alipay.codequery.coref.model.Statement.TryStatement tryStatement = new com.alipay.codequery.coref.model.Statement.TryStatement(getHashId(statement));
+ tryStatement.tryBlock = statement.getTryBlock() != null ?
+ new com.alipay.codequery.coref.model.Statement.CodeBlock(getHashId(statement.getTryBlock())) : new com.alipay.codequery.coref.model.Statement.CodeBlock((long) -1);
+ if(statement.getFinallyBlock() != null) {
+ tryStatement.finallyBlock = new com.alipay.codequery.coref.model.Statement.CodeBlock(getHashId(statement.getFinallyBlock()));
+ corefStorage.storeTryStatementWithFinally(tryStatement);
+ } else {
+ corefStorage.storeTryStatementWithoutFinally(tryStatement);
+ }
+ }
+ //PsiCatchSection extends PsiElement, not an expression.
+ @Override
+ public void visitCatchSection(PsiCatchSection section) {
+ super.visitCatchSection(section);
+ com.alipay.codequery.coref.model.Statement.CatchClause clauseStatement = new com.alipay.codequery.coref.model.Statement.CatchClause(getHashId(section));
+ clauseStatement.param = new com.alipay.codequery.coref.model.Expression(getHashId(section.getParameter()));
+ clauseStatement.tryStatement = new com.alipay.codequery.coref.model.Statement.TryStatement(getHashId(section.getTryStatement()));
+ clauseStatement.debug_message = section.getText();
+ clauseStatement.type = getType(section.getCatchType());
+ clauseStatement.parent = getParent(section);
+ clauseStatement.location = calculateLocation(document, section);
+ clauseStatement.index = elementIndex.get(section);
+ corefStorage.storeCatchClauseStatement(clauseStatement);
+ }
+
+ @Override
+ public void visitThrowStatement(PsiThrowStatement statement) {
+ super.visitThrowStatement(statement);
+ com.alipay.codequery.coref.model.Statement.ThrowStatement throwStatement = new com.alipay.codequery.coref.model.Statement.ThrowStatement(getHashId(statement));
+ throwStatement.exception = new com.alipay.codequery.coref.model.Expression(getHashId(statement.getException()));
+ throwStatement.body = new com.alipay.codequery.coref.model.Statement.CodeBlock(getHashId(statement.getContext()));
+ corefStorage.storeThrowStatement(throwStatement);
+ }
+
+ @Override
+ public void visitThisExpression(PsiThisExpression expression) {
+ super.visitThisExpression(expression);
+ com.alipay.codequery.coref.model.Expression.ThisExpression thisExpression = new com.alipay.codequery.coref.model.Expression.ThisExpression(getHashId(expression));
+ //qualifier info is always null.
+ if(expression.getQualifier() != null) {
+ thisExpression.qualifier = new com.alipay.codequery.coref.model.Expression(getHashId(expression.getQualifier()));
+ corefStorage.storeThisExpressionWithQualifier(thisExpression);
+ }
+ corefStorage.storeThisExpression(thisExpression);
+ }
+
+ @Override
+ public void visitEmptyStatement(PsiEmptyStatement statement) {
+ super.visitEmptyStatement(statement);
+ com.alipay.codequery.coref.model.Statement.EmptyStatement emptyStatement = new com.alipay.codequery.coref.model.Statement.EmptyStatement(getHashId(statement));
+ corefStorage.storeEmptyStatement(emptyStatement);
+ }
+
+ @Override
+ public void visitLabeledStatement(PsiLabeledStatement statement) {
+ super.visitLabeledStatement(statement);
+ com.alipay.codequery.coref.model.Statement.LabeledStatement labeledStatement = new com.alipay.codequery.coref.model.Statement.LabeledStatement(getHashId(statement));
+ labeledStatement.identifier = new com.alipay.codequery.coref.model.Identifier(statement.getLabelIdentifier().getText(), getHashId(statement.getLabelIdentifier()));
+ labeledStatement.statement = statement.getStatement() != null ? new com.alipay.codequery.coref.model.Statement(getHashId(statement.getStatement())) : new com.alipay.codequery.coref.model.Statement((long) -1);
+ if (statement.getStatement() != null) {
+ NameString nameString = new NameString(labeledStatement.hashId, labeledStatement.identifier.hashId, labeledStatement.hashId);
+ corefStorage.storeNameStrings(nameString);
+ }
+ corefStorage.storeLabeledStatement(labeledStatement);
+ }
+
+ @Override
+ public void visitLambdaExpression(PsiLambdaExpression expression) {
+ super.visitLambdaExpression(expression);
+ com.alipay.codequery.coref.model.Expression.LambdaExpression lExpression = new com.alipay.codequery.coref.model.Expression.LambdaExpression(getHashId(expression));
+ lExpression.body = new com.alipay.codequery.coref.model.Statement(getHashId(expression.getBody()));
+ lExpression.paramterList = new com.alipay.codequery.coref.model.Expression(getHashId(expression.getParameterList()));
+ try {
+ lExpression.isValueCompatible = expression.isValueCompatible() ? 1 : 0;
+ } catch (IllegalArgumentException e) {
+ lExpression.isValueCompatible = 0 ;
+ }
+ lExpression.isVoidCompatible = expression.isVoidCompatible() ? 1 : 0;
+ corefStorage.storeLambdaExpression(lExpression);
+ }
+
+ @Override
+ public void visitAssertStatement(PsiAssertStatement statement) {
+ super.visitAssertStatement(statement);
+ com.alipay.codequery.coref.model.Statement.AssertStatement assertStatement = new com.alipay.codequery.coref.model.Statement.AssertStatement(getHashId(statement));
+ assertStatement.condition = statement.getAssertCondition() != null ?
+ new com.alipay.codequery.coref.model.Expression(getHashId(statement.getAssertCondition())) : new com.alipay.codequery.coref.model.Expression((long) -1);
+ assertStatement.description = statement.getAssertDescription() != null ?
+ new com.alipay.codequery.coref.model.Expression(getHashId(statement.getAssertDescription())) : new com.alipay.codequery.coref.model.Expression((long) -1);
+ corefStorage.storeAssertStatement(assertStatement);
+ }
+
+ @Override
+ public void visitReturnStatement(PsiReturnStatement statement) {
+ super.visitReturnStatement(statement);
+ com.alipay.codequery.coref.model.Statement.ReturnStatement returnStatement = new com.alipay.codequery.coref.model.Statement.ReturnStatement(getHashId(statement));
+ returnStatement.returnExpression = statement.getReturnValue() != null ?
+ new com.alipay.codequery.coref.model.Expression(getHashId(statement.getReturnValue())) : new com.alipay.codequery.coref.model.Expression(getHashId(statement));
+ corefStorage.storeReturnStatement(returnStatement);
+ }
+
+ @Override
+ public void visitYieldStatement(PsiYieldStatement statement) {
+ super.visitYieldStatement(statement);
+ com.alipay.codequery.coref.model.Statement.YieldStatement yieldStatement = new com.alipay.codequery.coref.model.Statement.YieldStatement(getHashId(statement));
+ yieldStatement.expression = statement.getExpression() != null ?
+ new com.alipay.codequery.coref.model.Expression(getHashId(statement.getExpression())) : new com.alipay.codequery.coref.model.Expression((long) -1);
+ yieldStatement.enclosingExpression = statement.findEnclosingExpression() != null ?
+ new com.alipay.codequery.coref.model.Expression(getHashId(statement.findEnclosingExpression())) : new com.alipay.codequery.coref.model.Expression((long) -1);
+ corefStorage.storeYieldStatement(yieldStatement);
+ }
+
+ @Override
+ public void visitParameter(PsiParameter parameter) {
+ super.visitParameter(parameter);
+ // parameter in a foreach statement
+ if (!(parameter.getParent() instanceof PsiParameterList)) {
+ com.alipay.codequery.coref.model.Parameter param = new com.alipay.codequery.coref.model.Parameter(getHashId(parameter));
+ param.name = parameter.getName();
+ param.location = calculateLocation(document, parameter);
+ param.parent = getParent(parameter);
+ param.debug_message = parameter.getText();
+ param.index = 0;
+ // If the parameter has no type element, set its type id with -1.
+ param.type = parameter.getTypeElement() != null ? getType(parameter.getType()) : new Type((long) -1);
+ corefStorage.storeParameter(param);
+ }
+ }
+
+ //parent of resource expression and variable
+ @Override
+ public void visitResourceList(PsiResourceList resourceList) {
+ super.visitResourceList(resourceList);
+ Node list = new Node(getHashId(resourceList));
+ ResourceList rlist = new ResourceList();
+ rlist.setDebugMessage(resourceList.getText());
+ rlist.setElementHashId(list.hashId);
+ rlist.setParentHashId(getParent(resourceList).hashId);
+ rlist.setLocationHashId(calculateLocation(document, resourceList).hashId);
+ corefStorage.storeResourceList(rlist);
+ }
+
+ @Override
+ public void visitParameterList(PsiParameterList list) {
+ super.visitParameterList(list);
+ int i = 0;
+ for (PsiParameter param : list.getParameters()) {
+ com.alipay.codequery.coref.model.Parameter parameter = new com.alipay.codequery.coref.model.Parameter(getHashId(param));
+ parameter.name = param.getName();
+ parameter.location = calculateLocation(document, param);
+ parameter.parent = getParent(param); //skip parameter list
+ parameter.debug_message = param.getText();
+ parameter.index = i;
+ i++;
+ // If the parameter has no type element, set its type id with -1.
+ parameter.type = param.getTypeElement() != null ? getType(param.getType()) : new Type((long) -1);
+ corefStorage.storeParameter(parameter);
+ }
+ }
+
+ //extract reference element and reference expression.
+ @Override
+ public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
+ super.visitReferenceElement(reference);
+ com.alipay.codequery.coref.model.Expression referenceElement = new com.alipay.codequery.coref.model.Expression(getHashId(reference));
+ try {
+ if (reference instanceof PsiReferenceExpression) {
+ corefStorage.storeReferenceExpression(referenceElement);
+ } else {
+ referenceElement.debug_message = reference.getText();
+ referenceElement.parent = getParent(reference);
+ referenceElement.location = calculateLocation(document, reference);
+ corefStorage.storeReferenceElement(referenceElement);
+ }
+
+ // store the def-use relation between reference element and self-defined element
+ @Nullable PsiElement definition = reference.resolve();
+ if (isPhysicalValidElement(definition)) {
+ if (definition instanceof PsiMethod || definition instanceof PsiClass || definition instanceof PsiVariable) {
+ ReferenceRelation referenceRelation = new ReferenceRelation(getHashId(reference), getHashId(definition));
+ corefStorage.storeReferenceRelation(referenceRelation);
+ }
+ }
+ } catch (IllegalArgumentException illegalArgumentException) {
+ // avoid too many Missing extension point exception stacktrace
+ if (illegalArgumentException.getMessage().contains("Missing extension point")) {
+ logger.error("error message: {}, element text: {}", illegalArgumentException.getMessage(), reference.getText());
+ } else {
+ logger.error("error message: {}, element text: {}", illegalArgumentException.getMessage(), reference.getText(), illegalArgumentException);
+ }
+ } catch (Throwable e) {
+ PsiFile psiFile = reference.getContainingFile();
+ if (psiFile != null) {
+ logger.error("unknown error, file: {}, element text: {}", psiFile.getVirtualFile().getCanonicalPath(), reference.getText(), e);
+ } else {
+ logger.error("unknown error, element text: {}", reference.getText(), e);
+ }
+ }
+ }
+
+ @Override
+ public void visitField(PsiField field) {
+ com.alipay.codequery.coref.model.Field field1 = new com.alipay.codequery.coref.model.Field(getHashId(field));
+ field1.location = calculateLocation(document, field);
+ field1.name = field.getName();
+ field1.parent = getParent(field);
+ field1.debug_message = field.getText();
+ if (field instanceof PsiEnumConstant) {
+ corefStorage.storeEnumConstant(field1);
+ } else {
+ //String name = mangleFieldName(field);
+ corefStorage.storeField(field1);
+ }
+ super.visitField(field);
+ }
+
+ @Override
+ public void visitUnaryExpression(PsiUnaryExpression expression) {
+ super.visitUnaryExpression(expression);
+ com.alipay.codequery.coref.model.Expression.UnaryExpression unaryExpression = new com.alipay.codequery.coref.model.Expression.UnaryExpression(getHashId(expression));
+ unaryExpression.operand = new com.alipay.codequery.coref.model.Expression(getHashId(expression.getOperand()));
+ unaryExpression.opcode = expression.getOperationTokenType().toString();
+ if (expression instanceof PsiPostfixExpression) {
+ unaryExpression.isPostfix = 1;
+ } else {
+ unaryExpression.isPostfix = 0;
+ }
+ corefStorage.storeUnaryExpression(unaryExpression);
+ }
+
+ @Override
+ public void visitArrayAccessExpression(PsiArrayAccessExpression expression) {
+ super.visitArrayAccessExpression(expression);
+ com.alipay.codequery.coref.model.Expression.ArrayAccessExpression accessExpression = new com.alipay.codequery.coref.model.Expression.ArrayAccessExpression(getHashId(expression));
+ accessExpression.arrayExpression = new com.alipay.codequery.coref.model.Expression.ArrayExpression(getHashId(expression.getArrayExpression()));
+ accessExpression.indexExpression = expression.getIndexExpression() != null ? new com.alipay.codequery.coref.model.Expression.ArrayExpression(getHashId(expression.getIndexExpression())) : new com.alipay.codequery.coref.model.Expression((long) -1);
+ corefStorage.storeArrayAccessExpression(accessExpression);
+ }
+
+ @Override
+ public void visitLocalVariable(PsiLocalVariable variable) {
+ super.visitLocalVariable(variable);
+ com.alipay.codequery.coref.model.LocalVariable localVariable = new com.alipay.codequery.coref.model.LocalVariable(getHashId(variable));
+ localVariable.name = variable.getName();
+ localVariable.debug_message = variable.getText();
+ localVariable.location = calculateLocation(document, variable);
+ localVariable.parent = getParent(variable);
+ localVariable.index = elementIndex.get(variable);
+ corefStorage.storeLocalVariable(localVariable);
+ }
+
+ @Override
+ public void visitVariable(PsiVariable variable) {
+ super.visitVariable(variable);
+ // Check whether the variable has type element or not firstly, otherwise may cause illegal argument exception.
+ if (variable.getTypeElement() != null && variable.getType() instanceof PsiArrayType) {
+ Variable array = new Variable(getHashId(variable));
+ array.name = variable.getName();
+ corefStorage.storeArray(array);
+ }
+ }
+
+ @Override
+ public void visitMethod(PsiMethod psiMethod) {
+ com.alipay.codequery.coref.model.Method method = new Method(getHashId(psiMethod));
+ method.parent = getParent(psiMethod);
+ method.identifier = new com.alipay.codequery.coref.model.Identifier(psiMethod.getName(), getHashId(psiMethod.getNameIdentifier()));
+ method.returnType = psiMethod.getReturnType() != null ? getType(psiMethod.getReturnType()) : new Type( (long) -1);
+ method.location = calculateLocation(document, psiMethod);
+ // 若method有注释,则方法定义部分能需要取到psiMethod下modifier的起始位置
+ int definitionStartOffset = psiMethod.getModifierList().getTextRange().getStartOffset();
+ int definitionEndOffset = psiMethod.getTextRange().getEndOffset();
+ method.definitionBody = document.getText().substring(definitionStartOffset, definitionEndOffset);
+ if (psiMethod.isConstructor()) {
+ method.signature = psiMethod.getContainingClass().getQualifiedName() != null ? PsiUtil.mangleMethodName(psiMethod) : psiMethod.getContainingClass().getName();
+ corefStorage.storeConstructor(method);
+ } else {
+ method.signature = PsiUtil.mangleMethodName(psiMethod);
+ corefStorage.storeMethod(method);
+ }
+
+ generateCallableEnclosingNode(psiMethod, method);
+ super.visitMethod(psiMethod);
+ }
+
+ @Override
+ public void visitForStatement(PsiForStatement statement) {
+ super.visitForStatement(statement);
+ com.alipay.codequery.coref.model.Statement.ForStatement stmt = new com.alipay.codequery.coref.model.Statement.ForStatement(getHashId(statement));
+ stmt.init = statement.getInitialization() != null ?
+ new com.alipay.codequery.coref.model.Expression(getHashId(statement.getInitialization())) : new com.alipay.codequery.coref.model.Expression((long) -1);
+ stmt.update = statement.getUpdate() != null ?
+ new com.alipay.codequery.coref.model.Expression(getHashId(statement.getUpdate())) : new com.alipay.codequery.coref.model.Expression((long) -1);
+ stmt.condition = statement.getCondition() != null ?
+ new com.alipay.codequery.coref.model.Expression(getHashId(statement.getCondition())) : new com.alipay.codequery.coref.model.Expression((long) -1);
+ stmt.body = new com.alipay.codequery.coref.model.Statement(getHashId(statement.getBody()));
+ corefStorage.storeForStatement(stmt);
+ }
+
+ @Override
+ public void visitAnonymousClass(PsiAnonymousClass aClass) {
+ super.visitAnonymousClass(aClass);
+ com.alipay.codequery.coref.model.Class.AnonymousClass anonymousClass = new com.alipay.codequery.coref.model.Class.AnonymousClass(getHashId(aClass));
+ anonymousClass.location = calculateLocation(document, aClass);
+ anonymousClass.parent = getParent(aClass);
+ anonymousClass.baseType = getType(aClass.getBaseClassType());
+ //BaseClassReference may resolve to null.
+ anonymousClass.baseClass = new Class.ClassDefinition(getHashId(aClass.getBaseClassReference()));
+ corefStorage.storeAnonymousClass(anonymousClass);
+ }
+
+ @Override
+ public void visitForeachStatement(PsiForeachStatement statement) {
+ super.visitForeachStatement(statement);
+ com.alipay.codequery.coref.model.Statement.ForeachStatement stmt = new com.alipay.codequery.coref.model.Statement.ForeachStatement(getHashId(statement));
+ stmt.iterationParameter = new Parameter(getHashId(statement.getIterationParameter()));
+ stmt.iteratedValue = new com.alipay.codequery.coref.model.Expression(getHashId(statement.getIteratedValue()));
+ stmt.body = new com.alipay.codequery.coref.model.Statement(getHashId(statement.getBody()));
+ corefStorage.storeForeachStatement(stmt);
+ }
+
+ @Override
+ public void visitAssignmentExpression(PsiAssignmentExpression expression) {
+ super.visitAssignmentExpression(expression);
+ com.alipay.codequery.coref.model.Expression.AssignmentExpression assignmentExpression = new com.alipay.codequery.coref.model.Expression.AssignmentExpression(getHashId(expression));
+ assignmentExpression.lhs = new com.alipay.codequery.coref.model.Expression(getHashId(expression.getLExpression()));
+ assignmentExpression.rhs = new com.alipay.codequery.coref.model.Expression(getHashId(expression.getRExpression()));
+ assignmentExpression.opcode = expression.getOperationSign().getText();
+ corefStorage.storeAssignmentExpression(assignmentExpression);
+ }
+
+ @Override
+ public void visitKeyword(PsiKeyword keyword) {
+ super.visitKeyword(keyword);
+ com.alipay.codequery.coref.model.Modifier modifier = new Modifier(getHashId(keyword));
+ modifier.name = keyword.getText();
+ modifier.parent = getParent(keyword);
+ modifier.location = calculateLocation(document, keyword);
+ corefStorage.storeModifier(modifier);
+ }
+
+ @Override
+ public void visitIdentifier(PsiIdentifier identifier) {
+ super.visitIdentifier(identifier);
+ com.alipay.codequery.coref.model.Identifier identifiers = new Identifier(identifier.getText(), getHashId(identifier));
+ identifiers.parent = getParent(identifier);
+ identifiers.location = calculateLocation(document, identifier);
+ corefStorage.storeIdentifier(identifiers);
+ }
+
+ @Override
+ public void visitPolyadicExpression(PsiPolyadicExpression expression) {
+ super.visitPolyadicExpression(expression);
+ try {
+ if (expression instanceof PsiBinaryExpression) {
+ com.alipay.codequery.coref.model.Expression.BinaryExpression binaryExpression = new com.alipay.codequery.coref.model.Expression.BinaryExpression(getHashId(expression));
+ binaryExpression.lhs = new com.alipay.codequery.coref.model.Expression(getHashId(((PsiBinaryExpression) expression).getLOperand()));
+ binaryExpression.rhs = new com.alipay.codequery.coref.model.Expression(getHashId(((PsiBinaryExpression) expression).getROperand()));
+ binaryExpression.opcode = ((PsiBinaryExpression) expression).getOperationSign().getText();
+ corefStorage.storeBinaryExpression(binaryExpression);
+ } else {
+ com.alipay.codequery.coref.model.Expression.PolyadicExpression polyadicExpression = new com.alipay.codequery.coref.model.Expression.PolyadicExpression(getHashId(expression));
+ polyadicExpression.size = expression.getOperands().length;
+ polyadicExpression.opcode = expression.getOperationTokenType().toString();
+ corefStorage.storePolyadicExpression(polyadicExpression);
+ }
+ } catch (NullPointerException e) {
+ logger.error("error message: {}, element text: {}", e.getMessage(), expression.getText());
+ }
+ }
+
+ @Override
+ public void visitIfStatement(PsiIfStatement statement) {
+ super.visitIfStatement(statement);
+ com.alipay.codequery.coref.model.Statement.IfStatement ifStatement = new com.alipay.codequery.coref.model.Statement.IfStatement(getHashId(statement));
+ ifStatement.condition = statement.getCondition() != null ?
+ new com.alipay.codequery.coref.model.Expression(getHashId(statement.getCondition())) : new com.alipay.codequery.coref.model.Expression((long) -1);
+ ifStatement.thenBranch = statement.getThenBranch() != null ?
+ new com.alipay.codequery.coref.model.Statement(getHashId(statement.getThenBranch())) : new com.alipay.codequery.coref.model.Statement((long) -1);
+ if(statement.getElseBranch() != null) {
+ ifStatement.elseBranch = new Statement(getHashId(statement.getElseBranch()));
+ corefStorage.storeIfStatementWithElse(ifStatement);
+ } else {
+ corefStorage.storeIfStatementWithoutElse(ifStatement);
+ }
+
+ }
+
+ @Override
+ public void visitDocTag(PsiDocTag tag) {
+ super.visitDocTag(tag);
+ com.alipay.codequery.coref.model.Comment.JavaDocTag javaDocTag = new com.alipay.codequery.coref.model.Comment.JavaDocTag(getHashId(tag));
+ javaDocTag.value = tag.getValueElement() != null ? tag.getValueElement().getText() : "-1";
+ javaDocTag.name = tag.getName();
+ int i = 0;
+ for (PsiDocTag t : tag.getContainingComment().getTags()) {
+ if (t == tag) {
+ javaDocTag.index = i;
+ }
+ i++;
+ }
+ javaDocTag.location = calculateLocation(document, tag);
+ javaDocTag.containedComment = new com.alipay.codequery.coref.model.Comment(getHashId(tag.getContainingComment()));
+ corefStorage.storeJavaDocTag(javaDocTag);
+ }
+
+ /**
+ * This method extracts PsiComment element info, including java doc comment and normal coment.
+ */
+ @Override
+ public void visitComment(@NotNull PsiComment comment) {
+ super.visitComment(comment);
+ if (comment instanceof PsiDocComment) {
+ com.alipay.codequery.coref.model.Comment.JavaDocComment javaDocComments = new com.alipay.codequery.coref.model.Comment.JavaDocComment(getHashId(comment));
+ javaDocComments.text = comment.getText();
+ javaDocComments.documentedItem = ((PsiDocComment) comment).getOwner() != null ?
+ new Node(getHashId(((PsiDocComment) comment).getOwner())) : new Node((long) -1);
+ javaDocComments.location = calculateLocation(document, comment);
+ javaDocComments.parent = getParent(comment);
+ corefStorage.storeJavaDocComment(javaDocComments);
+ } else {
+ com.alipay.codequery.coref.model.Comment comments = new com.alipay.codequery.coref.model.Comment(getHashId(comment));
+ comments.text = comment.getText();
+ comments.parent = getParent(comment);
+ comments.location = calculateLocation(document, comment);
+ // Add one attribute to normal comment, to record the comment type, which may be end_of_line_comment or c_style_comment.
+ comments.commentType = comment.getTokenType().toString();
+ corefStorage.storeComment(comments);
+ }
+ }
+
+ /**
+ * This method extract the info about PsiDocToken with Data type.
+ */
+ @Override
+ public void visitDocToken(PsiDocToken token) {
+ super.visitDocToken(token);
+ if(token.getTokenType().toString().equals("DOC_COMMENT_DATA") && !(StringUtil.isEmptyOrSpaces(token.getText()))) {
+ com.alipay.codequery.coref.model.Comment.JavaDocDataToken javaDocDataToken = new com.alipay.codequery.coref.model.Comment.JavaDocDataToken(getHashId(token));
+ javaDocDataToken.value = token.getText();
+ int i = 0;
+ for (PsiElement t : token.getParent().getChildren()) {
+ if (t instanceof PsiDocToken && t.isEquivalentTo(token)) {
+ javaDocDataToken.index = i;
+ }
+ i++;
+ }
+ javaDocDataToken.parent = getParent(token);
+ javaDocDataToken.location = calculateLocation(document, token);
+ corefStorage.storeJavaDocDataToken(javaDocDataToken);
+ }
+ }
+
+ /**
+ * This method extract the info about PsiDocTagValue element.
+ */
+ @Override
+ public void visitDocTagValue(PsiDocTagValue value) {
+ super.visitDocTagValue(value);
+ com.alipay.codequery.coref.model.Comment.JavaDocTagValue javaDocTagValue = new Comment.JavaDocTagValue(getHashId(value));
+ javaDocTagValue.value = value.getText();
+ javaDocTagValue.parent = getParent(value);
+ javaDocTagValue.location = calculateLocation(document, value);
+ corefStorage.storeJavaDocTagValue(javaDocTagValue);
+ }
+
+ @Override
+ public void visitLiteralExpression(PsiLiteralExpression expression) {
+ super.visitLiteralExpression(expression);
+ Literal literal = new Literal(getHashId(expression));
+ literal.type = expression.getType().getPresentableText();
+ literal.value = expression.getText();
+ corefStorage.handleLiteral(literal);
+ }
+
+ @Override
+// PsiReferenceList is ReferenceElement's parent, get exception information.
+ public void visitReferenceList(PsiReferenceList list) {
+ super.visitReferenceList(list);
+ if (!(list.getText().isEmpty())) {
+ com.alipay.codequery.coref.model.Expression.ReferenceList referenceList = new Expression.ReferenceList(getHashId(list));
+ referenceList.parent = getParent(list);
+ referenceList.location = calculateLocation(document, list);
+ referenceList.role = list.getRole().name();
+ referenceList.debug_message = list.getText();
+ corefStorage.storeReferencelist(referenceList);
+ }
+ }
+
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/core/CorefURI.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/core/CorefURI.java
new file mode 100644
index 00000000..9cfeab32
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/core/CorefURI.java
@@ -0,0 +1,41 @@
+package com.alipay.codequery.coref.core;
+
+import com.alipay.codequery.coref.util.HashUtil;
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.commons.lang3.StringUtils;
+
+@Setter
+@Getter
+public class CorefURI {
+
+ private static String URI_TEMPLATE = "coref://%s?path=%s#%s";
+
+ private String signature;
+ private String repository;
+ private String path;
+
+
+ public CorefURI(String repository) {
+ this.repository = repository;
+ }
+
+ public String toString() {
+ return generate(repository, path, signature);
+ }
+
+ public static String generate(String repository, String path, String signature) {
+ if(StringUtils.isBlank(repository)
+ ||StringUtils.isBlank(path)
+ || StringUtils.isBlank(signature)) {
+ throw new RuntimeException("blank repository or path or signature");
+ }
+
+ return String.format(URI_TEMPLATE, repository, path, signature);
+ }
+
+ public static Long generateHashId(String repository, String path, String signature) {
+ return HashUtil.hashString(generate(repository, path, signature));
+ }
+
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/core/Runner.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/core/Runner.java
new file mode 100644
index 00000000..9e515a99
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/core/Runner.java
@@ -0,0 +1,345 @@
+package com.alipay.codequery.coref.core;
+
+
+import com.alipay.codequery.Configuration;
+import com.alipay.codequery.coref.model.Folder;
+import com.alipay.codequery.coref.model.Node;
+import com.alipay.codequery.coref.model.Program;
+import com.alipay.codequery.coref.storage.*;
+import com.alipay.codequery.coref.util.HashUtil;
+import com.alipay.codequery.project.PsiProject;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import lombok.extern.slf4j.Slf4j;
+import me.tongfei.progressbar.ProgressBar;
+import me.tongfei.progressbar.ProgressBarBuilder;
+import me.tongfei.progressbar.ProgressBarStyle;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.kotlin.com.intellij.psi.PsiJavaFile;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Paths;
+import java.time.Duration;
+import java.time.Instant;
+import java.util.*;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ForkJoinPool;
+import java.util.stream.Collectors;
+
+@Slf4j
+public class Runner {
+ public static final int DEFAULT_BATCH_SIZE = 100;
+ public static final int DEFAULT_PARALLEL_BATCH_SIZE = 100;
+
+ public final Configuration configuration;
+ public final PsiProject basicProject;
+ public final List javaFiles;
+ private final File srcRootDir;
+ private Program program;
+
+ public Runner(Configuration configuration,
+ PsiProject basicProject,
+ List javaFiles,
+ File srcRootDir) {
+ this.configuration = configuration;
+ this.basicProject = basicProject;
+ this.javaFiles = javaFiles;
+ this.srcRootDir = srcRootDir;
+ }
+
+
+ private static void analyseFile(Configuration configuration, PsiProject project, IStorage sliceCorefStorage, Program program, File javaPath) {
+ String srcRootPath = configuration.getSourcePath();
+
+ // corresponding the java path to a psi java file into the project
+ @Nullable PsiJavaFile psiJavaFile = project.getPsiJavaFileFromFile(javaPath);
+ assert psiJavaFile != null;
+ String fileName = psiJavaFile.getContainingFile().getVirtualFile().getCanonicalPath();
+ try {
+ CorefExtractor corefExtractor = new CorefExtractor(project, srcRootPath, psiJavaFile, sliceCorefStorage, program, new CorefURI(configuration.repository));
+ psiJavaFile.accept(corefExtractor);
+
+ } catch (Throwable e) {
+ log.error("extracting error for: {}", fileName, e);
+ }
+ }
+
+ // 填充基本信息
+ // 1. Coref 根节点 —— Program节点
+ // 2. 文件目录信息
+ private void fillCommonInfo(File srcRootDir, IStorage storage) {
+ Program program = createProgramNode(javaFiles, srcRootDir.getAbsolutePath(), storage);
+ this.program = program;
+ visitDirectory(srcRootDir.getAbsolutePath(), program, storage);
+ storage.commit();
+ }
+
+ // Create coref root (aka. program) node of the input source.
+ private Program createProgramNode(List allJavaFiles, String repoDir, IStorage corefStorage) {
+ Program program = new Program(HashUtil.getStringSHA256(this.configuration.sourcepath.toString()));
+ if (allJavaFiles.size() > 0) {
+ if (repoDir.startsWith("/")) {
+ program.prefix = repoDir;
+ } else {
+ String absolutePath = allJavaFiles.get(0).getAbsolutePath();
+ program.prefix = absolutePath.substring(0, absolutePath.indexOf(repoDir));
+ }
+ }
+ corefStorage.storeProgram(program);
+ return program;
+ }
+
+ // Create folder nodes from the input source root dir.
+ public void visitDirectory(String repoDir, Node parent, IStorage corefStorage) {
+ String[] blackFilePath = {"node_modules", ".git", ".idea"};
+ if (StringUtils.containsAnyIgnoreCase(repoDir, blackFilePath)) {
+ log.info("ignore dir: {}", repoDir);
+ return;
+ }
+
+ File file = new File(repoDir);
+
+ // Ignore the folder starts with "."
+ if (file.isDirectory() && !(file.getName().startsWith("."))) {
+ String absolutePath = file.getAbsolutePath();
+
+ Folder parentFolder = new Folder(HashUtil.getStringSHA256(absolutePath));
+ parentFolder.name = file.getName();
+ parentFolder.parent = parent;
+
+ // Calculate the relative path of the folder.
+ if (absolutePath.endsWith(srcRootDir.getAbsolutePath())) {
+ parentFolder.qualifiedName = "ROOT";
+ } else {
+ char head = repoDir.charAt(0);
+ switch (head) {
+ case '/':
+ parentFolder.qualifiedName = absolutePath.substring(srcRootDir.getAbsolutePath().length() + 1);
+ break;
+ case '.':
+ parentFolder.qualifiedName = absolutePath.substring(absolutePath.indexOf(repoDir) + 2);
+ break;
+ default:
+ parentFolder.qualifiedName = absolutePath.substring(absolutePath.indexOf(repoDir));
+ }
+ }
+ corefStorage.storeFolder(parentFolder);
+
+ // Recursively visit the sub folders.
+ for (File f : file.listFiles()) {
+ if (f.isDirectory()) {
+ visitDirectory(f.getAbsolutePath(), parentFolder, corefStorage);
+ } else if (f.getName().endsWith(".java")) {
+ SharedManager.FILE_MAP.put(f.getAbsolutePath(), parentFolder.hashId);
+ }
+ }
+ }
+ }
+
+ /**
+ * 生成coref ast
+ */
+ public void sequenceDumpCorefAST(String corefASTPath){
+ log.info("Dump Coref AST with {} java files.", javaFiles.size());
+ ProgressBarBuilder pbb = new ProgressBarBuilder()
+ .setInitialMax(javaFiles.size())
+ .setTaskName("Dump COREF-Java AST ")
+ .setStyle(ProgressBarStyle.ASCII);
+ for (File javaFile : ProgressBar.wrap(javaFiles, pbb)) {
+ try {
+ CorefASTDumpStorage storage = new CorefASTDumpStorage(corefASTPath, this.srcRootDir.toString(), javaFile, this.basicProject, configuration.repository);
+ analyseFile(configuration, basicProject, storage, program, javaFile);
+ storage.commit();
+ } catch (Throwable e) {
+ log.error("Error when extracting: " + javaFile.getAbsolutePath(), e);
+ }
+ }
+ }
+ /**
+ * run analysis in file sequence (with specific files)
+ */
+ public void sequenceAnalyse(String dbDir, String dbFileName) {
+ log.info("Analyse project with {} java files.", javaFiles.size());
+
+ IStorage storage = new SqliteStorage2(dbDir, dbFileName);
+ fillCommonInfo(this.srcRootDir, storage);
+
+ ProgressBarBuilder pbb = new ProgressBarBuilder()
+ .setInitialMax(javaFiles.size())
+ .setTaskName("Extracting COREF-Java")
+ .setStyle(ProgressBarStyle.ASCII);
+ for (File javaFile : ProgressBar.wrap(javaFiles, pbb)) {
+ try {
+ analyseFile(configuration, basicProject, storage, program, javaFile);
+ storage.commit();
+ } catch (Throwable e) {
+ log.error("Error when extracting: " + javaFile.getAbsolutePath(), e);
+ }
+ }
+ }
+
+ public void parallelAnalyse(String pathPrefix, int workerCount, String dbDir, String dbFileName) throws InterruptedException, IOException {
+ ExecutorService psiExecutePool = new ForkJoinPool(workerCount);
+
+ // 注册关闭hook函数,优雅退出
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ @Override
+ public void run() {
+ log.info("calling shutdown hook.");
+ psiExecutePool.shutdown();
+ }
+ });
+
+ List allJavaPaths = basicProject.allJavaPaths().collect(Collectors.toList());
+ log.info("Analyse project with {} java files.", javaFiles.size());
+ ThreadLocal threadLocal = new ThreadLocal<>();
+ List> partedList = Lists.partition(allJavaPaths, DEFAULT_PARALLEL_BATCH_SIZE);
+ log.info("Parallel Extraction Mode, Worker Count: {}, Batch Size: {}, Batch Count: {}", workerCount, DEFAULT_PARALLEL_BATCH_SIZE, partedList.size());
+ CountDownLatch latch = new CountDownLatch(partedList.size());
+ IStorage mergedStorage = new SqliteStorage2(dbDir, dbFileName);
+ fillCommonInfo(srcRootDir, mergedStorage);
+
+ ProgressBar parallelProgressBar = new ProgressBarBuilder()
+ .setInitialMax(javaFiles.size())
+ .setTaskName("Parallel Extracting COREF-Java")
+ .setStyle(ProgressBarStyle.ASCII)
+ .build();
+ for (int i = 0; i < partedList.size(); i++) {
+ int idx = i;
+ List part = partedList.get(i);
+ psiExecutePool.submit(() -> {
+ String sqliteFileDir = Paths.get(pathPrefix).toAbsolutePath().toString();
+ IStorage storage = new SqliteStorage2(sqliteFileDir, String.valueOf(idx));
+
+ part.stream()
+ .parallel()
+ .forEach(javaPath -> {
+ PsiProject threadProject;
+ threadProject = threadLocal.get();
+ if (threadProject == null) {
+ threadProject = PsiProject.buildProject(configuration);
+ threadLocal.set(threadProject);
+ }
+ analyseFile(configuration, threadProject, storage, program, javaPath);
+ });
+
+ // end of batch analysis, begin to storage
+ storage.commit();
+ latch.countDown();
+ parallelProgressBar.stepBy(part.size());
+ });
+ }
+
+ latch.await();
+ psiExecutePool.shutdown();
+
+ String mergedDBFileName = dbDir + File.separator + dbFileName;
+ SqliteUtil.importSqlite(
+ pathPrefix,
+ mergedDBFileName
+ );
+
+ // 合并完成后,删除分片
+ log.info("after merge. Will delete batch file dir: {}", pathPrefix);
+ FileUtils.deleteDirectory(Paths.get(pathPrefix).toFile());
+ }
+
+
+ public void incrementalAnalyse(String dbDir, String dbFileName, CorefCache corefCache, String commitId) throws InterruptedException {
+ log.info("start inc analyse");
+
+ IStorage storage = new SqliteStorage2(dbDir, dbFileName);
+ fillCommonInfo(this.srcRootDir, storage);
+
+ Set cachedFileIds = corefCache.getAllObjectIds();
+ log.info("end of get all objects");
+ // 计算所有源文件的hash信息,存储在内存中
+ Map currentFileObjectMap = new HashMap<>();
+ for (File javaFile : javaFiles) {
+ FileScopeCorefObject fileObject = new FileScopeCorefObject();
+ String currentFileId = HashUtil.getFileSha1Hash(javaFile);
+ fileObject.setHashId(currentFileId);
+ fileObject.setSourceFile(javaFile);
+ fileObject.setCacheFile(new File(corefCache.getLocalObjectDir().getAbsolutePath() + "/" + currentFileId));
+ currentFileObjectMap.put(currentFileId, fileObject);
+ }
+
+ // 找出当前文件集中存在,且缓存中不存在的。就是待分析的文件集
+ Set diffSet = Sets.difference(currentFileObjectMap.keySet(), cachedFileIds).immutableCopy();
+ Set toBeAnalyzedFileObject = new HashSet<>();
+ for (Map.Entry fileObjectEntry : currentFileObjectMap.entrySet()) {
+ if (diffSet.contains(fileObjectEntry.getKey())) {
+ toBeAnalyzedFileObject.add(fileObjectEntry.getValue());
+ }
+ }
+ log.info("total file: {}, to be analyzed file: {}", javaFiles.size(), toBeAnalyzedFileObject.size());
+
+ // 下载文件
+ Set sameSet = Sets.intersection(currentFileObjectMap.keySet(), cachedFileIds).immutableCopy();
+ corefCache.getObjectByIds(sameSet);
+ log.info("get intersection objects ends.");
+
+ // 开始抽取
+ ProgressBar pb = new ProgressBarBuilder()
+ .setInitialMax(toBeAnalyzedFileObject.size())
+ .setTaskName("Incremental Extracting COREF-Java")
+ .setStyle(ProgressBarStyle.ASCII).build();
+
+ // 并行抽取
+ CountDownLatch latch = new CountDownLatch(toBeAnalyzedFileObject.size());
+ List> partedList = Lists.partition(Lists.newArrayList(toBeAnalyzedFileObject), DEFAULT_PARALLEL_BATCH_SIZE);
+ ExecutorService psiExecutePool = new ForkJoinPool(8);
+ ThreadLocal threadLocal = new ThreadLocal<>();
+ for (List part : partedList) {
+ psiExecutePool.submit(() -> {
+ try {
+ part.stream()
+ .parallel()
+ .forEach(fileObject -> {
+ IStorage fileStorage = new SqliteStorage2(corefCache.getLocalObjectDir().getAbsolutePath(), fileObject.getHashId());
+ PsiProject threadProject;
+ threadProject = threadLocal.get();
+ if (threadProject == null) {
+ threadProject = PsiProject.buildProject(configuration);
+ threadLocal.set(threadProject);
+ }
+
+ analyseFile(configuration, threadProject, fileStorage, program, fileObject.getSourceFile());
+ fileStorage.commit();
+ latch.countDown();
+ pb.stepBy(1);
+ });
+ } catch (Throwable e) {
+ log.error("Error when extracting: ", e);
+ }
+ });
+ }
+
+ latch.await();
+ psiExecutePool.shutdown();
+ log.info("end extracting.");
+
+ log.info("analyze done. Will adding {} files to cache. ", toBeAnalyzedFileObject.size());
+ corefCache.putObjects(toBeAnalyzedFileObject);
+ log.info("put to cache objects ends.");
+ Commit commit = new Commit(commitId, currentFileObjectMap.values(), srcRootDir);
+ corefCache.putCommit(commit);
+ log.info("put to cache refs ends.");
+
+ // 合并成一个大DB,用于查询
+ Instant beforeMerge = Instant.now();
+ Set currentFileCorefData = currentFileObjectMap.values().stream()
+ .map(FileScopeCorefObject::getCacheFile)
+ .collect(Collectors.toSet());
+ SqliteUtil.importSqlite(
+ currentFileCorefData,
+ dbDir + "/" + dbFileName
+ );
+ long timeCost = Duration.between(beforeMerge, Instant.now()).getSeconds();
+ log.info("time cost of merge db: {}s", timeCost);
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/core/SharedManager.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/core/SharedManager.java
new file mode 100644
index 00000000..84382b03
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/core/SharedManager.java
@@ -0,0 +1,45 @@
+package com.alipay.codequery.coref.core;
+
+import com.alipay.codequery.coref.model.Type;
+import com.alipay.codequery.coref.storage.IStorage;
+import com.alipay.codequery.util.PsiUtil;
+import com.alipay.codequery.coref.util.HashUtil;
+import org.jetbrains.kotlin.com.intellij.psi.*;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+
+public class SharedManager {
+
+ public static final Set RESOLVED_ANNOTATION_SET = Collections.synchronizedSet(new HashSet<>());
+ public static final Map FILE_MAP = new ConcurrentHashMap<>();
+ private static final Map TYPE_MAP = new ConcurrentHashMap<>();
+
+ public static void clear() {
+ RESOLVED_ANNOTATION_SET.clear();
+ FILE_MAP.clear();
+ TYPE_MAP.clear();
+ }
+
+ public static Type getType(IStorage storage, PsiType type) {
+ String qualifiedName = PsiUtil.getQualifiedNameIfPossible(type);
+ if (type instanceof PsiPrimitiveType) {
+ for (Type.PrimitiveType primitiveType : Type.PrimitiveType.values()) {
+ if (primitiveType.name.equals(qualifiedName)) {
+ return new Type((long) primitiveType.index);
+ }
+ }
+ } else if (type instanceof PsiMethodReferenceType || type instanceof PsiArrayType || type instanceof PsiClassType) {
+ return TYPE_MAP.computeIfAbsent(qualifiedName, (k) -> {
+ Long hashId = HashUtil.hashString(k);
+ Type elementType = new Type(hashId);
+ elementType.qualifiedName = k;
+ elementType.name = PsiUtil.getNameIfPossible(type);
+ storage.storeReferenceType(elementType);
+ return elementType;
+ });
+ }
+ return new Type((long) -1);
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/core/SignatureGenerator.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/core/SignatureGenerator.java
new file mode 100644
index 00000000..73a468b3
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/core/SignatureGenerator.java
@@ -0,0 +1,128 @@
+package com.alipay.codequery.coref.core;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.jetbrains.kotlin.com.intellij.openapi.util.TextRange;
+import org.jetbrains.kotlin.com.intellij.psi.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SignatureGenerator {
+ private static final Logger LOGGER = LogManager.getLogger(SignatureGenerator.class);
+
+ public static String generate(PsiElement element) {
+ String signature;
+ if (element instanceof PsiClass) {
+ signature = SignatureGenerator.generateClassSignature((PsiClass) element);
+ } else if (element instanceof PsiMethod) {
+ signature = SignatureGenerator.generateMethodSignature((PsiMethod) element);
+ } else if (element instanceof PsiField) {
+ signature = SignatureGenerator.generateFieldSignature((PsiField) element);
+ } else {
+ signature = SignatureGenerator.generateCommonElementSignature(element);
+ }
+
+ return signature;
+ }
+
+ private static String generateClassSignature(PsiClass psiClass) {
+ // for generate signature of method whose class is null
+ if(psiClass == null) {
+ return "CorefDummyClass";
+ }
+ // if a class is an anonymous class or it is a local class inside a method.
+ if (psiClass instanceof PsiAnonymousClass || psiClass.getQualifiedName() == null) {
+ return generateCommonElementSignature(psiClass);
+ }
+ if (psiClass instanceof PsiTypeParameter) {
+ return generateCommonElementSignature(psiClass);
+ }
+ if (psiClass.getQualifiedName() != null) {
+ return psiClass.getQualifiedName();
+ }
+
+ // may be method's inner class.
+ // 普通inner class的parent是PsiClass,可以正常获取到qualified name
+ // method scope的inner class,psi中算作变量声明,因此我们当成普通变量来处理
+ if (psiClass.getParent() instanceof PsiDeclarationStatement) {
+ return generateCommonElementSignature(psiClass);
+ }
+ throw new RuntimeException("cannot generate signature for PsiClass: " + psiClass);
+ }
+
+ private static String generateMethodSignature(PsiMethod psiMethod) {
+ // return CorefExtractor.mangleMethodName(psiMethod);
+ StringBuilder paramListSignature = new StringBuilder();
+ PsiParameter[] params = psiMethod.getParameterList().getParameters();
+ paramListSignature.append("(");
+ for (int i = 0; i < params.length; ++i) {
+ PsiType paramType = params[i].getType();
+ paramListSignature.append(paramType.getCanonicalText());
+ if (i != params.length - 1) {
+ paramListSignature.append(",");
+ }
+ }
+ paramListSignature.append(")");
+
+ // Fixed: if the method exists type parameter, add it at the end of the method signature to guarantee the signature uniques.
+ // TODO: the current design may not be the best choice, needs to review it later.
+ // StringBuilder typeParameterSignature = new StringBuilder();
+ String typeParameterListSignature = "";
+ PsiTypeParameterList typeParameterList = psiMethod.getTypeParameterList();
+ try {
+ // typeParameterList.getText() may throws NPE
+ if(typeParameterList != null && !(typeParameterList.getText().isEmpty())) {
+ List typeParameterSignature = new ArrayList<>();
+ for (PsiTypeParameter t : typeParameterList.getTypeParameters()) {
+ typeParameterSignature.add(t.getText());
+ }
+ typeParameterListSignature = ":<" + StringUtils.join(typeParameterSignature, ", ") + ">";
+ }
+ } catch (Exception e) {
+ LOGGER.debug(e.getMessage(), e);
+ }
+
+ String methodName = psiMethod.getName();
+ if (psiMethod.isConstructor()) {
+ // 若是构造函数,则使用javac的处理方式,https://docs.oracle.com/javase/specs/jvms/se17/html/jvms-2.html#jvms-2.9.1
+ methodName = "";
+ }
+
+ return generateClassSignature(psiMethod.getContainingClass()) + "." + methodName + paramListSignature + typeParameterListSignature;
+ }
+
+ // TODO type info?
+ private static String generateFieldSignature(PsiField psiField) {
+ String classSignature = generateClassSignature(psiField.getContainingClass());
+ return classSignature + "." + psiField.getName();
+ }
+
+ private static String generateParameterSignature(PsiParameter psiParameter) {
+ return generateCommonElementSignature(psiParameter);
+ }
+
+ private static String generateLocalVariableSignature(PsiVariable psiVariable) {
+ return generateCommonElementSignature(psiVariable);
+ }
+
+ private static String generateLocationSignature(PsiElement psiElement) {
+ TextRange textRange = psiElement.getTextRange();
+ return textRange.getStartOffset() + "-" + textRange.getEndOffset();
+ }
+
+ // TODO: PsiKeywordImpl:(0,7) ?
+ private static String generateCommonElementSignature(PsiElement psiElement) {
+ String offsetString = "-1";
+ try {
+ if (psiElement.getTextRange() != null) {
+ offsetString = psiElement.getTextRange().toString();
+ }
+ } catch (Exception e) {
+ LOGGER.debug(e.getMessage(), e);
+ }
+ return psiElement.toString() + ":" + offsetString;
+ }
+
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Annotation.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Annotation.java
new file mode 100644
index 00000000..c706c9b7
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Annotation.java
@@ -0,0 +1,72 @@
+package com.alipay.codequery.coref.model;
+
+import com.alipay.codequery.dal.mybatis.domain.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class Annotation extends Node {
+
+ public Annotation(Long hashId) {
+ super(hashId);
+ }
+
+ public static class AnnotationModel extends Node {
+
+ public AnnotationModel(Long hashId) {
+ super(hashId);
+ }
+
+ public Identifier name;
+ public String qualifiedName;
+ public Node resolveAnnotationType;
+
+ public AnnotationCanResolved extractAnnotationCanResolved() {
+ return new AnnotationCanResolved(this.hashId, this.name.name, this.resolveAnnotationType.hashId, this.location.hashId, this.debug_message, this.parent.hashId);
+ }
+
+ public AnnotationCanNotResolved extractAnnotationCanNotResolved() {
+ return new AnnotationCanNotResolved(this.hashId, this.qualifiedName, this.location.hashId, this.debug_message, this.parent.hashId);
+ }
+
+ public AnnotationDeclaration extractAnnotationDeclaration() {
+ return new AnnotationDeclaration(this.hashId, this.qualifiedName);
+ }
+ }
+
+ public static class AnnotationArgument extends Annotation {
+
+ public com.alipay.codequery.coref.model.Expression kind;
+ public Expression value;
+ public int index;
+
+ public AnnotationArgument(Long hashId) {
+ super(hashId);
+ }
+
+ public AnnotationAccessArgumentWithName extractAnnotationArgumentWithName() {
+ return new AnnotationAccessArgumentWithName(this.hashId, this.parent.hashId, this.kind.hashId, this.value.hashId, this.location.hashId, this.index, this.debug_message);
+ }
+
+ public AnnotationAccessArgumentWithoutName extractAnnotationArgumentWithoutName() {
+ return new AnnotationAccessArgumentWithoutName(this.hashId, this.parent.hashId, this.value.hashId, this.location.hashId, this.index, this.debug_message);
+ }
+ }
+
+ public static class AnnotationParameter extends Method {
+ public Type type;
+ public Identifier name;
+
+ public AnnotationParameter(Long hashId) {
+ super(hashId);
+ }
+
+ public AnnotationDeclarationParameter extractAnnotationArgument() {
+ return new AnnotationDeclarationParameter(this.hashId, this.parent.hashId, this.type.hashId, this.name.hashId, this.location.hashId, this.debug_message);
+ }
+ }
+
+
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Class.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Class.java
new file mode 100644
index 00000000..eb5b4d84
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Class.java
@@ -0,0 +1,79 @@
+package com.alipay.codequery.coref.model;
+
+import com.alipay.codequery.dal.mybatis.domain.*;
+import com.alipay.codequery.dal.mybatis.domain.LocalClass;
+import com.alipay.codequery.dal.mybatis.domain.clazz;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.util.List;
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class Class extends Node {
+ public Class(Long hashId) {
+ super(hashId);
+ }
+
+ public static class ClassDefinition extends Statement {
+
+ public Identifier identifier;
+ public List superclass;
+ public Modifier modifier;
+ public List annotations;
+ public String qualifiedName;
+ public Expression restype;
+ public ClassDefinition implemented;
+
+ public ClassDefinition(Long hashId) {
+ super(hashId);
+ }
+
+ public clazz extractClass() {
+ return new clazz(this.hashId, qualifiedName, identifier.hashId, this.location.hashId, this.parent.hashId);
+ }
+
+ public InterfaceInfo extractInterface() {
+ return new InterfaceInfo(this.hashId, qualifiedName, identifier.hashId, this.location.hashId, this.parent.hashId);
+ }
+
+ public LocalClass extractLocalClass() {
+ return new LocalClass(this.hashId, this.identifier.name, this.debug_message, this.location.hashId, this.parent.hashId);
+ }
+
+ }
+
+ public static class AnonymousClass extends ClassDefinition {
+ public ClassDefinition baseClass;
+ public Type baseType;
+
+ public AnonymousClass(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.AnonymousClass extractAnonymousClass() {
+ return new com.alipay.codequery.dal.mybatis.domain.AnonymousClass(this.hashId, this.baseClass.hashId, this.baseType.hashId, this.location.hashId, this.parent.hashId);
+ }
+ }
+
+
+ public static class ClassHierarchy extends Node {
+ public Long child;
+ public Long parent;
+
+ public ClassHierarchy() {
+ super();
+ }
+
+ public ClassHierarchy (Long childId, Long parentId) {
+ this.child = childId;
+ this.parent = parentId;
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.ClassHierarchy extractClassHierarchy() {
+ return new com.alipay.codequery.dal.mybatis.domain.ClassHierarchy(child, parent);
+ }
+ }
+
+
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Comment.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Comment.java
new file mode 100644
index 00000000..43b89369
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Comment.java
@@ -0,0 +1,78 @@
+package com.alipay.codequery.coref.model;
+
+import com.alipay.codequery.dal.mybatis.domain.JavadocComment;
+import com.alipay.codequery.dal.mybatis.domain.JavadocDataToken;
+import com.alipay.codequery.dal.mybatis.domain.JavadocTag;
+import com.alipay.codequery.dal.mybatis.domain.JavadocTagValue;
+
+public class Comment extends Node {
+
+ public String text;
+ public String commentType;
+
+ public Comment(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.Comment extractComment() {
+ return new com.alipay.codequery.dal.mybatis.domain.Comment(this.hashId, this.text, this.parent.hashId, this.location.hashId, this.commentType);
+ }
+
+ public static class JavaDocComment extends Comment {
+
+ public String text;
+ public Node documentedItem;
+ public int index;
+
+ public JavaDocComment(Long hashId) {
+ super(hashId);
+ }
+
+ public JavadocComment extractJavaDocComment() {
+ return new JavadocComment(this.hashId, this.documentedItem.hashId, this.text, this.location.hashId, this.parent.hashId);
+ }
+ }
+
+ public static class JavaDocTag extends JavaDocComment {
+
+ public String name;
+ public String value;
+ public Comment containedComment;
+
+ public JavaDocTag(Long hashId) {
+ super(hashId);
+ }
+
+ public JavadocTag extractJavadocTag() {
+ return new JavadocTag(this.hashId, this.name, this.value, this.containedComment.hashId, this.index, this.location.hashId);
+ }
+ }
+
+ /**
+ * Model for JavaDocTagValue element.
+ */
+ public static class JavaDocTagValue extends JavaDocTag {
+ public JavaDocTagValue(Long hashId) {
+ super(hashId);
+ }
+
+ public JavadocTagValue extractJavaDocTagValue() {
+ return new JavadocTagValue(this.hashId, this.value, this.parent.hashId, this.location.getHashId());
+ }
+ }
+
+ /**
+ * Model for JavaDocDataToken element.
+ */
+ public static class JavaDocDataToken extends JavaDocTag {
+
+ public JavaDocDataToken(Long hashId) {
+ super(hashId);
+ }
+
+ public JavadocDataToken extractJavaDocDataToken() {
+ return new JavadocDataToken(this.hashId, this.value, this.parent.hashId, this.index, this.location.getHashId());
+ }
+ }
+
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Constructor.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Constructor.java
new file mode 100644
index 00000000..4e2c4287
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Constructor.java
@@ -0,0 +1,13 @@
+package com.alipay.codequery.coref.model;
+
+public class Constructor extends Method {
+ public int isConstructor;
+
+ public Constructor(int id, Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.Constructor extractConstructor(){
+ return new com.alipay.codequery.dal.mybatis.domain.Constructor(this.hashId, this.identifier.name, this.signature,this.parent.hashId,this.location.hashId, this.definitionBody);
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Containers.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Containers.java
new file mode 100644
index 00000000..c01fa371
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Containers.java
@@ -0,0 +1,8 @@
+package com.alipay.codequery.coref.model;
+
+
+public class Containers extends Node {
+ public Containers(Long hashId) {
+ super(hashId);
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Expression.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Expression.java
new file mode 100644
index 00000000..6f60ee3e
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Expression.java
@@ -0,0 +1,408 @@
+package com.alipay.codequery.coref.model;
+
+import com.alipay.codequery.dal.mybatis.domain.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class Expression extends Node {
+
+ public Expression(Long hashId) {
+ super(hashId);
+ }
+
+ public String baseName;
+
+ public int index;
+ public Type type;
+
+ public com.alipay.codequery.dal.mybatis.domain.Expression extractExpression() {
+ return new com.alipay.codequery.dal.mybatis.domain.Expression(this.hashId, this.baseName, this.parent.hashId, this.index, this.location.hashId, this.debug_message);
+ }
+
+ public ReferenceExpression extractReferenceExpression() {
+ return new ReferenceExpression(this.hashId);
+ }
+
+ public ReferenceElement extractReferenceElement() {
+ return new ReferenceElement(this.hashId, this.debug_message, this.parent.hashId, this.location.hashId);
+ }
+
+ public ImportStaticReferenceElement extractImportStaticReferenceElement() {
+ return new ImportStaticReferenceElement(this.hashId, this.debug_message, this.parent.hashId, this.location.hashId);
+ }
+
+ public ClassInitializer extractClassInitializer() {
+ return new ClassInitializer(this.hashId, this.debug_message, this.parent.hashId, this.location.hashId);
+ }
+
+
+ public static class ReferenceList extends ExpressionList {
+ public String role;
+
+ public ReferenceList(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.ReferenceList extractReferenceList() {
+ return new com.alipay.codequery.dal.mybatis.domain.ReferenceList(this.hashId, this.location.hashId, this.parent.hashId, this.debug_message, this.role);
+ }
+ }
+
+ public static class ExpressionList extends Expression {
+ public List subexps = new ArrayList<>();
+ public Expression list;
+
+ public ExpressionList(Long hashId) {
+ super(hashId);
+ }
+
+ public int indexOrder;
+ public Type type;
+ public int size;
+
+ public com.alipay.codequery.dal.mybatis.domain.ExpressionList extractExpressionList() {
+ return new com.alipay.codequery.dal.mybatis.domain.ExpressionList(this.hashId, this.parent.hashId, this.location.hashId, this.debug_message, size);
+ }
+
+ public ReferenceExpression extractReferenceExpression() {
+ return new ReferenceExpression(this.hashId);
+ }
+ }
+
+ public static class FieldAccess extends Expression {
+
+ public FieldAccess(int id, Long hashId) {
+ super(hashId);
+ }
+
+ public String name;
+ }
+
+ public static class InstanceOfExpression extends Expression {
+ public InstanceOfExpression(Long hashId) {
+ super(hashId);
+ }
+
+ public Expression operand;
+ public Expression checkType;
+ public Expression pattern;
+
+ public InstanceofExpression extractInstanceOfExpression() {
+ return new InstanceofExpression(this.hashId, this.operand.hashId, this.checkType.hashId, this.pattern.hashId);
+ }
+ }
+
+ public static class ArrayExpression extends Expression {
+
+ public ArrayExpression(Long hashId) {
+ super(hashId);
+ }
+
+ List elements;
+ }
+
+ public static class ArrayAccessExpression extends Expression {
+ public ArrayExpression arrayExpression;
+ public Expression indexExpression;
+
+ public ArrayAccessExpression(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.ArrayAccessExpression extractArrayAccessExpression() {
+ return new com.alipay.codequery.dal.mybatis.domain.ArrayAccessExpression(this.hashId, this.indexExpression.hashId, this.arrayExpression.hashId);
+ }
+
+ }
+
+
+ public static class InvokeExpression extends Expression {
+
+ public InvokeExpression(Long hashId) {
+ super(hashId);
+ }
+
+ public Expression callee;
+ public Identifier identifier;
+ public List args = new ArrayList<>();
+
+ public CallableBinding extractCallableBinding() {
+ return new CallableBinding(this.hashId, this.callee.hashId);
+ }
+ }
+
+ public static class CallExpression extends InvokeExpression {
+
+ public CallExpression(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.NewExpression extractNewExpression() {
+ return new com.alipay.codequery.dal.mybatis.domain.NewExpression(this.hashId, this.callee.hashId, this.type.hashId);
+ }
+ }
+
+ public static class MethodCallExpression extends CallExpression {
+
+ public MethodCallExpression(Long hashId) {
+ super(hashId);
+ }
+
+ public Expression reference;
+
+ public ReferenceList argumentList;
+
+ public int isConstructor;
+
+ public MethodAccessExpressionWithoutType extractMethodAccessExpressionWithoutType() {
+ return new MethodAccessExpressionWithoutType(this.hashId, this.reference.hashId, argumentList.hashId);
+ }
+
+ public MethodAccessExpressionWithType extractMethodAccessExpressionWithType() {
+ return new MethodAccessExpressionWithType(this.hashId, this.type.hashId, reference.hashId, argumentList.hashId);
+ }
+
+ public MethodReferenceExpression extractMethodReferenceExpression() {
+ return new MethodReferenceExpression(this.hashId, this.isConstructor);
+ }
+
+ public SuperAccessExpression extractSuperAccessExpression() {
+ return new SuperAccessExpression(this.hashId);
+ }
+
+ public SuperConstructorInvocation extractSuperConstructorInvocation() {
+ return new SuperConstructorInvocation(this.hashId);
+ }
+
+ }
+
+
+ public static class NewExpression extends CallExpression {
+
+ public NewExpression(Long hashId) {
+ super(hashId);
+ }
+
+ public Expression qualifier;
+ public Expression reference;
+ public int dimension;
+
+ public com.alipay.codequery.dal.mybatis.domain.NewExpression extractNewExpression() {
+ return new com.alipay.codequery.dal.mybatis.domain.NewExpression(this.hashId, this.reference.hashId, this.type.hashId);
+ }
+
+ public ArrayCreationExpression extractArrayCreationExpression() {
+ return new ArrayCreationExpression(this.hashId, this.dimension, this.type.hashId);
+ }
+
+ public ConstructorInvocation extractConstructorInvocation() {
+ return new ConstructorInvocation(this.hashId, this.reference.hashId);
+ }
+
+ }
+
+ public static class CastExpression extends Expression {
+ public Expression operand;
+ public CastExpression(Long hashId) {
+ super(hashId);
+ }
+
+ public TypeCastExpression extractTypeCastExpressiont() {
+ return new TypeCastExpression(this.hashId, this.operand.hashId);
+ }
+ }
+
+ public static class UnaryExpression extends Expression {
+
+ public UnaryExpression(Long hashId) {
+ super(hashId);
+ }
+
+ public Expression operand;
+ public String opcode;
+ public int isPostfix;
+
+ public com.alipay.codequery.dal.mybatis.domain.UnaryExpression extractUnaryExpression() {
+ return new com.alipay.codequery.dal.mybatis.domain.UnaryExpression(this.hashId, this.operand.hashId, this.opcode, this.isPostfix);
+ }
+
+ }
+
+ public static class UnaryOperator extends UnaryExpression {
+
+ public UnaryOperator(int id, Long hashId) {
+ super(hashId);
+ }
+ }
+
+ public static class UpdateExpression extends Expression {
+
+ public UpdateExpression(int id, Long hashId) {
+ super(hashId);
+ }
+ }
+
+ public static class UpdateOperator extends UpdateExpression {
+
+ public UpdateOperator(int id, Long hashId) {
+ super(id, hashId);
+ }
+ }
+
+ public static class PolyadicExpression extends Expression {
+
+ public PolyadicExpression(Long hashId) {
+ super(hashId);
+ }
+
+ public int size;
+ public String opcode;
+
+ public com.alipay.codequery.dal.mybatis.domain.PolyadicExpression extractPolyadicExpression() {
+ return new com.alipay.codequery.dal.mybatis.domain.PolyadicExpression(this.hashId, this.size, this.opcode);
+ }
+ }
+
+ public static class BinaryExpression extends PolyadicExpression {
+
+ public BinaryExpression(Long hashId) {
+ super(hashId);
+ }
+
+ public Expression lhs;
+ public Expression rhs;
+ public String opcode;
+
+ public com.alipay.codequery.dal.mybatis.domain.BinaryExpression extractBinaryExpression() {
+ return new com.alipay.codequery.dal.mybatis.domain.BinaryExpression(this.hashId, this.lhs.hashId, this.rhs.hashId, this.opcode);
+ }
+ }
+
+ public static class BinaryOperator extends Expression {
+
+ public BinaryOperator(int id, Long hashId) {
+ super(hashId);
+ }
+
+ public Expression opcode;
+ }
+
+ public static class AssignmentExpression extends Expression {
+
+ public AssignmentExpression(Long hashId) {
+ super(hashId);
+ }
+
+ public Expression lhs;
+ public Expression rhs;
+ public String opcode;
+
+ public com.alipay.codequery.dal.mybatis.domain.AssignmentExpression extractAssignmentExpression() {
+ return new com.alipay.codequery.dal.mybatis.domain.AssignmentExpression(this.hashId, this.lhs.hashId, this.rhs.hashId, this.opcode);
+ }
+ }
+
+ public static class AssignmentOperator extends Expression {
+
+ public AssignmentOperator(int id, Long hashId) {
+ super(hashId);
+ }
+ }
+
+ public static class LambdaExpression extends Expression {
+
+ public LambdaExpression(Long hashId) {
+ super(hashId);
+ }
+
+ public Statement body;
+ public Expression paramterList;
+ public int isVoidCompatible;
+ public int isValueCompatible;
+
+ public com.alipay.codequery.dal.mybatis.domain.LambdaExpression extractLambdaExpression() {
+ return new com.alipay.codequery.dal.mybatis.domain.LambdaExpression(this.hashId, this.paramterList.hashId, this.body.hashId, this.isVoidCompatible, this.isValueCompatible);
+ }
+
+ }
+
+ public static class ThisExpression extends Expression {
+
+ public ThisExpression(Long hashId) {
+ super(hashId);
+ }
+
+ public Expression qualifier;
+ public Expression reference;
+
+ public ThisAccessExpression extractThisAccessExpression() {
+ return new ThisAccessExpression(this.hashId);
+ }
+
+ public ThisExpressionWithQualifier extractThisExpressionWithQualifier() {
+ return new ThisExpressionWithQualifier(this.hashId, this.qualifier.hashId);
+ }
+ }
+
+
+ public static class SuperExpression extends Expression {
+
+ public SuperExpression(Long hashId) {
+ super(hashId);
+ }
+
+ public Expression qualifier;
+
+ public com.alipay.codequery.dal.mybatis.domain.SuperExpression extractSuperExpression() {
+ return new com.alipay.codequery.dal.mybatis.domain.SuperExpression(this.hashId);
+ }
+
+ public SuperExpressionWithQualifier extractSuperExpressionWithQualifier() {
+ return new SuperExpressionWithQualifier(this.hashId, qualifier.hashId);
+ }
+
+ public SuperAccessExpression extractSuperAccessExpression() {
+ return new SuperAccessExpression(this.hashId);
+ }
+
+ }
+
+ public static class ConditionalExpression extends Expression {
+
+ public ConditionalExpression(Long hashId) {
+ super(hashId);
+ }
+
+ public Expression condition;
+ public Expression thenExpression;
+ public Expression elseExpression;
+
+ public com.alipay.codequery.dal.mybatis.domain.ConditionalExpression extractCondtionalExpression() {
+ return new com.alipay.codequery.dal.mybatis.domain.ConditionalExpression(this.hashId, this.condition.hashId, this.thenExpression.hashId, this.elseExpression.hashId);
+ }
+
+ }
+
+ public static class ArrayInitializationExpression extends Expression {
+
+ public ArrayInitializationExpression(Long hashId) {
+ super(hashId);
+ }
+
+ public Expression initializer;
+
+ public ArrayInitializerExpression extractArrayInitializerExpression() {
+
+ return new ArrayInitializerExpression(this.hashId, this.type.hashId);
+ }
+
+
+ public AnnotationArrayInitializer extractAnnotationArrayInitializer() {
+
+ return new AnnotationArrayInitializer(this.hashId, this.debug_message, this.parent.hashId, this.location.hashId);
+ }
+ }
+
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Field.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Field.java
new file mode 100644
index 00000000..d8fbdc0f
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Field.java
@@ -0,0 +1,19 @@
+package com.alipay.codequery.coref.model;
+
+import com.alipay.codequery.dal.mybatis.domain.EnumConstant;
+
+
+public class Field extends Variable {
+
+ public Field(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.Field extractField() {
+ return new com.alipay.codequery.dal.mybatis.domain.Field(this.hashId, this.name, this.parent.hashId, this.debug_message, this.location.hashId);
+ }
+
+ public EnumConstant extractEnumConstant() {
+ return new EnumConstant(this.hashId, this.name, this.parent.hashId, this.location.hashId, this.debug_message);
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/File.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/File.java
new file mode 100644
index 00000000..34395939
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/File.java
@@ -0,0 +1,21 @@
+package com.alipay.codequery.coref.model;
+
+
+public class File extends Containers{
+
+ public String qualifiedName;
+ public String extension;
+ public String name;
+ public Program program;
+ public Location.NumberOfLines numberOfLines;
+
+ public com.alipay.codequery.dal.mybatis.domain.File extractFile(){
+ return new com.alipay.codequery.dal.mybatis.domain.File(this.hashId,this.qualifiedName,this.extension,this.name, this.numberOfLines.hashId);
+ }
+
+ public File(Long hashId) {
+ super(hashId);
+ }
+
+
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Folder.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Folder.java
new file mode 100644
index 00000000..264c1eb5
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Folder.java
@@ -0,0 +1,15 @@
+package com.alipay.codequery.coref.model;
+
+
+public class Folder extends Containers{
+ public String qualifiedName;
+ public String name;
+
+ public Folder(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.Folder extractFolder(){
+ return new com.alipay.codequery.dal.mybatis.domain.Folder(this.hashId,this.qualifiedName,this.name, this.parent.hashId);
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Identifier.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Identifier.java
new file mode 100644
index 00000000..76687d53
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Identifier.java
@@ -0,0 +1,16 @@
+package com.alipay.codequery.coref.model;
+
+
+public class Identifier extends Node {
+
+ public Identifier(String name, Long hashId) {
+ super(hashId);
+ this.name = name;
+ this.hashId = hashId;
+ }
+ public String name;
+
+ public com.alipay.codequery.dal.mybatis.domain.Identifier extractIdentifier(){
+ return new com.alipay.codequery.dal.mybatis.domain.Identifier(this.hashId,this.location.hashId,this.name,this.parent.hashId);
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Literal.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Literal.java
new file mode 100644
index 00000000..e4d9bd64
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Literal.java
@@ -0,0 +1,18 @@
+package com.alipay.codequery.coref.model;
+
+
+import com.alipay.codequery.dal.mybatis.domain.StringLiteral;
+
+public class Literal extends Expression {
+
+ public Literal(Long hashId) {
+ super(hashId);
+ }
+
+ public Object value;
+ public String type;
+
+ public StringLiteral extractLiteral() {
+ return new StringLiteral(this.hashId, this.value.toString());
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/LocalVariable.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/LocalVariable.java
new file mode 100644
index 00000000..10e377b0
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/LocalVariable.java
@@ -0,0 +1,13 @@
+package com.alipay.codequery.coref.model;
+
+
+public class LocalVariable extends Variable {
+
+ public LocalVariable(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.LocalVariable extractLocalVariable(){
+ return new com.alipay.codequery.dal.mybatis.domain.LocalVariable(this.hashId, this.parent.hashId, this.location.hashId, this.debug_message, this.name, this.index);
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Location.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Location.java
new file mode 100644
index 00000000..1bbcbbd4
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Location.java
@@ -0,0 +1,59 @@
+package com.alipay.codequery.coref.model;
+
+public class Location extends Node {
+
+ public File file;
+ public int startLineNumber;
+ public int startColumnNumber;
+ public int endLineNumber;
+ public int endColumnNumber;
+ public LocalLocation localLocation;
+ public NumberOfLines numberOfLines;
+
+ public Location(Long hashId) {
+ super(hashId);
+ }
+
+ public Location() {
+ }
+
+ public Location(Long hashId, File file, LocalLocation localLocation) {
+ this.hashId = hashId;
+ this.file = file;
+ this.startLineNumber = localLocation.startLineNumber;
+ this.startColumnNumber = localLocation.startColumnNumber;
+ this.endLineNumber = localLocation.endLineNumber;
+ this.endColumnNumber = localLocation.endColumnNumber;
+ }
+ public com.alipay.codequery.dal.mybatis.domain.Location extractLocation(){
+ return new com.alipay.codequery.dal.mybatis.domain.Location(
+ this.hashId,
+ this.file.hashId,
+ this.startLineNumber,
+ this.startColumnNumber,
+ this.endLineNumber,
+ this.endColumnNumber);
+ }
+ public static class LocalLocation extends Location {
+ public LocalLocation(int startLineNumber,int startColumnNumber, int endLineNumber, int endColumnNumber){
+ this.startLineNumber = startLineNumber;
+ this.startColumnNumber = startColumnNumber;
+ this.endLineNumber = endLineNumber;
+ this.endColumnNumber = endColumnNumber;
+ }
+ }
+
+ public static class NumberOfLines extends Location {
+ public int numberOfLines;
+ public int numberOfCommentLines;
+ public int numberOfCodeLines;
+
+ public NumberOfLines(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.NumberOfLines extractNumberOfLines(){
+ return new com.alipay.codequery.dal.mybatis.domain.NumberOfLines(this.hashId, this.numberOfLines,this.numberOfCodeLines,this.numberOfCommentLines);
+ }
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Method.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Method.java
new file mode 100644
index 00000000..01ad5c1f
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Method.java
@@ -0,0 +1,24 @@
+package com.alipay.codequery.coref.model;
+
+import com.alipay.codequery.dal.mybatis.domain.Constructor;
+
+
+public class Method extends Node {
+ public Identifier identifier;
+ public Type returnType;
+ public String signature;
+ public String definitionBody;
+
+ public Method(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.Method extractMethodDeclaration() {
+ return new com.alipay.codequery.dal.mybatis.domain.Method(this.hashId, identifier.name, signature, this.returnType.hashId, parent.hashId, this.location.hashId, this.definitionBody);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.Constructor extractConstructor() {
+ return new Constructor(this.hashId, identifier.name, signature, parent.hashId, this.location.hashId, this.definitionBody);
+ }
+
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Modifier.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Modifier.java
new file mode 100644
index 00000000..94f889ff
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Modifier.java
@@ -0,0 +1,42 @@
+package com.alipay.codequery.coref.model;
+
+import com.alipay.codequery.dal.mybatis.domain.ModifierList;
+
+
+public class Modifier extends Node {
+ String PUBLIC = "public";
+ String PROTECTED = "protected";
+ String PRIVATE = "private";
+ String PACKAGE_LOCAL = "packageLocal";
+ String STATIC = "static";
+ String ABSTRACT = "abstract";
+ String FINAL = "final";
+ String NATIVE = "native";
+ String SYNCHRONIZED = "synchronized";
+ String STRICTFP = "strictfp";
+ String TRANSIENT = "transient";
+ String VOLATILE = "volatile";
+ String DEFAULT = "default";
+ String OPEN = "open";
+ String TRANSITIVE = "transitive";
+ String SEALED = "sealed";
+ String NON_SEALED = "non-sealed";
+
+ String[] MODIFIERS = {
+ PUBLIC, PROTECTED, PRIVATE, STATIC, ABSTRACT, FINAL, NATIVE, SYNCHRONIZED, STRICTFP, TRANSIENT, VOLATILE, DEFAULT, OPEN, TRANSITIVE, SEALED, NON_SEALED
+ };
+
+ public Modifier(Long hashId) {
+ super(hashId);
+ }
+
+ public String name;
+
+ public com.alipay.codequery.dal.mybatis.domain.Modifier extractModifier(){
+ return new com.alipay.codequery.dal.mybatis.domain.Modifier(this.hashId, name,this.parent.hashId,this.location.hashId);
+ }
+
+ public ModifierList extractModifierList(){
+ return new ModifierList(this.hashId,this.parent.hashId,this.location.hashId);
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Module.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Module.java
new file mode 100644
index 00000000..2988ea3d
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Module.java
@@ -0,0 +1,12 @@
+package com.alipay.codequery.coref.model;
+
+
+public class Module extends Node {
+ public Module(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.Module extractModule(){
+ return new com.alipay.codequery.dal.mybatis.domain.Module(this.hashId,this.debug_message);
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Node.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Node.java
new file mode 100644
index 00000000..634cf999
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Node.java
@@ -0,0 +1,24 @@
+package com.alipay.codequery.coref.model;
+
+import lombok.Data;
+
+
+@Data
+public class Node {
+
+ public Location location;
+ public String debug_message;
+ public Long hashId;
+ public Type type;
+ public Node parent;
+
+ public Node(Long hashId) {
+ this.hashId = hashId;
+ }
+
+ public Node() {
+ }
+
+}
+
+
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/NpClass.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/NpClass.java
new file mode 100644
index 00000000..bf297087
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/NpClass.java
@@ -0,0 +1,14 @@
+package com.alipay.codequery.coref.model;
+
+public class NpClass extends Node {
+ public String name;
+ public String qualifiedName;
+
+ public NpClass(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.NpClass extractNpClass() {
+ return new com.alipay.codequery.dal.mybatis.domain.NpClass(hashId, name, qualifiedName, parent.hashId);
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/NpFile.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/NpFile.java
new file mode 100644
index 00000000..310c7093
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/NpFile.java
@@ -0,0 +1,16 @@
+package com.alipay.codequery.coref.model;
+
+public class NpFile extends Node {
+ public String qualifiedName;
+ public String extension;
+ public String name;
+ public Long projectId;
+
+ public NpFile(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.NpFile extractNpFile() {
+ return new com.alipay.codequery.dal.mybatis.domain.NpFile(hashId, qualifiedName, name, projectId);
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/NpInterface.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/NpInterface.java
new file mode 100644
index 00000000..407493c0
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/NpInterface.java
@@ -0,0 +1,15 @@
+package com.alipay.codequery.coref.model;
+
+public class NpInterface extends Node {
+ public String name;
+ public String qualifiedName;
+ public String extension;
+
+ public NpInterface(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.NpInterface extractNpInterface() {
+ return new com.alipay.codequery.dal.mybatis.domain.NpInterface(hashId, name, qualifiedName, parent.hashId);
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/NpMethod.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/NpMethod.java
new file mode 100644
index 00000000..a18e6ed5
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/NpMethod.java
@@ -0,0 +1,15 @@
+package com.alipay.codequery.coref.model;
+
+public class NpMethod extends Node {
+ public String name;
+ public Type returnType;
+ public String signature;
+
+ public NpMethod(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.NpMethod extractNpMethod() {
+ return new com.alipay.codequery.dal.mybatis.domain.NpMethod(this.hashId, name, signature, this.returnType.hashId, parent.hashId);
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/NpProject.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/NpProject.java
new file mode 100644
index 00000000..5f5685f4
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/NpProject.java
@@ -0,0 +1,14 @@
+package com.alipay.codequery.coref.model;
+
+public class NpProject extends Node {
+ public String extension;
+ public String name;
+
+ public NpProject(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.NpProject extractNpProject() {
+ return new com.alipay.codequery.dal.mybatis.domain.NpProject(hashId, extension, name);
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Package.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Package.java
new file mode 100644
index 00000000..4e60ffb1
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Package.java
@@ -0,0 +1,10 @@
+package com.alipay.codequery.coref.model;
+
+
+public class Package extends Node {
+ public String packageName;
+
+ public Package(Long hashId) {
+ super(hashId);
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Parameter.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Parameter.java
new file mode 100644
index 00000000..124d7c73
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Parameter.java
@@ -0,0 +1,14 @@
+package com.alipay.codequery.coref.model;
+
+
+public class Parameter extends Variable {
+ public int index;
+
+ public Parameter(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.Parameter extractParameter() {
+ return new com.alipay.codequery.dal.mybatis.domain.Parameter(this.hashId, this.name, this.index, this.parent.hashId, this.location.hashId, this.debug_message, this.type.hashId);
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/ParameterList.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/ParameterList.java
new file mode 100644
index 00000000..594b5f44
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/ParameterList.java
@@ -0,0 +1,34 @@
+package com.alipay.codequery.coref.model;
+
+import com.alipay.codequery.dal.mybatis.domain.EmptyReferenceParameterList;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class ParameterList extends Node{
+ public ParameterList(Long hashId) {
+ super(hashId);
+ }
+
+ public static class ReferenceParameterList extends ParameterList {
+
+ public Type[] types;
+
+ public ReferenceParameterList(Long hashId) {
+ super(hashId);
+ }
+
+ public EmptyReferenceParameterList extractEmptyReferenceParameterList() {
+ return new EmptyReferenceParameterList(this.hashId, this.parent.hashId, this.debug_message, this.location.hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.ReferenceParameterList extractReferenceParameterList(int index) {
+
+ return new com.alipay.codequery.dal.mybatis.domain.ReferenceParameterList(types[index].hashId, this.hashId, index, this.parent.hashId, this.debug_message, this.location.hashId);
+
+ }
+ }
+}
+
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Parent.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Parent.java
new file mode 100644
index 00000000..8517c5a4
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Parent.java
@@ -0,0 +1,21 @@
+package com.alipay.codequery.coref.model;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+
+@EqualsAndHashCode(callSuper = true)
+@Data
+public class Parent extends Node {
+ public Long childId;
+ public String parentType;
+
+ public Parent(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.Parent extractParent(){
+ return new com.alipay.codequery.dal.mybatis.domain.Parent(this.hashId,this.parentType);
+
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Primitive.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Primitive.java
new file mode 100644
index 00000000..5091db62
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Primitive.java
@@ -0,0 +1,25 @@
+package com.alipay.codequery.coref.model;
+
+
+public class Primitive extends Type {
+
+ public String value;
+
+ public Primitive(Long hashId) {
+ super(hashId);
+ }
+
+ public enum PrimitiveType {
+ BYTE,
+ CHAR,
+ DOUBLE,
+ FLOAT,
+ INT,
+ LONG,
+ SHORT,
+ BOOLEAN,
+ VOID,
+ NULL
+ }
+
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Program.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Program.java
new file mode 100644
index 00000000..936be768
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Program.java
@@ -0,0 +1,22 @@
+package com.alipay.codequery.coref.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class Program extends Node {
+
+ public List list = new ArrayList();
+
+ // FIXME: the correct concept is root.
+ // FIXME: rootdir should be in some table like Debug/Job Information
+ public String prefix = "";
+
+ public Program(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.Program extractProgram(){
+ return new com.alipay.codequery.dal.mybatis.domain.Program(this.hashId, this.prefix);
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Statement.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Statement.java
new file mode 100644
index 00000000..6aec97c8
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Statement.java
@@ -0,0 +1,402 @@
+package com.alipay.codequery.coref.model;
+
+import com.alipay.codequery.dal.mybatis.domain.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class Statement extends Node{
+
+ public String baseName;
+
+ public Statement(Long hashId) {
+ super(hashId);
+ }
+ public int index;
+
+ public com.alipay.codequery.dal.mybatis.domain.Statement extractStatement(){
+ return new com.alipay.codequery.dal.mybatis.domain.Statement(this.hashId,this.parent.hashId,this.index,this.location.hashId,this.debug_message, this.baseName);
+ }
+
+ public static class ExpressionStatement extends Statement {
+
+ public ExpressionStatement(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.coref.model.Expression expr;
+
+ public com.alipay.codequery.dal.mybatis.domain.ExpressionStatement extractExpressionStatement(){
+ return new com.alipay.codequery.dal.mybatis.domain.ExpressionStatement(this.hashId, this.expr.hashId);
+ }
+ }
+
+ public static class BlockStatement extends Statement {
+
+ public BlockStatement(Long hashId) {
+ super(hashId);
+ }
+
+ public List stats = new ArrayList<>();
+
+ public CodeBlock codeBlock;
+ public com.alipay.codequery.dal.mybatis.domain.BlockStatement extractBlockStatement(){
+ return new com.alipay.codequery.dal.mybatis.domain.BlockStatement(this.hashId, this.codeBlock.hashId);
+ }
+ }
+
+ public static class CodeBlock extends Node {
+
+ public CodeBlock(Long hashId) {
+ super(hashId);
+ }
+
+ public List stats = new ArrayList<>();
+ public int count;
+ public int isEmpty;
+
+ public com.alipay.codequery.dal.mybatis.domain.CodeBlock extractCodeBlock(){
+ return new com.alipay.codequery.dal.mybatis.domain.CodeBlock(this.hashId, this.count, this.parent.hashId, this.isEmpty,this.location.hashId,this.debug_message);
+ }
+ }
+
+ public static class ControlStatement extends Statement {
+
+ public ControlStatement(Long hashId) {
+ super(hashId);
+ }
+ }
+
+ public static class ConstructorCallStatement extends Statement {
+
+ public ConstructorCallStatement(Long hashId) {
+ super(hashId);
+ }
+ public Constructor constructor;
+
+ }
+
+ public static class ImportStatement extends Statement {
+
+ public ImportStatement(Long hashId) {
+ super(hashId);
+ }
+
+ public Statement reference;
+ public String referenceName;
+ public int isForeignImport;
+
+ public ImportStaticStatement extractImportStaticStatement(){
+ return new ImportStaticStatement(this.hashId,this.reference.hashId,this.debug_message,this.parent.hashId,this.location.hashId);
+ }
+
+ public ImportInfo extractImport(){
+ return new ImportInfo( this.hashId,this.reference.hashId, this.debug_message,this.parent.hashId,this.location.hashId, this.isForeignImport);
+ }
+
+ }
+
+ public static class ContinueStatement extends Statement {
+
+ public ContinueStatement(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.coref.model.Identifier discriminant;
+ public Statement continuedStatement;
+
+ public com.alipay.codequery.dal.mybatis.domain.ContinueStatement extractContinueStatement(){
+ return new com.alipay.codequery.dal.mybatis.domain.ContinueStatement(this.hashId,this.continuedStatement.hashId);
+ }
+
+ }
+
+ public static class BreakStatement extends Statement {
+
+ public BreakStatement(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.coref.model.Identifier discriminant;
+ public Statement exitedStatemnt;
+
+ public com.alipay.codequery.dal.mybatis.domain.BreakStatement extractBreakStatement(){
+ return new com.alipay.codequery.dal.mybatis.domain.BreakStatement(this.hashId, this.exitedStatemnt.hashId);
+ }
+
+ }
+
+ public static class EmptyStatement extends Statement {
+
+ public EmptyStatement(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.EmptyStatement extractEmptyStatement(){
+ return new com.alipay.codequery.dal.mybatis.domain.EmptyStatement( this.hashId);
+ }
+
+ }
+
+ public static class LabeledStatement extends Statement {
+
+ public LabeledStatement(Long hashId) {
+ super(hashId);
+ }
+
+ public Identifier identifier;
+ public Statement statement;
+
+ public com.alipay.codequery.dal.mybatis.domain.LabeledStatement extractLabeledStatement(){
+ return new com.alipay.codequery.dal.mybatis.domain.LabeledStatement( this.hashId,this.identifier.hashId, this.statement.hashId);
+ }
+
+ }
+
+
+ public static class IfStatement extends ControlStatement {
+
+ public IfStatement(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.coref.model.Expression condition;
+ public Statement thenBranch;
+ public Statement elseBranch;
+
+ public IfStatementWithElse extractIfStatementWithElse(){
+ return new IfStatementWithElse(this.hashId, condition.hashId, thenBranch.hashId, elseBranch.hashId);
+ }
+
+ public IfStatementWithoutElse extractIfStatementWithoutElse(){
+ return new IfStatementWithoutElse(this.hashId, condition.hashId, thenBranch.hashId);
+ }
+ }
+ public static class SwitchStatement extends ControlStatement {
+
+ public SwitchStatement(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.coref.model.Expression discriminant;
+ public BlockStatement body;
+
+ public com.alipay.codequery.dal.mybatis.domain.SwitchStatement extractSwitchStatement(){
+ return new com.alipay.codequery.dal.mybatis.domain.SwitchStatement(this.hashId, this.discriminant.hashId, this.body.hashId);
+ }
+ }
+
+ public static class YieldStatement extends Statement {
+
+ public YieldStatement(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.coref.model.Expression expression;
+ public com.alipay.codequery.coref.model.Expression enclosingExpression;
+
+ public com.alipay.codequery.dal.mybatis.domain.YieldStatement extractYieldStatement(){
+ return new com.alipay.codequery.dal.mybatis.domain.YieldStatement(this.hashId,this.expression.hashId,this.enclosingExpression.hashId);
+ }
+ }
+
+ public static class SynchronizedStatement extends Statement {
+
+ public SynchronizedStatement(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.coref.model.Expression lockExpression;
+ public Statement body;
+
+ public com.alipay.codequery.dal.mybatis.domain.SynchronizedStatement extractSynchronizedStatement(){
+ return new com.alipay.codequery.dal.mybatis.domain.SynchronizedStatement(this.hashId,this.lockExpression.hashId,this.body.hashId);
+ }
+ }
+
+
+ public static class SwitchLabelStatement extends ControlStatement {
+
+ public SwitchLabelStatement(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.coref.model.Expression caseValue;
+ public BlockStatement enclosingSwitchBlock;
+ public long nextSwitchCashHashId = 0;
+
+
+ public com.alipay.codequery.dal.mybatis.domain.SwitchLabelStatement extractSwitchLabelStatement(){
+ return new com.alipay.codequery.dal.mybatis.domain.SwitchLabelStatement(this.hashId,this.caseValue.hashId,this.enclosingSwitchBlock.hashId,this.nextSwitchCashHashId);
+ }
+ }
+ public static class CaseStatement extends ControlStatement {
+
+ public CaseStatement(int id, Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.coref.model.Expression label;
+ public boolean isDefault;
+ public Statement body;
+ }
+ public static class ForStatement extends ControlStatement {
+
+ public ForStatement(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.coref.model.Expression init;
+ public com.alipay.codequery.coref.model.Expression condition;
+ public com.alipay.codequery.coref.model.Expression update;
+ public Statement body;
+
+ public com.alipay.codequery.dal.mybatis.domain.ForStatement extractForStatement(){
+ return new com.alipay.codequery.dal.mybatis.domain.ForStatement( this.hashId,this.init.hashId,this.condition.hashId,this.update.hashId,this.body.hashId);
+ }
+ }
+
+ public static class ForeachStatement extends ControlStatement {
+
+ public ForeachStatement(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.coref.model.Expression iteratedValue;
+ public Parameter iterationParameter;
+ public Statement body;
+
+ public com.alipay.codequery.dal.mybatis.domain.ForeachStatement extractForeachStatement(){
+ return new com.alipay.codequery.dal.mybatis.domain.ForeachStatement(this.hashId,this.iteratedValue.hashId,this.iterationParameter.hashId,this.body.hashId);
+ }
+ }
+ public static class TryStatement extends ControlStatement {
+
+ public TryStatement(Long hashId) {
+ super(hashId);
+ }
+
+ public CodeBlock tryBlock;
+ public CodeBlock catchBlock;
+ public CodeBlock finallyBlock;
+
+ public TryStatementWithoutFinally extractTryStatementWithoutFinally(){
+ return new TryStatementWithoutFinally(this.hashId, this.tryBlock.hashId);
+ }
+
+ public TryStatementWithFinally extractTryStatementWithFinally(){
+ return new TryStatementWithFinally(this.hashId, this.tryBlock.hashId, this.finallyBlock.hashId);
+ }
+
+ }
+ public static class CatchClause extends Node {
+
+ public CatchClause(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.coref.model.Expression param;
+ public TryStatement tryStatement;
+
+ public int index;
+
+ public CatchSection extractCatchSection(){
+ return new CatchSection( this.hashId,this.debug_message,this.param.hashId,this.type.hashId,this.location.hashId,this.tryStatement.hashId, this.index);
+ }
+
+ }
+
+ public static class ThrowStatement extends ControlStatement {
+
+ public ThrowStatement(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.coref.model.Expression exception;
+ public CodeBlock body;
+
+ public com.alipay.codequery.dal.mybatis.domain.ThrowStatement extractThrowStatement(){
+ return new com.alipay.codequery.dal.mybatis.domain.ThrowStatement(this.hashId, this.exception.hashId,this.body.hashId);
+ }
+ }
+ public static class WhileStatement extends ControlStatement {
+
+ public WhileStatement(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.coref.model.Expression condition;
+ public Statement body;
+
+ public com.alipay.codequery.dal.mybatis.domain.WhileStatement extractWhileStatement(){
+ return new com.alipay.codequery.dal.mybatis.domain.WhileStatement(this.hashId,this.condition.hashId,this.body.hashId);
+ }
+ }
+ public static class DoWhileStatement extends ControlStatement {
+
+ public DoWhileStatement(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.coref.model.Expression condition;
+ public Statement body;
+ public String keyword;
+
+ public com.alipay.codequery.dal.mybatis.domain.DoWhileStatement extractDoWhileStatement(){
+ return new com.alipay.codequery.dal.mybatis.domain.DoWhileStatement(this.hashId,this.keyword,this.condition.hashId,this.body.hashId);
+ }
+
+ }
+
+ public static class PackageStatement extends Statement{
+ public Package referencePackage;
+
+ public PackageStatement(Long hashId) {
+ super(hashId);
+ }
+ public com.alipay.codequery.dal.mybatis.domain.PackageStatement extractPackage(){
+ return new com.alipay.codequery.dal.mybatis.domain.PackageStatement(this.hashId, this.debug_message, this.location.hashId, this.referencePackage.hashId,this.parent.hashId);
+ }
+ }
+
+ public static class ReturnStatement extends Statement {
+
+ public ReturnStatement(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.coref.model.Expression returnExpression;
+
+ public com.alipay.codequery.dal.mybatis.domain.ReturnStatement extractReturnStatement(){
+ return new com.alipay.codequery.dal.mybatis.domain.ReturnStatement(this.hashId,this.returnExpression.hashId);
+ }
+ }
+
+ public static class AssertStatement extends Statement {
+
+ public AssertStatement(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.coref.model.Expression condition;
+ public Expression description;
+
+ public com.alipay.codequery.dal.mybatis.domain.AssertStatement extractAssertStatement() {
+ return new com.alipay.codequery.dal.mybatis.domain.AssertStatement( this.hashId, this.condition.hashId, this.description.hashId);
+ }
+ }
+
+ public static class DeclarationStatement extends Statement {
+
+ public DeclarationStatement(Long hashId) {
+ super(hashId);
+ }
+
+ public int index;
+
+ public DeclarationElement extractDeclarationElement() {
+ return new DeclarationElement( this.hashId, this.index, this.parent.hashId);
+ }
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Type.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Type.java
new file mode 100644
index 00000000..d33f7aca
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Type.java
@@ -0,0 +1,85 @@
+package com.alipay.codequery.coref.model;
+
+import com.alipay.codequery.dal.mybatis.domain.*;
+import com.alipay.codequery.dal.mybatis.domain.Primitive;
+
+import java.util.ArrayList;
+
+
+public class Type extends Node {
+ public String name;
+ public String qualifiedName;
+ public int isInferred;
+ public Node innermostComponentReferenceElement;
+
+ public Type(Long hashId) {
+ this.hashId = hashId;
+ }
+
+ public ReferenceType extractReferenceType(){
+ return new ReferenceType(this.hashId, this.name,this.qualifiedName);
+ }
+ public TypeElement extractTypeElement(){
+ return new TypeElement( this.hashId,this.type.hashId,this.debug_message,this.parent.hashId,this.location.hashId);
+ }
+ public enum PrimitiveType {
+ BYTE ("byte", 1),
+ CHAR ("char", 2),
+ DOUBLE ("double", 3),
+ FLOAT ("float", 4),
+ INT ("int", 5),
+ LONG ("long", 6),
+ SHORT ("short", 7),
+ BOOLEAN("boolean", 8),
+ VOID ("void", 9),
+ NULL ("null", 10);
+ public String name;
+ public int index;
+
+ public static ArrayList values =new ArrayList<>();
+
+ PrimitiveType(String name, int index){
+ this.name = name;
+ this.index = index;
+ }
+
+ public Primitive extractPrimitive(){
+ return new Primitive(this.index, this.name);
+ }
+
+ static {
+ for (PrimitiveType value : PrimitiveType.values()) {
+ PrimitiveType.values.add(value);
+ }
+ }
+ }
+
+ public static class TypeLiteral extends Type {
+ public Type type;
+ public Type typeElement;
+
+ public TypeLiteral(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.TypeLiteral extractTypeLiteral(){
+ return new com.alipay.codequery.dal.mybatis.domain.TypeLiteral(this.hashId, this.typeElement.hashId, this.type.hashId);
+ }
+
+ }
+
+ public static class TypeParameter extends Type {
+ public Node owner;
+ public Node extendsList;
+ public int index;
+
+ public TypeParameter(Long hashId) {
+ super(hashId);
+ }
+
+ public com.alipay.codequery.dal.mybatis.domain.TypeParameter extractTypeParameter(){
+ return new com.alipay.codequery.dal.mybatis.domain.TypeParameter(this.hashId,this.debug_message,this.owner.hashId,this.index,this.extendsList.hashId, this.parent.hashId,this.location.hashId);
+ }
+
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Variable.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Variable.java
new file mode 100644
index 00000000..1a07ad84
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/model/Variable.java
@@ -0,0 +1,19 @@
+package com.alipay.codequery.coref.model;
+
+import com.alipay.codequery.dal.mybatis.domain.Array;
+
+
+public class Variable extends Node{
+
+ public Identifier identifier;
+ public String name;
+ public int index;
+
+ public Variable(Long hashId) {
+ super(hashId);
+ }
+
+ public Array extractArray(){
+ return new Array(this.hashId, this.name);
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/Commit.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/Commit.java
new file mode 100644
index 00000000..d1f2cf37
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/Commit.java
@@ -0,0 +1,63 @@
+package com.alipay.codequery.coref.storage;
+
+import com.alibaba.fastjson.JSON;
+import com.alipay.codequery.util.PathUtil;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.IOUtils;
+
+import java.io.*;
+import java.util.Collection;
+import java.util.stream.Collectors;
+
+@Data
+@Slf4j
+public class Commit {
+ private String id;
+ private Collection containedFileObjects;
+
+ public Commit(String commitId, Collection containedFiles, File rootDir) {
+ this.id = commitId;
+ this.containedFileObjects = containedFiles.stream()
+ .map(fileObject -> {
+ SimpleFileObject simpleFileObject = new SimpleFileObject();
+ simpleFileObject.setObjectId(fileObject.getHashId());
+ simpleFileObject.setRelativePath(PathUtil.getRelPath(rootDir.getAbsolutePath(), fileObject.getSourceFile().getAbsolutePath()));
+ return simpleFileObject;
+ })
+ .collect(Collectors.toList());
+ }
+
+ public void writeToJsonFile(File targetFile) {
+ String jsonString = JSON.toJSONString(this);
+ try (
+ InputStream inputStream = new ByteArrayInputStream(jsonString.getBytes());
+ OutputStream outputStream = new FileOutputStream(targetFile)
+ ) {
+ IOUtils.copy(inputStream, outputStream);
+ } catch (IOException ioe) {
+ log.error("write json string to file get error!", ioe);
+ throw new RuntimeException(ioe);
+ }
+ }
+
+ public static Commit readFromFile(File targetFile) {
+ try (
+ InputStream inputStream = new FileInputStream(targetFile);
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream()
+ ) {
+ IOUtils.copy(inputStream, outputStream);
+ String jsonString = outputStream.toString();
+ return JSON.parseObject(jsonString, Commit.class);
+ } catch (IOException e) {
+ log.error("read file to json get error!", e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Data
+ public static class SimpleFileObject {
+ String objectId;
+ String relativePath;
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/CorefASTDumpStorage.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/CorefASTDumpStorage.java
new file mode 100644
index 00000000..4b918a16
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/CorefASTDumpStorage.java
@@ -0,0 +1,866 @@
+package com.alipay.codequery.coref.storage;
+
+import com.alipay.codequery.coref.core.CorefURI;
+import com.alipay.codequery.coref.core.SignatureGenerator;
+import com.alipay.codequery.coref.model.*;
+import com.alipay.codequery.coref.model.Class;
+import com.alipay.codequery.coref.model.Comment;
+import com.alipay.codequery.coref.model.Expression;
+import com.alipay.codequery.coref.model.File;
+import com.alipay.codequery.coref.model.Folder;
+import com.alipay.codequery.coref.model.Identifier;
+import com.alipay.codequery.coref.model.Modifier;
+import com.alipay.codequery.coref.model.Module;
+import com.alipay.codequery.coref.model.Program;
+import com.alipay.codequery.coref.model.Statement;
+import com.alipay.codequery.coref.model.NpClass;
+import com.alipay.codequery.coref.model.NpFile;
+import com.alipay.codequery.coref.model.NpInterface;
+import com.alipay.codequery.coref.model.NpMethod;
+import com.alipay.codequery.coref.model.NpProject;
+import com.alipay.codequery.coref.util.HashUtil;
+import com.alipay.codequery.dal.mybatis.domain.*;
+import com.alipay.codequery.dal.mybatis.domain.Exception;
+import com.alipay.codequery.dal.mybatis.mapper.*;
+import com.alipay.codequery.project.PsiProject;
+import com.google.gson.*;
+import com.alipay.codequery.dal.mybatis.domain.Primitive;
+import com.alipay.codequery.util.PathUtil;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.jetbrains.kotlin.com.intellij.psi.*;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Map;
+
+public class CorefASTDumpStorage implements IStorage {
+
+ public static final Logger logger = LogManager.getLogger(CorefASTDumpStorage.class);
+ private final Map hashIDToNodeMap = new HashMap<>();
+ private final String corefASTPath;
+ private final String srcRootDir;
+ private final java.io.File file;
+ private PsiJavaFile psiJavaFile;
+ private final CorefURI corefURI ;
+
+ public CorefASTDumpStorage(String corefASTPath, String srcRootDir, java.io.File file, PsiProject basicProject,
+ String repository) {
+ this.psiJavaFile = basicProject.getPsiJavaFileFromFile(file);
+ assert psiJavaFile != null;
+
+ this.corefURI = new CorefURI(repository);
+ String relativePath = PathUtil.getRelPath(srcRootDir, psiJavaFile.getVirtualFile().getPath());
+ this.corefURI.setPath(relativePath);
+
+ this.corefASTPath = corefASTPath;
+ this.srcRootDir = srcRootDir;
+ this.file = file;
+
+ }
+
+ @Override
+ public void commit() {
+ this.dumpCorefAST();
+ }
+
+ @Override
+ public void storeLocation(com.alipay.codequery.coref.model.Location location) {
+ }
+
+ @Override
+ public void storeStatementEnclosingExpression(StatementEnclosingExpression s) {
+ }
+
+ @Override
+ public void storeCallableEnclosingExpression(CallableEnclosingExpression c) {
+
+ }
+
+ void collectHashIdToNode(Long hashId, Object node) {
+ hashIDToNodeMap.put(hashId, node.getClass().getSimpleName());
+ }
+
+ @Override
+ public void storeCallableEnclosingStatement(CallableEnclosingStatement c) {
+ }
+
+ @Override
+ public void storeNumberOfLines(com.alipay.codequery.coref.model.Location.NumberOfLines numberOfLines) {
+ }
+
+ @Override
+ public void storeNameStrings(NameString nameString) {
+ }
+
+ @Override
+ public void storeReferenceRelation(ReferenceRelation referenceRelation) {
+ }
+
+ @Override
+ public void storeCallableBinding(CallableBinding callableBinding) {
+ }
+
+ @Override
+ public void storeParent(com.alipay.codequery.coref.model.Parent parent) {
+ }
+
+ @Override
+ public void storeAnnotatedRelation(AnnotatedRelation annotatedRelation) {
+ }
+
+ @Override
+ public void storeParameter(com.alipay.codequery.coref.model.Parameter parameter) {
+ collectHashIdToNode(parameter.getHashId(), parameter.extractParameter());
+ }
+
+ @Override
+ public void storeReferenceElement(com.alipay.codequery.coref.model.Expression reference) {
+ collectHashIdToNode(reference.getHashId(), reference.extractReferenceElement());
+ }
+
+ @Override
+ public void storeImportStaticReferenceElement(com.alipay.codequery.coref.model.Expression reference) {
+ collectHashIdToNode(reference.getHashId(), reference.extractImportStaticReferenceElement());
+ }
+
+ @Override
+ public void storeTypeParameter(Type.TypeParameter parameter) {
+ collectHashIdToNode(parameter.getHashId(), parameter.extractTypeParameter());
+ }
+
+ @Override
+ public void storeClassInitializer(com.alipay.codequery.coref.model.Expression initializer) {
+ collectHashIdToNode(initializer.getHashId(), initializer.extractClassInitializer());
+ }
+
+ @Override
+ public void storeAnnotationDeclarationParameterDefaultValue(AnnotationDeclarationParameterDefaultValue parameter) {
+ collectHashIdToNode(parameter.getElementHashId(), parameter);
+ }
+
+ @Override
+ public void storeJavaDocTag(com.alipay.codequery.coref.model.Comment.JavaDocTag docTag) {
+ collectHashIdToNode(docTag.getHashId(), docTag.extractJavadocTag());
+ }
+
+ @Override
+ public void storeAnonymousClass(Class.AnonymousClass clazz) {
+ collectHashIdToNode(clazz.getHashId(), clazz.extractAnonymousClass());
+ }
+
+ @Override
+ public void storeFileMd5Sum(FileMd5Sum file) {
+ }
+
+ @Override
+ public void storeFileSHA256Sum(FileSha256Sum file) {
+ }
+
+// public void storeAnnotation(Annotations.AnnotationModel annotation){
+// if(!mock)// }
+
+ @Override
+ public void storeReferenceType(Type type) {
+ collectHashIdToNode(type.getHashId(), type.extractReferenceType());
+ }
+
+ @Override
+ public void storeIfStatementWithElse(com.alipay.codequery.coref.model.Statement.IfStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractIfStatementWithElse());
+ }
+
+ @Override
+ public void storeIfStatementWithoutElse(com.alipay.codequery.coref.model.Statement.IfStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractIfStatementWithoutElse());
+ }
+
+// public void storeTypeParameter(TypeParameterElement element){
+// if(!mock)// }
+
+ @Override
+ public void storeTypeElement(Type element) {
+ collectHashIdToNode(element.getHashId(), element.extractTypeElement());
+ }
+
+// public void storeTypeArgument(TypeArgument argument){
+// if(!mock)// }
+
+ @Override
+ public void storeYieldStatement(com.alipay.codequery.coref.model.Statement.YieldStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractYieldStatement());
+ }
+
+ @Override
+ public void storeSynchronizedStatement(com.alipay.codequery.coref.model.Statement.SynchronizedStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractSynchronizedStatement());
+ }
+
+
+ @Override
+ public void storeExpressionStatement(com.alipay.codequery.coref.model.Statement.ExpressionStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractExpressionStatement());
+ }
+
+ @Override
+ public void storeCodeBlock(com.alipay.codequery.coref.model.Statement.CodeBlock codeblock) {
+ collectHashIdToNode(codeblock.getHashId(), codeblock.extractCodeBlock());
+ }
+
+ @Override
+ public void storeBlockStatement(com.alipay.codequery.coref.model.Statement.BlockStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractBlockStatement());
+ }
+
+ @Override
+ public void storeLabeledStatement(com.alipay.codequery.coref.model.Statement.LabeledStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractLabeledStatement());
+ }
+
+ @Override
+ public void storeLambdaExpression(com.alipay.codequery.coref.model.Expression.LambdaExpression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractLambdaExpression());
+ }
+
+ @Override
+ public void storeThisExpression(com.alipay.codequery.coref.model.Expression.ThisExpression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractThisAccessExpression());
+ }
+
+ @Override
+ public void storeThisExpressionWithQualifier(com.alipay.codequery.coref.model.Expression.ThisExpression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractThisExpressionWithQualifier());
+
+ }
+
+ @Override
+ public void storeSuperAccessExpression(com.alipay.codequery.coref.model.Expression.MethodCallExpression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractSuperAccessExpression());
+ }
+
+ @Override
+ public void storeSuperConstructorInvocation(com.alipay.codequery.coref.model.Expression.MethodCallExpression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractSuperConstructorInvocation());
+ }
+
+ @Override
+ public void storeEmptyStatement(com.alipay.codequery.coref.model.Statement.EmptyStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractEmptyStatement());
+ }
+
+ @Override
+ public void storeWhileStatement(com.alipay.codequery.coref.model.Statement.WhileStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractWhileStatement());
+ }
+
+ @Override
+ public void storeTryStatementWithoutFinally(com.alipay.codequery.coref.model.Statement.TryStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractTryStatementWithoutFinally());
+ }
+
+ @Override
+ public void storeTryStatementWithFinally(com.alipay.codequery.coref.model.Statement.TryStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractTryStatementWithFinally());
+ }
+
+ @Override
+ public void storeThrowStatement(com.alipay.codequery.coref.model.Statement.ThrowStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractThrowStatement());
+ }
+
+
+ @Override
+ public void storeSwitchStatement(com.alipay.codequery.coref.model.Statement.SwitchStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractSwitchStatement());
+ }
+
+ @Override
+ public void storeSwitchLabelStatement(com.alipay.codequery.coref.model.Statement.SwitchLabelStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractSwitchLabelStatement());
+ }
+
+ @Override
+ public void storeDoWhileStatement(com.alipay.codequery.coref.model.Statement.DoWhileStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractDoWhileStatement());
+ }
+
+ @Override
+ public void storeContinueStatement(com.alipay.codequery.coref.model.Statement.ContinueStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractContinueStatement());
+ }
+
+ @Override
+ public void storeBreakStatement(com.alipay.codequery.coref.model.Statement.BreakStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractBreakStatement());
+ }
+
+ @Override
+ public void storeReturnStatement(com.alipay.codequery.coref.model.Statement.ReturnStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractReturnStatement());
+ }
+
+ @Override
+ public void storeModule(Module module) {
+ collectHashIdToNode(module.getHashId(), module.extractModule());
+ }
+
+ @Override
+ public void storeTypeLiteral(Type.TypeLiteral literal) {
+ collectHashIdToNode(literal.getHashId(), literal.extractTypeLiteral());
+ }
+
+ @Override
+ public void storeAssertStatement(com.alipay.codequery.coref.model.Statement.AssertStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractAssertStatement());
+ }
+
+ @Override
+ public void storeDeclarationElement(com.alipay.codequery.coref.model.Statement.DeclarationStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractDeclarationElement());
+ }
+
+ @Override
+ public void storeImport(com.alipay.codequery.coref.model.Statement.ImportStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractImport());
+ }
+
+ @Override
+ public void storeImportStaticStatement(com.alipay.codequery.coref.model.Statement.ImportStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractImportStaticStatement());
+ }
+
+ @Override
+ public void storeResourceList(ResourceList list) {
+
+ }
+
+ @Override
+ public void storeMethodAccessExpressionWithoutType(com.alipay.codequery.coref.model.Expression.MethodCallExpression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractMethodAccessExpressionWithoutType());
+ }
+
+ @Override
+ public void storeMethodAccessExpressionWithType(com.alipay.codequery.coref.model.Expression.MethodCallExpression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractMethodAccessExpressionWithType());
+ }
+
+ @Override
+ public void storeMethodReferenceExpression(com.alipay.codequery.coref.model.Expression.MethodCallExpression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractMethodReferenceExpression());
+ }
+
+ @Override
+ public void storeArrayInitializerExpression(com.alipay.codequery.coref.model.Expression.ArrayInitializationExpression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractArrayInitializerExpression());
+ }
+
+ @Override
+ public void storeAnnotationArrayInitializer(com.alipay.codequery.coref.model.Expression.ArrayInitializationExpression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractAnnotationArrayInitializer());
+ }
+
+ @Override
+ public void storeArrayAccessExpression(com.alipay.codequery.coref.model.Expression.ArrayAccessExpression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractArrayAccessExpression());
+ }
+
+ @Override
+ public void storeToken(Token token) {
+ }
+
+ @Override
+ public void storeLocalVariable(com.alipay.codequery.coref.model.LocalVariable variable) {
+ collectHashIdToNode(variable.getHashId(), variable.extractLocalVariable());
+ }
+
+// public void storeCallExpression(Expressions.CallExpression expression){
+// if(!mock)// }
+
+ @Override
+ public void storeCastExpression(com.alipay.codequery.coref.model.Expression.CastExpression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractTypeCastExpressiont());
+ }
+
+ @Override
+ public void storeReferenceExpression(com.alipay.codequery.coref.model.Expression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractReferenceExpression());
+
+ }
+
+ @Override
+ public void storeConstructorInvocation(com.alipay.codequery.coref.model.Expression.NewExpression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractConstructorInvocation());
+
+ }
+
+ @Override
+ public void storeConditionalExpression(com.alipay.codequery.coref.model.Expression.ConditionalExpression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractCondtionalExpression());
+
+ }
+
+ @Override
+ public void storeNewExpression(com.alipay.codequery.coref.model.Expression.NewExpression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractNewExpression());
+
+ }
+
+ @Override
+ public void storeArrayCreationExpression(com.alipay.codequery.coref.model.Expression.NewExpression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractArrayCreationExpression());
+
+ }
+
+ @Override
+ public void storeField(com.alipay.codequery.coref.model.Field field) {
+ collectHashIdToNode(field.getHashId(), field.extractField());
+
+ }
+
+ @Override
+ public void storeMethod(com.alipay.codequery.coref.model.Method method) {
+ collectHashIdToNode(method.getHashId(), method.extractMethodDeclaration());
+
+ }
+
+ @Override
+ public void storeConstructor(com.alipay.codequery.coref.model.Method method) {
+ collectHashIdToNode(method.getHashId(), method.extractConstructor());
+ }
+
+ @Override
+ public void storePrimitive(Primitive primitive) {
+ }
+
+ @Override
+ public void storeCatchClauseStatement(com.alipay.codequery.coref.model.Statement.CatchClause catchClause) {
+ collectHashIdToNode(catchClause.getHashId(), catchClause.extractCatchSection());
+
+ }
+
+ @Override
+ public void storeLocalClass(Class.ClassDefinition statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractLocalClass());
+
+ }
+
+ @Override
+ public void storeEnumConstant(com.alipay.codequery.coref.model.Field enumField) {
+ collectHashIdToNode(enumField.getHashId(), enumField.extractEnumConstant());
+
+ }
+
+ @Override
+ public void storeInstanceOfExpression(com.alipay.codequery.coref.model.Expression.InstanceOfExpression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractInstanceOfExpression());
+
+ }
+
+ @Override
+ public void storeArray(Variable array) {
+ }
+
+ @Override
+ public void storeAnnotationCanResolved(Annotation.AnnotationModel annotation) {
+ collectHashIdToNode(annotation.getHashId(), annotation.extractAnnotationCanResolved());
+ }
+
+ @Override
+ public void storeAnnotationCanNotResolved(Annotation.AnnotationModel annotation) {
+ collectHashIdToNode(annotation.getHashId(), annotation.extractAnnotationCanNotResolved());
+ }
+
+ @Override
+ public void storeAnnotationDeclaration(Annotation.AnnotationModel annotation) {
+ collectHashIdToNode(annotation.getHashId(), annotation.extractAnnotationDeclaration());
+ }
+
+ @Override
+ public void storeAnnotationDeclarationParameter(Annotation.AnnotationParameter parameter) {
+ collectHashIdToNode(parameter.getHashId(), parameter.extractAnnotationArgument());
+ }
+
+ @Override
+ public void storeExpression(com.alipay.codequery.coref.model.Expression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractExpression());
+ }
+
+ @Override
+ public void storePackageStatement(com.alipay.codequery.coref.model.Statement.PackageStatement packages) {
+ collectHashIdToNode(packages.getHashId(), packages.extractPackage());
+ }
+
+ @Override
+ public void storeCuPackage(Cupackage cupackage) {
+ }
+
+ @Override
+ public void storeClassHierarchy(Class.ClassHierarchy classHierarchy) {
+ collectHashIdToNode(classHierarchy.getHashId(), classHierarchy.extractClassHierarchy());
+ }
+
+ @Override
+ public void storeSuperExpression(com.alipay.codequery.coref.model.Expression.SuperExpression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractSuperExpression());
+ }
+
+ @Override
+ public void storeSuperExpressionWithQualifier(com.alipay.codequery.coref.model.Expression.SuperExpression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractSuperExpressionWithQualifier());
+ }
+
+ @Override
+ public void storeException(Exception exception) {
+ }
+
+ @Override
+ public void storeClass(Class.ClassDefinition classDefinition) {
+ collectHashIdToNode(classDefinition.getHashId(), classDefinition.extractClass());
+ }
+
+ @Override
+ public void storeImplementlist(ClassImplementList list) {
+ }
+
+
+ @Override
+ public void storeElement(Element e) {
+ }
+
+ @Override
+ public void storeReferencelist(com.alipay.codequery.coref.model.Expression.ReferenceList list) {
+ collectHashIdToNode(list.getHashId(), list.extractReferenceList());
+ }
+
+ @Override
+ public void storeReferenceParameterlist(ParameterList.ReferenceParameterList list, int index) {
+ collectHashIdToNode(list.getHashId(), list.extractReferenceParameterList(index));
+ }
+
+ @Override
+ public void storeEmptyReferenceParameterlist(ParameterList.ReferenceParameterList list) {
+ collectHashIdToNode(list.getHashId(), list.extractEmptyReferenceParameterList());
+ }
+
+ @Override
+ public void storeInterface(Class.ClassDefinition classDefinition) {
+ collectHashIdToNode(classDefinition.getHashId(), classDefinition.extractInterface());
+ }
+
+ @Override
+ public void storeStatement(com.alipay.codequery.coref.model.Statement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractStatement());
+ }
+
+ @Override
+ public void storeComment(com.alipay.codequery.coref.model.Comment comment) {
+ collectHashIdToNode(comment.getHashId(), comment.extractComment());
+ }
+
+ @Override
+ public void storeExpressionList(com.alipay.codequery.coref.model.Expression.ExpressionList list) {
+ collectHashIdToNode(list.getHashId(), list.extractExpressionList());
+ }
+
+ @Override
+ public void storeExpressionListExpressionRelation(ExpressionListExpressionRelation expressionListRelation) {
+ }
+
+ @Override
+ public void storeJavaDocComment(com.alipay.codequery.coref.model.Comment.JavaDocComment comments) {
+ collectHashIdToNode(comments.getHashId(), comments.extractJavaDocComment());
+ }
+
+ @Override
+ public void storeJavaDocDataToken(com.alipay.codequery.coref.model.Comment.JavaDocDataToken javaDocDataToken) {
+ collectHashIdToNode(javaDocDataToken.getHashId(), javaDocDataToken.extractJavaDocDataToken());
+ }
+
+ @Override
+ public void storeJavaDocTagValue(Comment.JavaDocTagValue javaDocTagValue) {
+ collectHashIdToNode(javaDocTagValue.getHashId(), javaDocTagValue.extractJavaDocTagValue());
+ }
+
+ @Override
+ public void storeForStatement(com.alipay.codequery.coref.model.Statement.ForStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractForStatement());
+ }
+
+ @Override
+ public void storeAssignmentExpression(com.alipay.codequery.coref.model.Expression.AssignmentExpression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractAssignmentExpression());
+ }
+
+ @Override
+ public void storeBinaryExpression(com.alipay.codequery.coref.model.Expression.BinaryExpression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractBinaryExpression());
+ }
+
+ @Override
+ public void storePolyadicExpression(com.alipay.codequery.coref.model.Expression.PolyadicExpression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractPolyadicExpression());
+ }
+
+ @Override
+ public void storeUnaryExpression(Expression.UnaryExpression expression) {
+ collectHashIdToNode(expression.getHashId(), expression.extractUnaryExpression());
+ }
+
+ @Override
+ public void storeForeachStatement(Statement.ForeachStatement statement) {
+ collectHashIdToNode(statement.getHashId(), statement.extractForeachStatement());
+ }
+
+ @Override
+ public void storeAnnotationArgumentWithName(Annotation.AnnotationArgument annotationArgument) {
+ collectHashIdToNode(annotationArgument.getHashId(), annotationArgument.extractAnnotationArgumentWithName());
+
+ }
+
+ @Override
+ public void storeAnnotationArgumentWithoutName(Annotation.AnnotationArgument annotationArgument) {
+ collectHashIdToNode(annotationArgument.getHashId(), annotationArgument.extractAnnotationArgumentWithoutName());
+ }
+
+ @Override
+ public void storeProgram(Program program) {
+ collectHashIdToNode(program.getHashId(), program.extractProgram());
+ }
+
+ @Override
+ public void storeModifier(com.alipay.codequery.coref.model.Modifier modifier) {
+ collectHashIdToNode(modifier.getHashId(), modifier.extractModifier());
+ }
+
+ @Override
+ public void storeModifierList(Modifier modifier) {
+ collectHashIdToNode(modifier.getHashId(), modifier.extractModifierList());
+ }
+
+ @Override
+ public void storeFile(File file) {
+ collectHashIdToNode(file.getHashId(), file.extractFile());
+ }
+
+ @Override
+ public void storeFolder(Folder folder) {
+ collectHashIdToNode(folder.getHashId(), folder.extractFolder());
+ }
+
+ @Override
+ public void storeContainerParent(ContainerParent container) {
+ }
+
+ @Override
+ public void storeIdentifier(Identifier identifier) {
+ collectHashIdToNode(identifier.getHashId(), identifier.extractIdentifier());
+ }
+
+ @Override
+ public void handleLiteral(Literal literal) {
+ switch (literal.type) {
+ case "String":
+ storeLiteral(literal, StringLiteralMapper.class);
+ break;
+ case "int":
+ storeLiteral(literal, IntegerLiteralMapper.class);
+ break;
+ case "char":
+ storeLiteral(literal, CharacterLiteralMapper.class);
+ break;
+ case "double":
+ storeLiteral(literal, DoubleLiteralMapper.class);
+ break;
+ case "float":
+ storeLiteral(literal, FloatingPointLiteralMapper.class);
+ break;
+ case "long":
+ storeLiteral(literal, LongLiteralMapper.class);
+ break;
+ case "boolean":
+ storeLiteral(literal, BooleanLiteralMapper.class);
+ break;
+ case "null":
+ storeLiteral(literal, NullLiteralMapper.class);
+ break;
+ default:
+ break;
+ }
+ }
+
+ @Override
+ public void storeLiteral(Literal literal, java.lang.Class mapperClass) {
+ collectHashIdToNode(literal.getHashId(), literal.extractLiteral());
+ }
+
+ @Override
+ public void storeNpProject(NpProject npProject) {
+ collectHashIdToNode(npProject.getHashId(), npProject.extractNpProject());
+ }
+
+ @Override
+ public void storeNpFile(NpFile npFile) {
+ collectHashIdToNode(npFile.getHashId(), npFile.extractNpFile());
+ }
+
+ @Override
+ public void storeNpClass(NpClass npClass) {
+ collectHashIdToNode(npClass.getHashId(), npClass.extractNpClass());
+ }
+
+ @Override
+ public void storeNpInterface(NpInterface npInterface) {
+ collectHashIdToNode(npInterface.getHashId(), npInterface.extractNpInterface());
+ }
+
+ @Override
+ public void storeNpMethod(NpMethod npMethod) {
+ collectHashIdToNode(npMethod.getHashId(), npMethod.extractNpMethod());
+ }
+
+ public void clearHashIDToNodeMap() {
+ this.hashIDToNodeMap.clear();
+ }
+
+
+ private void dumpCorefAST() {
+ if (corefASTPath != null ) {
+ Path basePath = Paths.get(srcRootDir);
+ // 计算相对路径
+ Path relativePath = basePath.relativize(Paths.get(file.toString()));
+ // 拼接输出路径
+ Path fullPath = Paths.get(corefASTPath, relativePath.toString());
+
+ // 非空和覆盖的情况
+ java.io.File astPathDir = new java.io.File(corefASTPath);
+ if (!astPathDir.exists()) {
+ boolean created = astPathDir.mkdir();
+ if (created) {
+ logger.info("Folder created successfully.");
+ } else {
+ logger.error("Folder creation failed.");
+ }
+ }
+ // 直接添加一个.json的后缀
+ dumpAstJsonStr(psiJavaFile, hashIDToNodeMap, fullPath + ".json");
+ }
+ this.clearHashIDToNodeMap();
+ }
+
+
+ private void dumpAstJsonStr(PsiFile psiFile, Map hashIDToNodeMap, String outputPath) {
+ JsonElement jsonObject = getElementJsonStr(psiFile, hashIDToNodeMap);
+ Gson gson = new GsonBuilder().setPrettyPrinting().create();
+ String jsonString = gson.toJson(jsonObject);
+ java.io.File file = new java.io.File(outputPath);
+
+
+ try {
+ FileWriter writer = new FileWriter(file);
+ writer.write(jsonString);
+ writer.close();
+ logger.info("\nsuccess to generate file: " + outputPath);
+ } catch (IOException e) {
+ logger.error("\nfaild to generate file: " + outputPath, e);
+ }
+ }
+
+ private String truncate(String text, int maxTextLength) {
+ if (text.length() > maxTextLength){
+ return text.substring(0, maxTextLength).trim() + "...";
+ }
+ else{
+ return text;
+ }
+
+ }
+
+ private String getNodeMessage(PsiElement element) {
+ int maxTextLength = 80;
+ String result = "";
+ if (element instanceof PsiPlainTextFile) {
+ result = ((PsiPlainTextFile) element).getName();
+ } else if (element instanceof PsiFile) {
+ result = ((PsiFile) element).getName();
+ } else if (element instanceof PsiDirectory) {
+ result = ((PsiDirectory) element).getName();
+ } else if (element instanceof PsiComment) {
+ result = truncate(element.getText(), maxTextLength);
+ } else if (element instanceof PsiBinaryFile) {
+ result = ((PsiBinaryFile) element).getName();
+ } else {
+ result = truncate(element.getText(), maxTextLength);
+ }
+
+ return result;
+ }
+
+ private Long getHashId(PsiElement element){
+ if( element != null) {
+ String signature = SignatureGenerator.generate(element);
+ String path = corefURI.getPath();
+
+ //when a resolved element is from another file, needs to use its real file path.
+ if(element.getContainingFile() != null && element.getContainingFile().getVirtualFile() != null) {
+ if(!(element.getContainingFile().equals(file))){
+ path = PathUtil.getRelPath(this.srcRootDir, element.getContainingFile().getVirtualFile().getPath());
+ }
+ }
+
+ String corefURIString = CorefURI.generate(corefURI.getRepository(), path, signature);
+ return HashUtil.hashString(corefURIString);
+ } else {
+ return Long.valueOf(-1);
+ }
+ }
+
+ private JsonElement getElementJsonStr(PsiElement element, Map hashIDToNodeMap) {
+
+ if (element == null || (element instanceof PsiWhiteSpace)) {
+ return null;
+ }
+ Long hashId = getHashId(element);
+ String label = "";
+
+
+ if (hashIDToNodeMap.containsKey(hashId)) {
+ label = hashIDToNodeMap.get(hashId);
+
+ // 手工做一些特殊处理,更标准的方法是在代码中找到对应关系
+ if (("clazz").equals(label)) {
+ label = "Class";
+ } else if (("ImportInfo").equals(label)) {
+ label = "Import";
+ } else if (("InterfaceInfo").equals(label)) {
+ label = "Interface";
+ }
+ }
+
+ String nodeMessage = getNodeMessage(element);
+ if ("".equals(nodeMessage) && "".equals(label)) {
+ return null;
+ }
+
+ JsonObject jsonObject = new JsonObject();
+ jsonObject.add("nodeName", new JsonPrimitive(label));
+ jsonObject.add("nodeMessage", new JsonPrimitive(nodeMessage));
+ jsonObject.add("startOffset", new JsonPrimitive(element.getTextRange().getStartOffset()));
+ jsonObject.add("endOffset", new JsonPrimitive(element.getTextRange().getEndOffset()));
+
+ JsonArray jsonElements = new JsonArray();
+ if (element.getChildren().length > 0) {
+ for (PsiElement child : element.getChildren()) {
+ JsonElement childObject = getElementJsonStr(child, hashIDToNodeMap);
+ if (childObject != null) {
+ jsonElements.add(childObject);
+ }
+
+ }
+ }
+ jsonObject.add("children", jsonElements);
+ return jsonObject;
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/CorefCache.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/CorefCache.java
new file mode 100644
index 00000000..bbbd8f3a
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/CorefCache.java
@@ -0,0 +1,19 @@
+package com.alipay.codequery.coref.storage;
+
+import java.io.File;
+import java.util.Set;
+
+public interface CorefCache {
+
+ Set getAllObjectIds();
+
+ void putObjects(Set objectList);
+
+ Set getObjectByIds(Set objectIds);
+
+ File getLocalObjectDir();
+
+ void putCommit(Commit commit);
+
+ Commit getCommit(String commitId);
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/FileScopeCorefObject.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/FileScopeCorefObject.java
new file mode 100644
index 00000000..fdee6c02
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/FileScopeCorefObject.java
@@ -0,0 +1,12 @@
+package com.alipay.codequery.coref.storage;
+
+import lombok.Data;
+
+import java.io.File;
+
+@Data
+public class FileScopeCorefObject {
+ File sourceFile;
+ String hashId;
+ File cacheFile;
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/IStorage.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/IStorage.java
new file mode 100644
index 00000000..06109ae7
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/IStorage.java
@@ -0,0 +1,277 @@
+package com.alipay.codequery.coref.storage;
+
+import com.alipay.codequery.coref.model.*;
+import com.alipay.codequery.coref.model.Class;
+import com.alipay.codequery.coref.model.Comment;
+import com.alipay.codequery.coref.model.Expression;
+import com.alipay.codequery.coref.model.Location;
+import com.alipay.codequery.coref.model.Module;
+import com.alipay.codequery.coref.model.Statement;
+import com.alipay.codequery.coref.model.*;
+import com.alipay.codequery.coref.model.File;
+import com.alipay.codequery.coref.model.Folder;
+import com.alipay.codequery.coref.model.Identifier;
+import com.alipay.codequery.coref.model.Modifier;
+import com.alipay.codequery.coref.model.NpClass;
+import com.alipay.codequery.coref.model.NpFile;
+import com.alipay.codequery.coref.model.NpInterface;
+import com.alipay.codequery.coref.model.NpMethod;
+import com.alipay.codequery.coref.model.NpProject;
+import com.alipay.codequery.coref.model.Program;
+import com.alipay.codequery.dal.mybatis.domain.*;
+import com.alipay.codequery.dal.mybatis.domain.Exception;
+import com.alipay.codequery.coref.model.*;
+import com.alipay.codequery.dal.mybatis.domain.Primitive;
+
+
+public interface IStorage {
+ void commit();
+
+ void storeLocation(Location location);
+
+ void storeStatementEnclosingExpression(StatementEnclosingExpression s);
+
+ void storeCallableEnclosingExpression(CallableEnclosingExpression c);
+
+ void storeCallableEnclosingStatement(CallableEnclosingStatement c);
+
+ void storeNumberOfLines(Location.NumberOfLines numberOfLines);
+
+ void storeNameStrings(NameString nameString);
+
+ void storeReferenceRelation(ReferenceRelation referenceRelation);
+
+ void storeCallableBinding(CallableBinding callableBinding);
+
+ void storeParent(com.alipay.codequery.coref.model.Parent parent);
+
+ void storeAnnotatedRelation(AnnotatedRelation annotatedRelation);
+
+ void storeParameter(com.alipay.codequery.coref.model.Parameter parameter);
+
+ void storeReferenceElement(com.alipay.codequery.coref.model.Expression reference);
+
+ void storeImportStaticReferenceElement(com.alipay.codequery.coref.model.Expression reference);
+
+ void storeTypeParameter(Type.TypeParameter parameter);
+
+ void storeClassInitializer(com.alipay.codequery.coref.model.Expression initializer);
+
+ void storeAnnotationDeclarationParameterDefaultValue(AnnotationDeclarationParameterDefaultValue parameter);
+
+ void storeJavaDocTag(com.alipay.codequery.coref.model.Comment.JavaDocTag docTag);
+
+ void storeAnonymousClass(Class.AnonymousClass clazz);
+
+ void storeFileMd5Sum(FileMd5Sum file);
+
+ void storeFileSHA256Sum(FileSha256Sum file);
+
+ void storeReferenceType(Type type);
+
+ void storeIfStatementWithElse(com.alipay.codequery.coref.model.Statement.IfStatement statement);
+
+ void storeIfStatementWithoutElse(com.alipay.codequery.coref.model.Statement.IfStatement statement);
+
+ void storeTypeElement(Type element);
+
+ void storeYieldStatement(com.alipay.codequery.coref.model.Statement.YieldStatement statement);
+
+ void storeSynchronizedStatement(com.alipay.codequery.coref.model.Statement.SynchronizedStatement statement);
+
+ void storeExpressionStatement(com.alipay.codequery.coref.model.Statement.ExpressionStatement statement);
+
+ void storeCodeBlock(com.alipay.codequery.coref.model.Statement.CodeBlock statement);
+
+ void storeBlockStatement(com.alipay.codequery.coref.model.Statement.BlockStatement statement);
+
+ void storeLabeledStatement(com.alipay.codequery.coref.model.Statement.LabeledStatement statement);
+
+ void storeLambdaExpression(com.alipay.codequery.coref.model.Expression.LambdaExpression expression);
+
+ void storeThisExpression(com.alipay.codequery.coref.model.Expression.ThisExpression expression);
+
+ void storeThisExpressionWithQualifier(com.alipay.codequery.coref.model.Expression.ThisExpression expression);
+
+ void storeSuperAccessExpression(com.alipay.codequery.coref.model.Expression.MethodCallExpression expression);
+
+ void storeSuperConstructorInvocation(com.alipay.codequery.coref.model.Expression.MethodCallExpression expression);
+
+ void storeEmptyStatement(com.alipay.codequery.coref.model.Statement.EmptyStatement statement);
+
+ void storeWhileStatement(com.alipay.codequery.coref.model.Statement.WhileStatement statement);
+
+ void storeTryStatementWithoutFinally(com.alipay.codequery.coref.model.Statement.TryStatement statement);
+
+ void storeTryStatementWithFinally(com.alipay.codequery.coref.model.Statement.TryStatement statement);
+
+ void storeThrowStatement(com.alipay.codequery.coref.model.Statement.ThrowStatement statement);
+
+ void storeSwitchStatement(com.alipay.codequery.coref.model.Statement.SwitchStatement statement);
+
+ void storeSwitchLabelStatement(com.alipay.codequery.coref.model.Statement.SwitchLabelStatement statement);
+
+ void storeDoWhileStatement(com.alipay.codequery.coref.model.Statement.DoWhileStatement statement);
+
+ void storeContinueStatement(com.alipay.codequery.coref.model.Statement.ContinueStatement statement);
+
+ void storeBreakStatement(com.alipay.codequery.coref.model.Statement.BreakStatement statement);
+
+ void storeReturnStatement(com.alipay.codequery.coref.model.Statement.ReturnStatement statement);
+
+ void storeModule(Module module);
+
+ void storeTypeLiteral(Type.TypeLiteral literal);
+
+ void storeAssertStatement(com.alipay.codequery.coref.model.Statement.AssertStatement statement);
+
+ void storeDeclarationElement(com.alipay.codequery.coref.model.Statement.DeclarationStatement statement);
+
+ void storeImport(com.alipay.codequery.coref.model.Statement.ImportStatement statement);
+
+ void storeImportStaticStatement(com.alipay.codequery.coref.model.Statement.ImportStatement statement);
+
+ void storeResourceList(ResourceList list);
+
+ void storeMethodAccessExpressionWithoutType(com.alipay.codequery.coref.model.Expression.MethodCallExpression expression);
+
+ void storeMethodAccessExpressionWithType(com.alipay.codequery.coref.model.Expression.MethodCallExpression expression);
+
+ void storeMethodReferenceExpression(com.alipay.codequery.coref.model.Expression.MethodCallExpression expression);
+
+ void storeArrayInitializerExpression(com.alipay.codequery.coref.model.Expression.ArrayInitializationExpression expression);
+
+ void storeAnnotationArrayInitializer(com.alipay.codequery.coref.model.Expression.ArrayInitializationExpression expression);
+
+ void storeArrayAccessExpression(com.alipay.codequery.coref.model.Expression.ArrayAccessExpression expression);
+
+ void storeToken(Token token);
+
+ void storeLocalVariable(com.alipay.codequery.coref.model.LocalVariable variable);
+
+ void storeCastExpression(com.alipay.codequery.coref.model.Expression.CastExpression expression);
+
+ void storeReferenceExpression(com.alipay.codequery.coref.model.Expression expression);
+
+ void storeConstructorInvocation(com.alipay.codequery.coref.model.Expression.NewExpression expression);
+
+ void storeConditionalExpression(com.alipay.codequery.coref.model.Expression.ConditionalExpression expression);
+
+ void storeNewExpression(com.alipay.codequery.coref.model.Expression.NewExpression expression);
+
+ void storeArrayCreationExpression(com.alipay.codequery.coref.model.Expression.NewExpression expression);
+
+ void storeField(com.alipay.codequery.coref.model.Field field);
+
+ void storeMethod(com.alipay.codequery.coref.model.Method method);
+
+ void storeConstructor(com.alipay.codequery.coref.model.Method method);
+
+ void storePrimitive(Primitive primitive);
+
+ void storeCatchClauseStatement(com.alipay.codequery.coref.model.Statement.CatchClause catchClause);
+
+ void storeLocalClass(Class.ClassDefinition statement);
+
+ void storeEnumConstant(com.alipay.codequery.coref.model.Field enumField);
+
+ void storeInstanceOfExpression(com.alipay.codequery.coref.model.Expression.InstanceOfExpression expression);
+
+ void storeArray(Variable array);
+
+ // void storeAnnotationAccess(com.alipay.codequery.coref.model.Annotation.AnnotationModel annotation);
+
+ void storeAnnotationCanResolved(Annotation.AnnotationModel annotation);
+
+ void storeAnnotationCanNotResolved(Annotation.AnnotationModel annotation);
+
+ void storeAnnotationDeclaration(Annotation.AnnotationModel annotation);
+
+ void storeAnnotationDeclarationParameter(Annotation.AnnotationParameter parameter);
+
+ void storeExpression(com.alipay.codequery.coref.model.Expression expression);
+
+ void storePackageStatement(com.alipay.codequery.coref.model.Statement.PackageStatement packages);
+
+ void storeCuPackage(Cupackage cupackage);
+
+ void storeClassHierarchy(Class.ClassHierarchy classHierarchy);
+
+ void storeSuperExpression(com.alipay.codequery.coref.model.Expression.SuperExpression expression);
+
+ void storeSuperExpressionWithQualifier(com.alipay.codequery.coref.model.Expression.SuperExpression expression);
+
+ void storeException(Exception exception);
+
+ void storeClass(Class.ClassDefinition classDefinition);
+
+ void storeImplementlist(ClassImplementList list);
+
+ void storeElement(Element e);
+
+ void storeReferencelist(com.alipay.codequery.coref.model.Expression.ReferenceList list);
+
+ void storeReferenceParameterlist(ParameterList.ReferenceParameterList list, int index);
+
+ void storeEmptyReferenceParameterlist(ParameterList.ReferenceParameterList list);
+
+ void storeInterface(Class.ClassDefinition classDefinition);
+
+ void storeStatement(Statement statement);
+
+ void storeComment(com.alipay.codequery.coref.model.Comment comment);
+
+ void storeExpressionList(com.alipay.codequery.coref.model.Expression.ExpressionList list);
+
+ void storeExpressionListExpressionRelation(ExpressionListExpressionRelation expressionListRelation);
+
+ void storeJavaDocComment(com.alipay.codequery.coref.model.Comment.JavaDocComment comments);
+
+ void storeJavaDocDataToken(com.alipay.codequery.coref.model.Comment.JavaDocDataToken javaDocDataToken);
+
+ void storeJavaDocTagValue(Comment.JavaDocTagValue javaDocTagValue);
+
+ void storeForStatement(Statement.ForStatement statement);
+
+ void storeAssignmentExpression(com.alipay.codequery.coref.model.Expression.AssignmentExpression expression);
+
+ void storeBinaryExpression(com.alipay.codequery.coref.model.Expression.BinaryExpression expression);
+
+ void storePolyadicExpression(Expression.PolyadicExpression expression);
+
+ void storeUnaryExpression(Expression.UnaryExpression expression);
+
+ void storeForeachStatement(Statement.ForeachStatement statement);
+
+ void storeAnnotationArgumentWithName(Annotation.AnnotationArgument annotationArgument);
+
+ void storeAnnotationArgumentWithoutName(Annotation.AnnotationArgument annotationArgument);
+
+ void storeProgram(Program program);
+
+ void storeModifier(Modifier modifier);
+
+ void storeModifierList(Modifier modifier);
+
+ void storeFile(File file);
+
+ void storeFolder(Folder folder);
+
+ void storeContainerParent(ContainerParent container);
+
+ void storeIdentifier(Identifier identifier);
+
+ void handleLiteral(Literal literal);
+
+ void storeLiteral(Literal literal, java.lang.Class mapperClass);
+
+ void storeNpProject(NpProject npProject);
+
+ void storeNpFile(NpFile npFile);
+
+ void storeNpClass(NpClass npClass);
+
+ void storeNpInterface(NpInterface npInterface);
+
+ void storeNpMethod(NpMethod npMethod);
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/LocalCorefCache.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/LocalCorefCache.java
new file mode 100644
index 00000000..4c511632
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/LocalCorefCache.java
@@ -0,0 +1,100 @@
+package com.alipay.codequery.coref.storage;
+
+import com.google.common.collect.Sets;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Set;
+
+public class LocalCorefCache implements CorefCache {
+
+ private final File fileObjectDir;
+ private final File refDir;
+
+ /**
+ * 本地缓存可以选择关联远程缓存,对本地缓存的操作同时映射到远程缓存上。
+ */
+ private CorefCache remoteCorefCache;
+
+ public LocalCorefCache(File dir, CorefCache remoteCorefCache) {
+ this.fileObjectDir = new File(dir.getAbsolutePath() + File.separator + "objects");
+ this.fileObjectDir.mkdirs();
+ this.refDir = new File(dir.getAbsolutePath() + File.separator + "refs");
+ this.refDir.mkdirs();
+ this.remoteCorefCache = remoteCorefCache;
+ }
+
+ @Override
+ public Set getAllObjectIds() {
+ Set localObjectIds = getLocalObjectIds();
+ if (remoteCorefCache == null) {
+ return localObjectIds;
+ }
+
+ // 若关联着远端存储,则需要统计远端和本地,合并结果
+ Set remoteObjectIds = remoteCorefCache.getAllObjectIds();
+ localObjectIds.addAll(remoteObjectIds);
+ return localObjectIds;
+ }
+
+ @Override
+ public void putObjects(Set objectList) {
+ // 本地存储,storage已经写入过了,可以不管
+ if (remoteCorefCache == null) {
+ return;
+ }
+
+ remoteCorefCache.putObjects(objectList);
+ }
+
+ @Override
+ public Set getObjectByIds(Set objectIds) {
+ if (remoteCorefCache == null) {
+ return new HashSet<>();
+ }
+
+ // 只下载本地不存在,且远程存在的
+ Set localObjectIds = getLocalObjectIds();
+ Set shouldFetchIds = Sets.difference(objectIds, localObjectIds).immutableCopy();
+ return remoteCorefCache.getObjectByIds(shouldFetchIds);
+ }
+
+ @Override
+ public File getLocalObjectDir() {
+ return this.fileObjectDir;
+ }
+
+ @Override
+ public void putCommit(Commit commit) {
+ File commitJsonFile = new File(refDir + File.separator + commit.getId() + ".json");
+ commit.writeToJsonFile(commitJsonFile);
+
+ if (remoteCorefCache != null) {
+ remoteCorefCache.putCommit(commit);
+ }
+ }
+
+ @Override
+ public Commit getCommit(String commitId) {
+ File commitJsonFile = new File(refDir + File.separator + commitId);
+ if (!commitJsonFile.exists()) {
+ // 若本地没有则尝试从远程获取
+ return remoteCorefCache.getCommit(commitId);
+ }
+ return Commit.readFromFile(commitJsonFile);
+ }
+
+ private Set getLocalObjectIds() {
+ Set cachedFileObjectIds = new HashSet<>();
+ File[] childFiles = fileObjectDir.listFiles();
+ if (childFiles == null || childFiles.length == 0) {
+ return cachedFileObjectIds;
+ }
+
+ for (File childFile : childFiles) {
+ cachedFileObjectIds.add(childFile.getName());
+ }
+
+ return cachedFileObjectIds;
+ }
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/OssCorefCache.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/OssCorefCache.java
new file mode 100644
index 00000000..12959216
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/OssCorefCache.java
@@ -0,0 +1,255 @@
+package com.alipay.codequery.coref.storage;
+
+import com.alibaba.fastjson.JSON;
+import com.aliyun.oss.ClientException;
+import com.aliyun.oss.OSS;
+import com.aliyun.oss.OSSClientBuilder;
+import com.aliyun.oss.OSSException;
+import com.aliyun.oss.model.*;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.ini4j.Wini;
+
+import java.io.*;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+@Slf4j
+public class OssCorefCache implements CorefCache {
+
+ private final String endpoint;
+ private final String bucket;
+ private final String objectPathPrefix;
+ private final String refPathPrefix;
+
+ private final String accessKeyId;
+ private final String accessKeySecret;
+
+ private final File localFileObjectDir;
+ private final File localRefDir;
+
+ private static final String compressedFileSuffix = ".gz";
+ private static final String jsonFileSuffix = ".json";
+
+ public OssCorefCache(String pathPrefix, File localCacheDir, String bucket, File ossConfigFile) {
+ this.objectPathPrefix = pathPrefix + "objects/";
+ this.refPathPrefix = pathPrefix + "refs/";
+ this.localFileObjectDir = new File(localCacheDir.getAbsolutePath() + File.separator + "objects");
+ this.localFileObjectDir.mkdirs();
+ this.localRefDir = new File(localCacheDir.getAbsolutePath() + File.separator + "refs");
+ this.localRefDir.mkdirs();
+ if (StringUtils.isBlank(bucket)) {
+ throw new IllegalArgumentException("bucket cannot be blank!");
+ }
+ this.bucket = bucket;
+
+ if (ossConfigFile == null) {
+ throw new IllegalArgumentException("please specify oss config file!");
+ }
+ if (!ossConfigFile.exists()) {
+ throw new RuntimeException("oss config file not exists!");
+ }
+ try {
+ Wini ini = new Wini(ossConfigFile);
+ String endpoint = ini.get("Credentials", "endpoint");
+ String accessKeyId = ini.get("Credentials", "accessKeyID");
+ String accessKeySecret = ini.get("Credentials", "accessKeySecret");
+
+ if (endpoint == null || accessKeyId == null || accessKeySecret == null) {
+ throw new IllegalArgumentException("missing value: endpoint or accessKeyID or accessKeySecret.");
+ }
+ this.endpoint = endpoint;
+ this.accessKeyId = accessKeyId;
+ this.accessKeySecret = accessKeySecret;
+ } catch (IOException iffe) {
+ throw new RuntimeException("parse config file get exception.", iffe);
+ }
+
+ }
+
+ @Override
+ public Set getAllObjectIds() {
+ OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+ Set idSet = new HashSet<>();
+ try {
+ // 分页获取
+ int maxKeys = 200;
+ ListObjectsV2Result listObjectsV2Result;
+ String nextContinuationToken = null;
+ do {
+ ListObjectsV2Request listObjectsV2Request = new ListObjectsV2Request(bucket, objectPathPrefix);
+ listObjectsV2Request.setMaxKeys(maxKeys);
+ listObjectsV2Request.setContinuationToken(nextContinuationToken);
+
+ listObjectsV2Result = ossClient.listObjectsV2(listObjectsV2Request);
+
+ for (OSSObjectSummary summary : listObjectsV2Result.getObjectSummaries()) {
+ String key = summary.getKey();
+ if (key.endsWith(compressedFileSuffix)) {
+ key = key.substring(0, key.lastIndexOf('.'));
+ }
+ String hashId = StringUtils.removeStart(key, objectPathPrefix);
+ idSet.add(hashId);
+ }
+ nextContinuationToken = listObjectsV2Result.getNextContinuationToken();
+ } while (listObjectsV2Result.isTruncated());
+ } catch (OSSException oe) {
+ log.error("List object get OSSException. Error Message: {}, Error Code: {}, Request ID: {}, Host ID: {}",
+ oe.getErrorMessage(), oe.getErrorCode(), oe.getRequestId(), oe.getHostId());
+ } catch (ClientException ce) {
+ log.error("List object get ClientException. Error Message:" + ce.getMessage());
+ } finally {
+ if (ossClient != null) {
+ ossClient.shutdown();
+ }
+ }
+
+ return idSet;
+ }
+
+ @Override
+ public void putObjects(Set objectList) {
+ OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+ ExecutorService es = Executors.newFixedThreadPool(8);
+ CountDownLatch count = new CountDownLatch(objectList.size());
+ for (FileScopeCorefObject fileObject : objectList) {
+ es.submit(() -> {
+ File cacheFile = fileObject.getCacheFile();
+ File cacheZipFile = new File(cacheFile.getAbsolutePath() + compressedFileSuffix);
+ try {
+ FileInputStream fis = new FileInputStream(cacheFile);
+ GZIPOutputStream gzipOutputStream = new GZIPOutputStream(new FileOutputStream(cacheZipFile));
+ IOUtils.copy(fis, gzipOutputStream);
+ gzipOutputStream.close();
+ fis.close();
+
+ // 上传到OSS
+ String objectName = objectPathPrefix + fileObject.getHashId() + compressedFileSuffix;
+ ossClient.putObject(new PutObjectRequest(bucket, objectName, cacheZipFile));
+ } catch (IOException e) {
+ log.error("gzip compress get IOException. file objectId: {}", fileObject.getHashId(), e);
+ } catch (OSSException oe) {
+ log.error("Put object get OSSException. Error Message: {}, Error Code: {}, Request ID: {}, Host ID: {}",
+ oe.getErrorMessage(), oe.getErrorCode(), oe.getRequestId(), oe.getHostId());
+ } catch (ClientException ce) {
+ log.error("Put object get ClientException. Error Message:" + ce.getMessage());
+ } finally {
+ count.countDown();
+ }
+
+ // 上传完gz文件后,删除本地的gz文件
+ cacheZipFile.delete();
+ });
+ }
+
+ try {
+ count.await();
+ } catch (InterruptedException e) {
+ log.error("count down await get exception. ", e);
+ } finally {
+ es.shutdown();
+ if (ossClient != null) {
+ ossClient.shutdown();
+ }
+ }
+ }
+
+ @Override
+ public Set getObjectByIds(Set objectIds) {
+ OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+ Set cacheFileSet = new HashSet<>();
+ ExecutorService es = Executors.newFixedThreadPool(8);
+ CountDownLatch count = new CountDownLatch(objectIds.size());
+ for (String objectId : objectIds) {
+ es.submit(() -> {
+ try {
+ String path = objectPathPrefix + objectId + compressedFileSuffix;
+ File downloadedFile = new File(this.localFileObjectDir + "/" + objectId + compressedFileSuffix);
+ ossClient.getObject(new GetObjectRequest(bucket, path), downloadedFile);
+ File decompressedFile = new File(this.localFileObjectDir + "/" + objectId);
+
+ GZIPInputStream gzipInputStream = new GZIPInputStream(new FileInputStream(downloadedFile));
+ FileOutputStream fos = new FileOutputStream(decompressedFile);
+ IOUtils.copy(gzipInputStream, fos);
+ gzipInputStream.close();
+ fos.close();
+ // 删除下载的压缩文件
+ downloadedFile.delete();
+
+ FileScopeCorefObject fileScopeCorefObject = new FileScopeCorefObject();
+ fileScopeCorefObject.setCacheFile(decompressedFile);
+ fileScopeCorefObject.setHashId(objectId);
+ cacheFileSet.add(fileScopeCorefObject);
+ } catch (IOException e) {
+ log.error("gzip decompress get IOException. file objectId: {}", objectId, e);
+ } catch (OSSException oe) {
+ log.error("Get object get OSSException. Error Message: {}, Error Code: {}, Request ID: {}, Host ID: {}",
+ oe.getErrorMessage(), oe.getErrorCode(), oe.getRequestId(), oe.getHostId());
+ } catch (ClientException ce) {
+ log.error("Get object get ClientException. Error Message:" + ce.getMessage());
+ } finally {
+ count.countDown();
+ }
+ });
+ }
+
+ try {
+ count.await();
+ } catch (InterruptedException e) {
+ log.error("count down await get exception. ", e);
+ } finally {
+ es.shutdown();
+ if (ossClient != null) {
+ ossClient.shutdown();
+ }
+ }
+
+ return cacheFileSet;
+ }
+
+ @Override
+ public File getLocalObjectDir() {
+ return this.localFileObjectDir;
+ }
+
+ @Override
+ public void putCommit(Commit commit) {
+ OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+ String objectName = refPathPrefix + commit.getId() + jsonFileSuffix;
+ String commitJsonString = JSON.toJSONString(commit);
+ InputStream inputStream = new ByteArrayInputStream(commitJsonString.getBytes());
+ try {
+ ossClient.putObject(new PutObjectRequest(bucket, objectName, inputStream));
+ } catch (OSSException oe) {
+ log.error("Put object get OSSException. Error Message: {}, Error Code: {}, Request ID: {}, Host ID: {}",
+ oe.getErrorMessage(), oe.getErrorCode(), oe.getRequestId(), oe.getHostId());
+ } catch (ClientException ce) {
+ log.error("Put object get ClientException. Error Message:" + ce.getMessage());
+ } finally {
+ if (ossClient != null) {
+ ossClient.shutdown();
+ }
+ }
+ }
+
+ @Override
+ public Commit getCommit(String commitId) {
+ OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+ String objectName = refPathPrefix + commitId + jsonFileSuffix;
+ boolean exists = ossClient.doesObjectExist(bucket, objectName);
+ if (!exists) {
+ return null;
+ }
+ // 若在oss存在,则拷贝到本地缓存,并读取内容返回
+ File localCommitFile = new File(localRefDir.getAbsolutePath() + File.separator + commitId + jsonFileSuffix);
+ ossClient.getObject(new GetObjectRequest(bucket, objectName), localCommitFile);
+ return Commit.readFromFile(localCommitFile);
+ }
+
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/RemoteCacheType.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/RemoteCacheType.java
new file mode 100644
index 00000000..091a4ab2
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/RemoteCacheType.java
@@ -0,0 +1,5 @@
+package com.alipay.codequery.coref.storage;
+
+public enum RemoteCacheType {
+ oss;
+}
diff --git a/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/SqliteStorage2.java b/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/SqliteStorage2.java
new file mode 100644
index 00000000..8f57a35d
--- /dev/null
+++ b/language/java/extractor/src/main/java/com/alipay/codequery/coref/storage/SqliteStorage2.java
@@ -0,0 +1,830 @@
+package com.alipay.codequery.coref.storage;
+
+import com.alipay.codequery.coref.model.*;
+import com.alipay.codequery.coref.model.Class;
+import com.alipay.codequery.coref.model.Comment;
+import com.alipay.codequery.coref.model.Expression;
+import com.alipay.codequery.coref.model.File;
+import com.alipay.codequery.coref.model.Folder;
+import com.alipay.codequery.coref.model.Identifier;
+import com.alipay.codequery.coref.model.Modifier;
+import com.alipay.codequery.coref.model.Module;
+import com.alipay.codequery.coref.model.Program;
+import com.alipay.codequery.coref.model.Statement;
+import com.alipay.codequery.coref.model.*;
+import com.alipay.codequery.coref.model.NpClass;
+import com.alipay.codequery.coref.model.NpFile;
+import com.alipay.codequery.coref.model.NpInterface;
+import com.alipay.codequery.coref.model.NpMethod;
+import com.alipay.codequery.coref.model.NpProject;
+import com.alipay.codequery.dal.mybatis.domain.*;
+import com.alipay.codequery.dal.mybatis.domain.Exception;
+import com.alipay.codequery.dal.mybatis.mapper.*;
+import com.alipay.codequery.coref.model.*;
+import com.alipay.codequery.dal.mybatis.domain.Primitive;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.IOUtils;
+import org.apache.ibatis.datasource.DataSourceFactory;
+import org.apache.ibatis.datasource.pooled.PooledDataSourceFactory;
+import org.apache.ibatis.io.ResolverUtil;
+import org.apache.ibatis.mapping.Environment;
+import org.apache.ibatis.session.Configuration;
+import org.apache.ibatis.session.SqlSession;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.apache.ibatis.session.SqlSessionFactoryBuilder;
+import org.apache.ibatis.transaction.TransactionFactory;
+import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import tk.mybatis.mapper.entity.Config;
+import tk.mybatis.mapper.mapperhelper.MapperHelper;
+
+import javax.sql.DataSource;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.*;
+import java.util.List;
+import java.util.stream.Stream;
+
+@Slf4j
+public class SqliteStorage2 implements IStorage {
+
+ public static final Logger logger = LogManager.getLogger(SqliteStorage2.class);
+
+ private static final Set> mappers = new HashSet<>();
+ static {
+ ResolverUtil> resolverUtil = new ResolverUtil<>();
+ resolverUtil.find(new ResolverUtil.IsA(Object.class), "com.alipay.codequery.dal.mybatis.mapper");
+ Set>> mapperSet = resolverUtil.getClasses();
+ mappers.addAll(mapperSet);
+ }
+
+ private final SqlSessionFactory sqlSessionFactory;
+ private final MapperHelper mapperHelper;
+ private int batchSize = 2000;
+
+ private final Map> cacheManager = Collections.synchronizedMap(new HashMap<>());
+
+ public SqliteStorage2(String dbDir, String dbFileName) {
+ copyDBFiles(dbDir, dbFileName);
+
+ // init the mapper
+ Config config = new Config();
+ config.setIDENTITY("sqlite");
+ config.setEnableMethodAnnotation(true);
+ config.setNotEmpty(true);
+ config.setCheckExampleEntityClass(true);
+ config.setUseSimpleType(true);
+ config.setEnumAsSimpleType(true);
+ config.setWrapKeyword("`{0}`");
+ mapperHelper = new MapperHelper();
+ mapperHelper.setConfig(config);
+
+ Properties properties = new Properties();
+ properties.setProperty("driver", "org.sqlite.JDBC");
+ properties.setProperty("url", "jdbc:sqlite:" + Paths.get(dbDir, dbFileName));
+ properties.setProperty("username", "");
+ properties.setProperty("password", "");
+
+ DataSourceFactory factory = new PooledDataSourceFactory();
+ DataSource dataSource = factory.getDataSource();
+ factory.setProperties(properties);
+ TransactionFactory transactionFactory = new JdbcTransactionFactory();
+ Environment environment = new Environment("development", transactionFactory, dataSource);
+ Configuration configuration = new Configuration(environment);
+ for (java.lang.Class> mapperClass : mappers) {
+ configuration.addMapper(mapperClass);
+ }
+
+ sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
+
+ SqlSession session = sqlSessionFactory.openSession(false);
+ mapperHelper.processConfiguration(session.getConfiguration());
+ session.commit();
+ session.close();
+ }
+
+ private void copyDBFiles(String dbDir, String corefDbName) {
+ try {
+ Path destPath = Paths.get(dbDir, corefDbName);
+ if (destPath.toFile().exists()) {
+ Files.delete(destPath);
+ }
+
+ InputStream in = this.getClass().getClassLoader().getResourceAsStream("coref_java_src.db");
+ IOUtils.copy(in, new FileOutputStream(destPath.toFile()));
+ } catch (IOException e) {
+ logger.error("copy db file get error!", e);
+ }
+ }
+
+ private void insert(java.lang.Class mapperClass, Object object) {
+ Set