build: merge Coati app and Trial to single executable
* removed trial target * updated deploy scripts to exclude trial * cleanup CMakeLists * removed Eigen dependencies * split parser lib into lib_cxx and lib_java * added ProjectFactory and ProjectFactoryModules * removed old installer projects * updated wix installer * updated readme for wix setup * updated to use obfuscated exe * added qt.conf * added indexing dialog images * added jars * added coatidb files of sample projects * added source code of javaparser sample * removed auto-refresh image * intermediate files of windows installer are created in build folder * preselected desktop shortcut * build bat is executed from deploy_windows script
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
#include "data/parser/java/JavaEnvironment.h"
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include "utility/logging/logging.h"
|
||||
#include "data/parser/java/JavaEnvironmentFactory.h"
|
||||
|
||||
JavaEnvironment::~JavaEnvironment()
|
||||
{
|
||||
JavaEnvironmentFactory::getInstance()->unregisterEnvironment();
|
||||
}
|
||||
|
||||
bool JavaEnvironment::callStaticVoidMethod(std::string className, std::string methodName, int arg1, std::string arg2, std::string arg3, std::string arg4)
|
||||
{
|
||||
jclass javaClass = m_env->FindClass(className.c_str());
|
||||
if(javaClass == nullptr)
|
||||
{
|
||||
LOG_ERROR("class " + className + " not found in JVM environment");
|
||||
jthrowable exc = m_env->ExceptionOccurred();
|
||||
if(exc)
|
||||
{
|
||||
m_env->ExceptionDescribe();
|
||||
m_env->ExceptionClear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
jmethodID javaMethodId = m_env->GetStaticMethodID(javaClass, methodName.c_str(), "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
|
||||
if(javaMethodId == nullptr)
|
||||
{
|
||||
LOG_ERROR("method void " + methodName + "(int, String, String, String) not found in JVM environment");
|
||||
}
|
||||
else
|
||||
{
|
||||
jint jarg1 = arg1;
|
||||
jstring jarg2 = m_env->NewStringUTF(arg2.c_str());
|
||||
jstring jarg3 = m_env->NewStringUTF(arg3.c_str());
|
||||
jstring jarg4 = m_env->NewStringUTF(arg4.c_str());
|
||||
m_env->CallStaticVoidMethod(javaClass, javaMethodId, jarg1, jarg2, jarg3, jarg4);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string JavaEnvironment::toStdString(jstring s)
|
||||
{
|
||||
const char *nativeString = m_env->GetStringUTFChars(s, 0);
|
||||
std::string ret = nativeString;
|
||||
m_env->ReleaseStringUTFChars(s, nativeString);
|
||||
return ret;
|
||||
}
|
||||
|
||||
jstring JavaEnvironment::toJString(std::string s)
|
||||
{
|
||||
return m_env->NewStringUTF(s.c_str());
|
||||
}
|
||||
|
||||
JavaEnvironment::JavaEnvironment(JavaVM* jvm, JNIEnv* env)
|
||||
: m_jvm(jvm)
|
||||
, m_env(env)
|
||||
{
|
||||
JavaEnvironmentFactory::getInstance()->registerEnvironment();
|
||||
}
|
||||
|
||||
void JavaEnvironment::registerNativeMethods(std::string className, std::vector<NativeMethod> methods)
|
||||
{
|
||||
JNINativeMethod* jniMethods = new JNINativeMethod[methods.size()];
|
||||
|
||||
for (size_t i = 0; i < methods.size(); i++)
|
||||
{
|
||||
jniMethods[i].name = const_cast<char*>(methods[i].name.c_str());
|
||||
jniMethods[i].signature = const_cast<char*>(methods[i].signature.c_str());
|
||||
jniMethods[i].fnPtr = methods[i].function;
|
||||
}
|
||||
|
||||
jclass javaClass = m_env->FindClass(className.c_str());
|
||||
if (javaClass)
|
||||
{
|
||||
if (m_env->RegisterNatives(javaClass, jniMethods, methods.size()) < 0)
|
||||
{
|
||||
LOG_ERROR("RegisterNatives failed");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("class \"" + className + "\" not found while registering native methods");
|
||||
}
|
||||
|
||||
delete [] jniMethods;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#ifndef JAVA_ENVIRONMENT_H
|
||||
#define JAVA_ENVIRONMENT_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct JavaVM_;
|
||||
typedef JavaVM_ JavaVM;
|
||||
|
||||
struct JNIEnv_;
|
||||
typedef JNIEnv_ JNIEnv;
|
||||
|
||||
class _jstring;
|
||||
typedef _jstring *jstring;
|
||||
|
||||
class JavaEnvironmentFactory;
|
||||
|
||||
class JavaEnvironment
|
||||
{
|
||||
public:
|
||||
struct NativeMethod
|
||||
{
|
||||
std::string name;
|
||||
std::string signature;
|
||||
void *function;
|
||||
};
|
||||
|
||||
~JavaEnvironment();
|
||||
bool callStaticVoidMethod(std::string className, std::string methodName, int arg1, std::string arg2, std::string arg3, std::string arg4);
|
||||
|
||||
std::string toStdString(jstring s);
|
||||
jstring toJString(std::string s);
|
||||
|
||||
void registerNativeMethods(std::string className, std::vector<NativeMethod> methods);
|
||||
private:
|
||||
friend class JavaEnvironmentFactory;
|
||||
|
||||
JavaEnvironment(JavaVM* jvm, JNIEnv* env);
|
||||
|
||||
JavaVM* m_jvm;
|
||||
JNIEnv* m_env;
|
||||
};
|
||||
|
||||
#endif // JAVA_ENVIRONMENT_H
|
||||
@@ -0,0 +1,177 @@
|
||||
#include "data/parser/java/JavaEnvironmentFactory.h"
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include "data/parser/java/JavaEnvironment.h"
|
||||
#include "settings/ApplicationSettings.h"
|
||||
#include "utility/file/FileSystem.h"
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/utilityLibrary.h"
|
||||
|
||||
void JavaEnvironmentFactory::createInstance(std::string classPath, std::string& errorString)
|
||||
{
|
||||
if (s_instance)
|
||||
{
|
||||
if (classPath == s_classPath)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("java classpath cannot be changed!");
|
||||
// todo: implement destroying the old factory instance and create a new one.
|
||||
// may be not so easy... there can only be one java env per process (which can never be destroyed) -.-
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
std::function<jint (JavaVM**, void**, void*)> createInstanceFunction;
|
||||
|
||||
createInstanceFunction = utility::loadFunctionFromLibrary<jint, JavaVM**, void**, void*>(
|
||||
FilePath(ApplicationSettings::getInstance()->getJavaPath()),
|
||||
"JNI_CreateJavaVM",
|
||||
errorString
|
||||
);
|
||||
|
||||
if (!createInstanceFunction && errorString.size() > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
s_classPath = classPath;
|
||||
|
||||
JavaVM* jvm = nullptr; // Pointer to the JVM (Java Virtual Machine)
|
||||
JNIEnv* env = nullptr; // Pointer to native interface
|
||||
|
||||
JavaVMInitArgs vm_args; // Initialization arguments
|
||||
JavaVMOption* options = new JavaVMOption[3]; // JVM invocation options
|
||||
std::string classPathOption = "-Djava.class.path=" + classPath;
|
||||
options[0].optionString = const_cast<char*>(classPathOption.c_str());
|
||||
options[1].optionString = const_cast<char*>("-Xms64m");
|
||||
std::string maximumMemoryOprionString = "-Xmx" + std::to_string(ApplicationSettings::getInstance()->getJavaMaximumMemory()) + "m";
|
||||
options[2].optionString = const_cast<char*>(maximumMemoryOprionString.c_str());
|
||||
vm_args.version = JNI_VERSION_1_6;
|
||||
vm_args.nOptions = 3;
|
||||
vm_args.options = options;
|
||||
vm_args.ignoreUnrecognized = false; // invalid options make the JVM init fail
|
||||
|
||||
jint rc = createInstanceFunction(&jvm, (void**)&env, &vm_args);
|
||||
|
||||
delete [] options;
|
||||
|
||||
if (rc != JNI_OK)
|
||||
{
|
||||
if(rc == JNI_EVERSION)
|
||||
{
|
||||
errorString = "JVM is oudated and doesn't meet requirements";
|
||||
}
|
||||
else if(rc == JNI_ENOMEM)
|
||||
{
|
||||
errorString = "not enough memory for JVM";
|
||||
}
|
||||
else if(rc == JNI_EINVAL)
|
||||
{
|
||||
errorString = "invalid argument for launching JVM";
|
||||
}
|
||||
else if(rc == JNI_EEXIST)
|
||||
{
|
||||
errorString = "the process can only launch one JVM an not more";
|
||||
}
|
||||
else
|
||||
{
|
||||
errorString = "could not create the JVM instance (error code " + std::to_string(rc) + ")";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
jvm->DetachCurrentThread();
|
||||
s_instance = std::shared_ptr<JavaEnvironmentFactory>(new JavaEnvironmentFactory(jvm));
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<JavaEnvironmentFactory> JavaEnvironmentFactory::getInstance()
|
||||
{
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
JavaEnvironmentFactory::~JavaEnvironmentFactory()
|
||||
{
|
||||
// todo: what if there are threads running using the jvm?? log something!
|
||||
m_jvm->DestroyJavaVM();
|
||||
}
|
||||
|
||||
std::shared_ptr<JavaEnvironment> JavaEnvironmentFactory::createEnvironment()
|
||||
{
|
||||
std::thread::id currentThreadId = std::this_thread::get_id();
|
||||
|
||||
JNIEnv* env;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_threadIdToEnvAndUserCountMutex);
|
||||
|
||||
std::map<std::thread::id, std::pair<JNIEnv*, int>>::const_iterator it = m_threadIdToEnvAndUserCount.find(currentThreadId);
|
||||
if (it != m_threadIdToEnvAndUserCount.end())
|
||||
{
|
||||
env = it->second.first;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_jvm->AttachCurrentThread((void**)&env, NULL);
|
||||
m_threadIdToEnvAndUserCount.insert(std::make_pair(currentThreadId, std::make_pair(env, 0)));
|
||||
}
|
||||
}
|
||||
|
||||
return std::shared_ptr<JavaEnvironment>(new JavaEnvironment(m_jvm, env));
|
||||
}
|
||||
|
||||
std::shared_ptr<JavaEnvironmentFactory> JavaEnvironmentFactory::s_instance;
|
||||
|
||||
std::string JavaEnvironmentFactory::s_classPath;
|
||||
|
||||
JavaEnvironmentFactory::JavaEnvironmentFactory(JavaVM* jvm)
|
||||
: m_jvm(jvm)
|
||||
{
|
||||
}
|
||||
|
||||
void JavaEnvironmentFactory::registerEnvironment()
|
||||
{
|
||||
std::thread::id currentThreadId = std::this_thread::get_id();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_threadIdToEnvAndUserCountMutex);
|
||||
std::map<std::thread::id, std::pair<JNIEnv*, int>>::iterator it = m_threadIdToEnvAndUserCount.find(currentThreadId);
|
||||
if (it != m_threadIdToEnvAndUserCount.end())
|
||||
{
|
||||
it->second.second++;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("something went horribly wrong while registering a java environment");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JavaEnvironmentFactory::unregisterEnvironment()
|
||||
{
|
||||
std::thread::id currentThreadId = std::this_thread::get_id();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_threadIdToEnvAndUserCountMutex);
|
||||
std::map<std::thread::id, std::pair<JNIEnv*, int>>::iterator it = m_threadIdToEnvAndUserCount.find(currentThreadId);
|
||||
if (it != m_threadIdToEnvAndUserCount.end())
|
||||
{
|
||||
it->second.second--;
|
||||
if (it->second.second == 0)
|
||||
{ // TODO: currently this happens quite often. do something about that.
|
||||
m_jvm->DetachCurrentThread();
|
||||
m_threadIdToEnvAndUserCount.erase(it);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("something went horribly wrong while unregistering a java environment");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#ifndef JAVA_ENVIRONMENT_FACTORY_H
|
||||
#define JAVA_ENVIRONMENT_FACTORY_H
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
struct JavaVM_;
|
||||
typedef JavaVM_ JavaVM;
|
||||
|
||||
struct JNIEnv_;
|
||||
typedef JNIEnv_ JNIEnv;
|
||||
|
||||
class JavaEnvironment;
|
||||
|
||||
class JavaEnvironmentFactory
|
||||
{
|
||||
public:
|
||||
static void createInstance(std::string classPath, std::string& errorString);
|
||||
static std::shared_ptr<JavaEnvironmentFactory> getInstance();
|
||||
|
||||
~JavaEnvironmentFactory();
|
||||
|
||||
std::shared_ptr<JavaEnvironment> createEnvironment();
|
||||
|
||||
private:
|
||||
friend class JavaEnvironment;
|
||||
|
||||
static std::shared_ptr<JavaEnvironmentFactory> s_instance;
|
||||
static std::string s_classPath;
|
||||
|
||||
JavaEnvironmentFactory(JavaVM* jvm);
|
||||
|
||||
void registerEnvironment();
|
||||
void unregisterEnvironment();
|
||||
|
||||
JavaVM* m_jvm;
|
||||
std::map<std::thread::id, std::pair<JNIEnv*, int>> m_threadIdToEnvAndUserCount;
|
||||
std::mutex m_threadIdToEnvAndUserCountMutex;
|
||||
};
|
||||
|
||||
#endif // JAVA_ENVIRONMENT_FACTORY_H
|
||||
@@ -0,0 +1,206 @@
|
||||
#include "data/parser/java/JavaParser.h"
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include "data/parser/java/JavaEnvironmentFactory.h"
|
||||
#include "data/parser/ParseLocation.h"
|
||||
#include "data/parser/ReferenceKind.h"
|
||||
#include "data/parser/ParserClient.h"
|
||||
#include "utility/file/FileSystem.h"
|
||||
#include "utility/text/TextAccess.h"
|
||||
#include "utility/utilityString.h"
|
||||
|
||||
JavaParser::JavaParser(ParserClient* client)
|
||||
: Parser(client)
|
||||
, m_id(s_nextParserId++)
|
||||
, m_currentFilePath("")
|
||||
{
|
||||
std::shared_ptr<JavaEnvironmentFactory> factory = JavaEnvironmentFactory::getInstance();
|
||||
if (factory)
|
||||
{
|
||||
m_javaEnvironment = factory->createEnvironment();
|
||||
|
||||
std::vector<JavaEnvironment::NativeMethod> methods;
|
||||
|
||||
methods.push_back({"recordSymbol", "(ILjava/lang/String;IIIIIII)V", (void*)&JavaParser::RecordSymbol});
|
||||
methods.push_back({"recordSymbolWithoutLocation", "(ILjava/lang/String;III)V", (void*)&JavaParser::RecordSymbolWithoutLocation});
|
||||
methods.push_back({"recordSymbolWithScope", "(ILjava/lang/String;IIIIIIIIIII)V", (void*)&JavaParser::RecordSymbolWithScope});
|
||||
methods.push_back({"recordReference", "(IILjava/lang/String;Ljava/lang/String;IIII)V", (void*)&JavaParser::RecordReference});
|
||||
methods.push_back({"recordLocalSymbol", "(ILjava/lang/String;IIII)V", (void*)&JavaParser::RecordLocalSymbol});
|
||||
methods.push_back({"recordComment", "(IIIII)V", (void*)&JavaParser::RecordComment});
|
||||
methods.push_back({"recordError", "(ILjava/lang/String;IIIIII)V", (void*)&JavaParser::RecordError});
|
||||
|
||||
m_javaEnvironment->registerNativeMethods("io/coati/JavaIndexer", methods);
|
||||
}
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(s_parsersMutex);
|
||||
s_parsers[m_id] = this;
|
||||
}
|
||||
}
|
||||
|
||||
JavaParser::~JavaParser()
|
||||
{
|
||||
s_parsers.erase(m_id);
|
||||
}
|
||||
|
||||
void JavaParser::parseFiles(const std::vector<FilePath>& filePaths, const Arguments& arguments)
|
||||
{
|
||||
//m_fileRegister->setFilePaths(filePaths);
|
||||
//setupParsing(arguments);
|
||||
|
||||
//std::vector<std::string> sourcePaths;
|
||||
//for (const FilePath& path : m_fileRegister->getUnparsedSourceFilePaths()) // filter headers
|
||||
//{
|
||||
// sourcePaths.push_back(path.absolute().str());
|
||||
//}
|
||||
|
||||
//runTool(sourcePaths);
|
||||
}
|
||||
|
||||
void JavaParser::parseFile(const FilePath& filePath, std::shared_ptr<TextAccess> textAccess, const Arguments& arguments)
|
||||
{
|
||||
if (m_javaEnvironment)
|
||||
{
|
||||
m_currentFilePath = filePath.str();
|
||||
m_client->onFileParsed(FileSystem::getFileInfoForPath(filePath));
|
||||
std::string classPath = "";
|
||||
for (const FilePath& path: arguments.javaClassPaths)
|
||||
{
|
||||
// the separator used here should be the same as the one used in JavaIndexer.java
|
||||
classPath += path.str() + ";";
|
||||
}
|
||||
|
||||
// remove tabs because they screw with javaparser's location resolver
|
||||
std::string fileContent = utility::replace(textAccess->getText(), "\t", " ");
|
||||
|
||||
m_javaEnvironment->callStaticVoidMethod("io/coati/JavaIndexer", "processFile", m_id, filePath.str(), fileContent, classPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int JavaParser::s_nextParserId = 0;
|
||||
|
||||
std::map<int, JavaParser*> JavaParser::s_parsers;
|
||||
|
||||
std::mutex JavaParser::s_parsersMutex;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void JavaParser::doRecordSymbol(
|
||||
jstring jSymbolName, jint jSymbolType,
|
||||
jint beginLine, jint beginColumn, jint endLine, jint endColumn,
|
||||
jint jAccess, jint jIsImplicit
|
||||
)
|
||||
{
|
||||
AccessKind access = intToAccessKind(jAccess);
|
||||
bool isImplicit = jIsImplicit;
|
||||
|
||||
m_client->recordSymbol(
|
||||
NameHierarchy::deserialize(m_javaEnvironment->toStdString(jSymbolName)),
|
||||
intToSymbolKind(jSymbolType),
|
||||
ParseLocation(m_currentFilePath, beginLine, beginColumn, endLine, endColumn),
|
||||
access,
|
||||
isImplicit
|
||||
);
|
||||
}
|
||||
|
||||
void JavaParser::doRecordSymbolWithoutLocation(
|
||||
jstring jSymbolName, jint jSymbolType,
|
||||
jint jAccess, jint jIsImplicit
|
||||
)
|
||||
{
|
||||
AccessKind access = intToAccessKind(jAccess);
|
||||
bool isImplicit = jIsImplicit;
|
||||
|
||||
m_client->recordSymbol(
|
||||
NameHierarchy::deserialize(m_javaEnvironment->toStdString(jSymbolName)),
|
||||
intToSymbolKind(jSymbolType),
|
||||
access,
|
||||
isImplicit
|
||||
);
|
||||
}
|
||||
|
||||
void JavaParser::doRecordSymbolWithScope(
|
||||
jstring jSymbolName, jint jSymbolType,
|
||||
jint beginLine, jint beginColumn, jint endLine, jint endColumn,
|
||||
jint scopeBeginLine, jint scopeBeginColumn, jint scopeEndLine, jint scopeEndColumn,
|
||||
jint jAccess, jint jIsImplicit
|
||||
)
|
||||
{
|
||||
AccessKind access = intToAccessKind(jAccess);
|
||||
bool isImplicit = jIsImplicit;
|
||||
|
||||
m_client->recordSymbol(
|
||||
NameHierarchy::deserialize(m_javaEnvironment->toStdString(jSymbolName)),
|
||||
intToSymbolKind(jSymbolType),
|
||||
ParseLocation(m_currentFilePath, beginLine, beginColumn, endLine, endColumn),
|
||||
ParseLocation(m_currentFilePath, scopeBeginLine, scopeBeginColumn, scopeEndLine, scopeEndColumn),
|
||||
access,
|
||||
isImplicit
|
||||
);
|
||||
}
|
||||
|
||||
void JavaParser::doRecordReference(
|
||||
jint jReferenceKind, jstring jReferencedName, jstring jContextName,
|
||||
jint beginLine, jint beginColumn, jint endLine, jint endColumn
|
||||
)
|
||||
{
|
||||
m_client->recordReference(
|
||||
intToReferenceKind(jReferenceKind),
|
||||
NameHierarchy::deserialize(m_javaEnvironment->toStdString(jReferencedName)),
|
||||
NameHierarchy::deserialize(m_javaEnvironment->toStdString(jContextName)),
|
||||
ParseLocation(m_currentFilePath, beginLine, beginColumn, endLine, endColumn)
|
||||
);
|
||||
}
|
||||
|
||||
void JavaParser::doRecordLocalSymbol(jstring jSymbolName, jint beginLine, jint beginColumn, jint endLine, jint endColumn)
|
||||
{
|
||||
m_client->onLocalSymbolParsed(
|
||||
m_javaEnvironment->toStdString(jSymbolName),
|
||||
ParseLocation(m_currentFilePath, beginLine, beginColumn, endLine, endColumn)
|
||||
);
|
||||
}
|
||||
|
||||
void JavaParser::doRecordComment(
|
||||
jint beginLine, jint beginColumn, jint endLine, jint endColumn
|
||||
)
|
||||
{
|
||||
m_client->onCommentParsed(
|
||||
ParseLocation(m_currentFilePath, beginLine, beginColumn, endLine, endColumn)
|
||||
);
|
||||
}
|
||||
|
||||
void JavaParser::doRecordError(
|
||||
jstring jMessage, jint jFatal, jint jIndexed,
|
||||
jint beginLine, jint beginColumn, jint endLine, jint endColumn
|
||||
)
|
||||
{
|
||||
bool fatal = jFatal;
|
||||
bool indexed = jIndexed;
|
||||
|
||||
m_client->onError(
|
||||
ParseLocation(m_currentFilePath, beginLine, beginColumn, endLine, endColumn),
|
||||
m_javaEnvironment->toStdString(jMessage),
|
||||
fatal, indexed
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
#ifndef JAVA_PARSER_H
|
||||
#define JAVA_PARSER_H
|
||||
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
|
||||
#include "data/parser/Parser.h"
|
||||
#include "data/parser/java/JavaEnvironment.h"
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
struct JNIEnv_;
|
||||
typedef JNIEnv_ JNIEnv;
|
||||
|
||||
class _jobject;
|
||||
typedef _jobject* jobject;
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef long jint;
|
||||
#else
|
||||
typedef int jint;
|
||||
#endif
|
||||
|
||||
class _jstring;
|
||||
typedef _jstring *jstring;
|
||||
|
||||
class FileRegister;
|
||||
|
||||
class JavaParser: public Parser
|
||||
{
|
||||
public:
|
||||
JavaParser(ParserClient* client);
|
||||
~JavaParser();
|
||||
|
||||
// ParserClient implementation
|
||||
virtual void parseFiles(const std::vector<FilePath>& filePaths, const Arguments& arguments);
|
||||
virtual void parseFile(const FilePath& filePath, std::shared_ptr<TextAccess> textAccess, const Arguments& arguments);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// This macro makes available a variable T, the passed-in t. blablabla TODO: write somethign real here
|
||||
#define MAKE_PARAMS_0()
|
||||
#define MAKE_PARAMS_1(t1) t1 arg1
|
||||
#define MAKE_PARAMS_2(t1, t2) t1 arg1, t2 arg2
|
||||
#define MAKE_PARAMS_3(t1, t2, t3) t1 arg1, t2 arg2, t3 arg3
|
||||
#define MAKE_PARAMS_4(t1, t2, t3, t4) t1 arg1, t2 arg2, t3 arg3, t4 arg4
|
||||
#define MAKE_PARAMS_5(t1, t2, t3, t4, t5) t1 arg1, t2 arg2, t3 arg3, t4 arg4, t5 arg5
|
||||
#define MAKE_PARAMS_6(t1, t2, t3, t4, t5, t6) t1 arg1, t2 arg2, t3 arg3, t4 arg4, t5 arg5, t6 arg6
|
||||
#define MAKE_PARAMS_7(t1, t2, t3, t4, t5, t6, t7) t1 arg1, t2 arg2, t3 arg3, t4 arg4, t5 arg5, t6 arg6, t7 arg7
|
||||
#define MAKE_PARAMS_8(t1, t2, t3, t4, t5, t6, t7, t8) t1 arg1, t2 arg2, t3 arg3, t4 arg4, t5 arg5, t6 arg6, t7 arg7, t8 arg8
|
||||
#define MAKE_PARAMS_9(t1, t2, t3, t4, t5, t6, t7, t8, t9) t1 arg1, t2 arg2, t3 arg3, t4 arg4, t5 arg5, t6 arg6, t7 arg7, t8 arg8, t9 arg9
|
||||
#define MAKE_PARAMS_10(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) t1 arg1, t2 arg2, t3 arg3, t4 arg4, t5 arg5, t6 arg6, t7 arg7, t8 arg8, t9 arg9, t10 arg10
|
||||
#define MAKE_PARAMS_11(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11) t1 arg1, t2 arg2, t3 arg3, t4 arg4, t5 arg5, t6 arg6, t7 arg7, t8 arg8, t9 arg9, t10 arg10, t11 arg11
|
||||
#define MAKE_PARAMS_12(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12) t1 arg1, t2 arg2, t3 arg3, t4 arg4, t5 arg5, t6 arg6, t7 arg7, t8 arg8, t9 arg9, t10 arg10, t11 arg11, t12 arg12
|
||||
//.. add as many MAKE_PARAMS_* as required
|
||||
|
||||
#define MAKE_ARGS_0()
|
||||
#define MAKE_ARGS_1(type) arg1
|
||||
#define MAKE_ARGS_2(t1, t2) arg1, arg2
|
||||
#define MAKE_ARGS_3(t1, t2, t3) arg1, arg2, arg3
|
||||
#define MAKE_ARGS_4(t1, t2, t3, t4) arg1, arg2, arg3, arg4
|
||||
#define MAKE_ARGS_5(t1, t2, t3, t4, t5) arg1, arg2, arg3, arg4, arg5
|
||||
#define MAKE_ARGS_6(t1, t2, t3, t4, t5, t6) arg1, arg2, arg3, arg4, arg5, arg6
|
||||
#define MAKE_ARGS_7(t1, t2, t3, t4, t5, t6, t7) arg1, arg2, arg3, arg4, arg5, arg6, arg7
|
||||
#define MAKE_ARGS_8(t1, t2, t3, t4, t5, t6, t7, t8) arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8
|
||||
#define MAKE_ARGS_9(t1, t2, t3, t4, t5, t6, t7, t8, t9) arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9
|
||||
#define MAKE_ARGS_10(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10
|
||||
#define MAKE_ARGS_11(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11) arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11
|
||||
#define MAKE_ARGS_12(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12) arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12
|
||||
//.. add as many MAKE_ARGS_* as there are MAKE_PARAMS_*
|
||||
|
||||
|
||||
|
||||
#define DEF_RELAYING_METHOD_4(NAME, t1, t2, t3, t4) \
|
||||
DEF_RELAYING_METHOD(NAME, MAKE_PARAMS_4(t1, t2, t3, t4), MAKE_ARGS_4(t1, t2, t3, t4))
|
||||
|
||||
#define DEF_RELAYING_METHOD_5(NAME, t1, t2, t3, t4, t5) \
|
||||
DEF_RELAYING_METHOD(NAME, MAKE_PARAMS_5(t1, t2, t3, t4, t5), MAKE_ARGS_5(t1, t2, t3, t4, t5))
|
||||
|
||||
#define DEF_RELAYING_METHOD_6(NAME, t1, t2, t3, t4, t5, t6) \
|
||||
DEF_RELAYING_METHOD(NAME, MAKE_PARAMS_6(t1, t2, t3, t4, t5, t6), MAKE_ARGS_6(t1, t2, t3, t4, t5, t6))
|
||||
|
||||
#define DEF_RELAYING_METHOD_7(NAME, t1, t2, t3, t4, t5, t6, t7) \
|
||||
DEF_RELAYING_METHOD(NAME, MAKE_PARAMS_7(t1, t2, t3, t4, t5, t6, t7), MAKE_ARGS_7(t1, t2, t3, t4, t5, t6, t7))
|
||||
|
||||
#define DEF_RELAYING_METHOD_8(NAME, t1, t2, t3, t4, t5, t6, t7, t8) \
|
||||
DEF_RELAYING_METHOD(NAME, MAKE_PARAMS_8(t1, t2, t3, t4, t5, t6, t7, t8), MAKE_ARGS_8(t1, t2, t3, t4, t5, t6, t7, t8))
|
||||
|
||||
#define DEF_RELAYING_METHOD_9(NAME, t1, t2, t3, t4, t5, t6, t7, t8, t9) \
|
||||
DEF_RELAYING_METHOD(NAME, MAKE_PARAMS_9(t1, t2, t3, t4, t5, t6, t7, t8, t9), MAKE_ARGS_9(t1, t2, t3, t4, t5, t6, t7, t8, t9))
|
||||
|
||||
#define DEF_RELAYING_METHOD_10(NAME, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10) \
|
||||
DEF_RELAYING_METHOD(NAME, MAKE_PARAMS_10(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10), MAKE_ARGS_10(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10))
|
||||
|
||||
#define DEF_RELAYING_METHOD_11(NAME, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11) \
|
||||
DEF_RELAYING_METHOD(NAME, MAKE_PARAMS_11(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11), MAKE_ARGS_11(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11))
|
||||
|
||||
#define DEF_RELAYING_METHOD_12(NAME, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12) \
|
||||
DEF_RELAYING_METHOD(NAME, MAKE_PARAMS_12(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12), MAKE_ARGS_12(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12))
|
||||
|
||||
#define DEF_RELAYING_METHOD(NAME, PARAMETERS, ARGUMENTS) \
|
||||
static void NAME(JNIEnv *env, jobject objectOrClass, jint parserId, PARAMETERS) \
|
||||
{ \
|
||||
std::map<int, JavaParser*>::iterator it = s_parsers.find(int(parserId)); \
|
||||
if (it != s_parsers.end()) \
|
||||
{ \
|
||||
it->second->do##NAME(ARGUMENTS); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
LOG_ERROR("parser with id " + std::to_string(parserId) + " not found"); \
|
||||
} \
|
||||
}
|
||||
|
||||
DEF_RELAYING_METHOD_8(RecordSymbol, jstring, jint, jint, jint, jint, jint, jint, jint)
|
||||
DEF_RELAYING_METHOD_4(RecordSymbolWithoutLocation, jstring, jint, jint, jint)
|
||||
DEF_RELAYING_METHOD_12(RecordSymbolWithScope, jstring, jint, jint, jint, jint, jint, jint, jint, jint, jint, jint, jint)
|
||||
DEF_RELAYING_METHOD_7(RecordReference, jint, jstring, jstring, jint, jint, jint, jint)
|
||||
DEF_RELAYING_METHOD_5(RecordLocalSymbol, jstring, jint, jint, jint, jint)
|
||||
DEF_RELAYING_METHOD_4(RecordComment, jint, jint, jint, jint)
|
||||
DEF_RELAYING_METHOD_7(RecordError, jstring, jint, jint, jint, jint, jint, jint)
|
||||
|
||||
static int s_nextParserId;
|
||||
static std::map<int, JavaParser*> s_parsers;
|
||||
static std::mutex s_parsersMutex;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void doRecordSymbol(
|
||||
jstring jSymbolName, jint jSymbolType,
|
||||
jint beginLine, jint beginColumn, jint endLine, jint endColumn,
|
||||
jint jAccess, jint jIsImplicit
|
||||
);
|
||||
|
||||
void doRecordSymbolWithoutLocation(
|
||||
jstring jSymbolName, jint jSymbolType,
|
||||
jint jAccess, jint jIsImplicit
|
||||
);
|
||||
|
||||
void doRecordSymbolWithScope(
|
||||
jstring jSymbolName, jint jSymbolType,
|
||||
jint beginLine, jint beginColumn, jint endLine, jint endColumn,
|
||||
jint scopeBeginLine, jint scopeBeginColumn, jint scopeEndLine, jint scopeEndColumn,
|
||||
jint jAccess, jint jIsImplicit
|
||||
);
|
||||
|
||||
void doRecordReference(jint jRefType, jstring jReferencedName, jstring jContextName, jint beginLine, jint beginColumn, jint endLine, jint endColumn);
|
||||
void doRecordLocalSymbol(jstring jSymbolName, jint beginLine, jint beginColumn, jint endLine, jint endColumn);
|
||||
void doRecordComment(jint beginLine, jint beginColumn, jint endLine, jint endColumn);
|
||||
void doRecordError(jstring jMessage, jint jFatal, jint jIndexed, jint beginLine, jint beginColumn, jint endLine, jint endColumn);
|
||||
|
||||
std::shared_ptr<FileRegister> m_fileRegister;
|
||||
std::shared_ptr<JavaEnvironment> m_javaEnvironment;
|
||||
|
||||
const int m_id;
|
||||
std::string m_currentFilePath;
|
||||
};
|
||||
|
||||
#endif // JAVA_PARSER_H
|
||||
@@ -0,0 +1,90 @@
|
||||
#include "data/parser/java/TaskParseJava.h"
|
||||
|
||||
#include "component/view/DialogView.h"
|
||||
#include "data/parser/java/JavaParser.h"
|
||||
#include "data/parser/ParserClientImpl.h"
|
||||
#include "data/StorageProvider.h"
|
||||
#include "utility/file/FileRegister.h"
|
||||
#include "utility/messaging/type/MessageFinishedParsing.h"
|
||||
#include "utility/scheduling/Blackboard.h"
|
||||
#include "utility/text/TextAccess.h"
|
||||
#include "utility/utility.h"
|
||||
|
||||
TaskParseJava::TaskParseJava(
|
||||
std::shared_ptr<StorageProvider> storageProvider,
|
||||
std::shared_ptr<FileRegister> fileRegister,
|
||||
const Parser::Arguments& arguments,
|
||||
DialogView* dialogView
|
||||
)
|
||||
: m_storageProvider(storageProvider)
|
||||
, m_fileRegister(fileRegister)
|
||||
, m_arguments(arguments)
|
||||
, m_dialogView(dialogView)
|
||||
, m_interrupted(false)
|
||||
{
|
||||
}
|
||||
|
||||
void TaskParseJava::doEnter(std::shared_ptr<Blackboard> blackboard)
|
||||
{
|
||||
int indexerCount = 0;
|
||||
if (blackboard->get("indexer_count", indexerCount))
|
||||
{
|
||||
indexerCount++;
|
||||
blackboard->set("indexer_count", indexerCount);
|
||||
}
|
||||
}
|
||||
|
||||
Task::TaskState TaskParseJava::doUpdate(std::shared_ptr<Blackboard> blackboard)
|
||||
{
|
||||
std::shared_ptr<ParserClientImpl> parserClient = std::make_shared<ParserClientImpl>();
|
||||
std::shared_ptr<JavaParser> parser = std::make_shared<JavaParser>(parserClient.get());
|
||||
|
||||
FilePath sourcePath = m_fileRegister->consumeSourceFile();
|
||||
|
||||
if (sourcePath.empty())
|
||||
{
|
||||
return STATE_FAILURE;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dialogView->updateIndexingDialog(
|
||||
m_fileRegister->getParsedSourceFilesCount(), m_fileRegister->getSourceFilesCount(), sourcePath.str()
|
||||
);
|
||||
|
||||
std::shared_ptr<IntermediateStorage> storage = m_storageProvider->popIndexerTarget();
|
||||
parserClient->setStorage(storage);
|
||||
parserClient->startParsingFile();
|
||||
|
||||
parser->parseFile(sourcePath, TextAccess::createFromFile(sourcePath.str()), m_arguments);
|
||||
|
||||
parserClient->finishParsingFile();
|
||||
parserClient->resetStorage();
|
||||
|
||||
if (!m_interrupted)
|
||||
{
|
||||
m_fileRegister->markThreadFilesParsed(); // todo: rename to markThreadFilesProcessed
|
||||
m_storageProvider->pushIndexerTarget(storage);
|
||||
}
|
||||
}
|
||||
|
||||
return (m_interrupted ? STATE_FAILURE : STATE_SUCCESS);
|
||||
}
|
||||
|
||||
void TaskParseJava::doExit(std::shared_ptr<Blackboard> blackboard)
|
||||
{
|
||||
int indexerCount = 0;
|
||||
if (blackboard->get("indexer_count", indexerCount))
|
||||
{
|
||||
indexerCount--;
|
||||
blackboard->set("indexer_count", indexerCount);
|
||||
}
|
||||
}
|
||||
|
||||
void TaskParseJava::doReset(std::shared_ptr<Blackboard> blackboard)
|
||||
{
|
||||
}
|
||||
|
||||
void TaskParseJava::handleMessage(MessageInterruptTasks* message)
|
||||
{
|
||||
m_interrupted = true;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#ifndef TASK_PARSE_JAVA_H
|
||||
#define TASK_PARSE_JAVA_H
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "data/parser/Parser.h"
|
||||
#include "utility/scheduling/Task.h"
|
||||
#include "utility/messaging/type/MessageInterruptTasks.h"
|
||||
#include "utility/messaging/MessageListener.h"
|
||||
|
||||
class DialogView;
|
||||
class FileRegister;
|
||||
class StorageProvider;
|
||||
|
||||
class TaskParseJava
|
||||
: public Task
|
||||
, public MessageListener<MessageInterruptTasks>
|
||||
{
|
||||
public:
|
||||
TaskParseJava(
|
||||
std::shared_ptr<StorageProvider> storageProvider,
|
||||
std::shared_ptr<FileRegister> fileRegister,
|
||||
const Parser::Arguments& arguments,
|
||||
DialogView* dialogView
|
||||
);
|
||||
|
||||
private:
|
||||
virtual void doEnter(std::shared_ptr<Blackboard> blackboard);
|
||||
virtual TaskState doUpdate(std::shared_ptr<Blackboard> blackboard);
|
||||
virtual void doExit(std::shared_ptr<Blackboard> blackboard);
|
||||
virtual void doReset(std::shared_ptr<Blackboard> blackboard);
|
||||
|
||||
virtual void handleMessage(MessageInterruptTasks* message);
|
||||
|
||||
std::shared_ptr<StorageProvider> m_storageProvider;
|
||||
std::shared_ptr<FileRegister> m_fileRegister;
|
||||
Parser::Arguments m_arguments;
|
||||
DialogView* m_dialogView;
|
||||
|
||||
bool m_interrupted;
|
||||
};
|
||||
|
||||
#endif // TASK_PARSE_JAVA_H
|
||||
Reference in New Issue
Block a user