logic: auto-detection for java root source directories

* implemented auto-detecting root source directories for java projects
* revised help texts in java project setup
This commit is contained in:
malte_langkabel
2016-10-07 11:44:14 +02:00
parent 0bb17b08d3
commit ee7bf4e9b7
6 changed files with 167 additions and 45 deletions
+25 -11
View File
@@ -6,12 +6,12 @@ import java.io.StringReader;
import java.lang.String;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.PackageDeclaration;
import com.github.javaparser.JavaParser;
import com.github.javaparser.ParseException;
import com.github.javaparser.ParseProblemException;
import com.github.javaparser.Problem;
import com.github.javaparser.Token;
import me.tomassetti.symbolsolver.javaparser.Navigator;
import me.tomassetti.symbolsolver.javaparsermodel.JavaParserFacade;
import me.tomassetti.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
import me.tomassetti.symbolsolver.resolution.typesolvers.JarTypeSolver;
@@ -91,17 +91,31 @@ public class JavaIndexer
}
JavaParserFacade.clearInstances();
// String fileName = filePath.substring(filePath.lastIndexOf("/"), filePath.lastIndexOf(".java"));
// System.gc();
// HeapDumper.dumpHeap("D:/dump/" + fileName, false);
}
public static String getPackageName(String fileContent)
{
String packageName = "";
try
{
CompilationUnit cu = JavaParser.parse(new StringReader(fileContent), true);
PackageDeclaration pd = Navigator.findNodeOfGivenClass(cu, PackageDeclaration.class);
if (pd != null)
{
packageName = JavaparserDeclNameResolver.getQualifiedName(pd.getName()).toString();
}
}
catch (ParseProblemException e)
{
// do nothing
}
catch (IllegalArgumentException e)
{
// do nothing
}
return packageName;
}
static public void recordSymbol(
int address, String symbolName, SymbolType symbolType,
@@ -212,8 +212,7 @@ QtProjectWizzardContentPathsSourceJava::QtProjectWizzardContentPathsSourceJava(
{
setHelpString(
"Project Paths define the files and directories that will be indexed by Coati. Provide a directory to recursively "
"add all contained files. To make sure that type names are resolved correctly, <b>please add the root source directory "
"of your project</b> (the one where all your package names are relative to).<br />"
"add all contained files.<br />"
"<br />"
"If your project's source code resides in one location, but generated source files are kept at a different location, "
"you will also need to add that directory."
@@ -465,7 +464,7 @@ QtProjectWizzardContentPathsClassJava::QtProjectWizzardContentPathsClassJava(
setTitleString("Class Path");
setHelpString(
"Enter all the .jar files your project depends on. If your project depends on uncompiled java code that should "
"not be indexed, please add the root directory of those .java files here."
"not be indexed, please add the root directory of those .java files here (the one where all the package names are relative to)."
);
}
+63 -3
View File
@@ -1,9 +1,14 @@
#include "JavaProject.h"
#include "component/view/DialogView.h"
#include "data/parser/java/JavaEnvironmentFactory.h"
#include "data/parser/java/JavaEnvironment.h"
#include "data/parser/java/TaskParseJava.h"
#include "utility/file/FileRegister.h"
#include "utility/text/TextAccess.h"
#include "utility/messaging/type/MessageStatus.h"
#include "utility/ResourcePaths.h"
#include "utility/utilityString.h"
#include "Application.h"
#include "isTrial.h"
@@ -31,6 +36,8 @@ const std::shared_ptr<ProjectSettings> JavaProject::getProjectSettings() const
bool JavaProject::prepareIndexing()
{
m_rootDirectories.reset();
std::string errorString;
if (!JavaEnvironmentFactory::getInstance() && !isTrial())
{
@@ -89,11 +96,18 @@ std::shared_ptr<Task> JavaProject::createIndexerTask(
}
}
for (FilePath sourcePath: m_projectSettings->getAbsoluteSourcePaths())
if (!m_rootDirectories)
{
if (sourcePath.extension().empty() && sourcePath.exists())
getDialogView()->showProgressDialog("Preparing Project", "Gathering Root\nDirectories");
fetchRootDirectories();
getDialogView()->hideProgressDialog();
}
for (FilePath rootDirectory: *(m_rootDirectories.get()))
{
if (rootDirectory.exists())
{
arguments.javaClassPaths.push_back(sourcePath.str());
arguments.javaClassPaths.push_back(rootDirectory.str());
}
}
@@ -114,3 +128,49 @@ void JavaProject::updateFileManager(FileManager& fileManager)
fileManager.setPaths(sourcePaths, headerPaths, excludePaths, sourceExtensions);
}
void JavaProject::fetchRootDirectories()
{
m_rootDirectories = std::make_shared<std::set<FilePath>>();
FileManager fileManager;
fileManager.setPaths(
m_projectSettings->getAbsoluteSourcePaths(),
std::vector<FilePath>(),
m_projectSettings->getAbsoluteExcludePaths(),
m_projectSettings->getSourceExtensions()
);
fileManager.fetchFilePaths(std::vector<FileInfo>());
std::shared_ptr<JavaEnvironment> javaEnvironment = JavaEnvironmentFactory::getInstance()->createEnvironment();
for (FilePath filePath: fileManager.getAddedFilePaths())
{
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromFile(filePath.str());
std::string packageName = "";
javaEnvironment->callStaticMethod("io/coati/JavaIndexer", "getPackageName", packageName, textAccess->getText());
if (packageName.empty())
{
continue;
}
FilePath rootPath = filePath.parentDirectory();
bool success = true;
const std::vector<std::string> packageNameParts = utility::splitToVector(packageName, ".");
for (std::vector<std::string>::const_reverse_iterator it = packageNameParts.rbegin(); it != packageNameParts.rend(); it++)
{
if (rootPath.fileName() != (*it))
{
success = false;
break;
}
rootPath = rootPath.parentDirectory();
}
if (success)
{
m_rootDirectories->insert(rootPath);
}
}
}
+3
View File
@@ -30,8 +30,11 @@ private:
std::shared_ptr<FileRegister> fileRegister);
virtual void updateFileManager(FileManager& fileManager);
void fetchRootDirectories();
std::shared_ptr<JavaProjectSettings> m_projectSettings;
std::shared_ptr<std::set<FilePath>> m_rootDirectories;
friend Project;
};
@@ -12,31 +12,33 @@ JavaEnvironment::~JavaEnvironment()
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)
jclass javaClass = getJavaClass(className);
jmethodID javaMethodId = getJavaStaticMethod(javaClass, methodName, "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
if(javaMethodId != nullptr)
{
LOG_ERROR("class " + className + " not found in JVM environment");
jthrowable exc = m_env->ExceptionOccurred();
if(exc)
{
m_env->ExceptionDescribe();
m_env->ExceptionClear();
}
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;
}
else
return false;
}
bool JavaEnvironment::callStaticMethod(std::string className, std::string methodName, std::string& ret, std::string arg1)
{
jclass javaClass = getJavaClass(className);
jmethodID javaMethodId = getJavaStaticMethod(javaClass, methodName, "(Ljava/lang/String;)Ljava/lang/String;");
if(javaMethodId != nullptr)
{
jmethodID javaMethodId = m_env->GetStaticMethodID(javaClass, methodName.c_str(), "(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
if(javaMethodId == nullptr)
jstring jarg1 = m_env->NewStringUTF(arg1.c_str());
jstring jret = (jstring)m_env->CallStaticObjectMethod(javaClass, javaMethodId, jarg1);
if (jret)
{
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);
const char *buffer = m_env->GetStringUTFChars(jret, JNI_FALSE);
ret = std::string(buffer);
m_env->ReleaseStringUTFChars(jret, buffer);
return true;
}
}
@@ -56,13 +58,6 @@ 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()];
@@ -90,3 +85,44 @@ void JavaEnvironment::registerNativeMethods(std::string className, std::vector<N
delete [] jniMethods;
}
JavaEnvironment::JavaEnvironment(JavaVM* jvm, JNIEnv* env)
: m_jvm(jvm)
, m_env(env)
{
JavaEnvironmentFactory::getInstance()->registerEnvironment();
}
jclass JavaEnvironment::getJavaClass(const std::string& className)
{
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();
}
}
return javaClass;
}
jmethodID JavaEnvironment::getJavaStaticMethod(const std::string& className, const std::string& methodName, const std::string& methodSignature)
{
return getJavaStaticMethod(getJavaClass(className), methodName, methodSignature);
}
jmethodID JavaEnvironment::getJavaStaticMethod(jclass javaClass, const std::string& methodName, const std::string& methodSignature)
{
if(javaClass != nullptr)
{
jmethodID javaMethodId = m_env->GetStaticMethodID(javaClass, methodName.c_str(), methodSignature.c_str());
if(javaMethodId == nullptr)
{
LOG_ERROR("method " + methodName + methodSignature + " not found in JVM environment");
}
return javaMethodId;
}
return nullptr;
}
@@ -10,9 +10,15 @@ typedef JavaVM_ JavaVM;
struct JNIEnv_;
typedef JNIEnv_ JNIEnv;
class _jclass;
typedef _jclass *jclass;
class _jstring;
typedef _jstring *jstring;
struct _jmethodID;
typedef struct _jmethodID *jmethodID;
class JavaEnvironmentFactory;
class JavaEnvironment
@@ -27,6 +33,7 @@ public:
~JavaEnvironment();
bool callStaticVoidMethod(std::string className, std::string methodName, int arg1, std::string arg2, std::string arg3, std::string arg4);
bool callStaticMethod(std::string className, std::string methodName, std::string& ret, std::string arg1);
std::string toStdString(jstring s);
jstring toJString(std::string s);
@@ -36,6 +43,9 @@ private:
friend class JavaEnvironmentFactory;
JavaEnvironment(JavaVM* jvm, JNIEnv* env);
jclass getJavaClass(const std::string& className);
jmethodID getJavaStaticMethod(const std::string& className, const std::string& methodName, const std::string& methodSignature);
jmethodID getJavaStaticMethod(jclass javaClass, const std::string& methodName, const std::string& methodSignature);
JavaVM* m_jvm;
JNIEnv* m_env;