data: indexing java

* expanded appsettings to include java specific stuff
* added java indexer as separate project that can be build via its build script
* added dependencies for java indexer to the setup folder
* added license files for these dependencies.
* added sample project for java. this is just to test java on other machines and can be removed again in the future.
* the java parser test suite is currently uncommented because java is not running on every machine.
* added some more node types
* removed TokenComponentAccess::AccessType and replaced all its usages by using AccessKind
* moved access components from edges to nodes
* using recordReference of ParserClient for java
* removed recording access specifier of inheritance edges.
* added styles for new node types
This commit is contained in:
malte_langkabel
2016-08-04 09:20:13 +02:00
parent 05c06a6102
commit b072972b50
122 changed files with 7291 additions and 696 deletions
+27
View File
@@ -0,0 +1,27 @@
#include "data/parser/AccessKind.h"
AccessKind intToAccessKind(int v)
{
switch (v)
{
case ACCESS_PUBLIC:
return ACCESS_PUBLIC;
case ACCESS_PROTECTED:
return ACCESS_PROTECTED;
case ACCESS_PRIVATE:
return ACCESS_PRIVATE;
case ACCESS_DEFAULT:
return ACCESS_DEFAULT;
case ACCESS_TEMPLATE_PARAMETER:
return ACCESS_TEMPLATE_PARAMETER;
case ACCESS_TYPE_PARAMETER:
return ACCESS_TYPE_PARAMETER;
}
return ACCESS_NONE;
}
int accessKindToInt(AccessKind t)
{
return t;
}
+18
View File
@@ -0,0 +1,18 @@
#ifndef ACCESS_KIND_H
#define ACCESS_KIND_H
enum AccessKind
{ // these values need to be the same as AccessType in Java code
ACCESS_NONE = 0,
ACCESS_PUBLIC = 1,
ACCESS_PROTECTED = 2,
ACCESS_PRIVATE = 3,
ACCESS_DEFAULT = 4,
ACCESS_TEMPLATE_PARAMETER = 5,
ACCESS_TYPE_PARAMETER = 6
};
AccessKind intToAccessKind(int v);
int accessKindToInt(AccessKind t);
#endif // ACCESS_KIND_H
+2
View File
@@ -17,6 +17,8 @@ public:
{
Arguments();
std::vector<FilePath> javaClassPaths;
std::vector<FilePath> headerSearchPaths;
std::vector<FilePath> systemHeaderSearchPaths;
std::vector<FilePath> frameworkSearchPaths;
+4 -3
View File
@@ -6,7 +6,7 @@
#include "data/type/DataType.h"
#include "utility/utilityString.h"
std::string ParserClient::addAccessPrefix(const std::string& str, AccessType access)
std::string ParserClient::addAccessPrefix(const std::string& str, AccessKind access)
{
switch (access)
{
@@ -16,9 +16,10 @@ std::string ParserClient::addAccessPrefix(const std::string& str, AccessType acc
return "protected " + str;
case ACCESS_PRIVATE:
return "private " + str;
case ACCESS_NONE:
return str;
case ACCESS_DEFAULT:
return "default " + str;
}
return str;
}
std::string ParserClient::addAbstractionPrefix(const std::string& str, AbstractionType abstraction)
+30 -17
View File
@@ -5,7 +5,9 @@
#include <vector>
#include "data/name/NameHierarchy.h"
#include "data/parser/SymbolType.h"
#include "data/parser/AccessKind.h"
#include "data/parser/ReferenceKind.h"
#include "data/parser/SymbolKind.h"
#include "utility/file/FileInfo.h"
#include "utility/types.h"
@@ -15,20 +17,13 @@ class DataType;
class ParserClient
{
public:
enum AccessType {
ACCESS_PUBLIC,
ACCESS_PROTECTED,
ACCESS_PRIVATE,
ACCESS_NONE
};
enum AbstractionType {
ABSTRACTION_VIRTUAL,
ABSTRACTION_PURE_VIRTUAL,
ABSTRACTION_NONE
};
static std::string addAccessPrefix(const std::string& str, AccessType access);
static std::string addAccessPrefix(const std::string& str, AccessKind access);
static std::string addAbstractionPrefix(const std::string& str, AbstractionType abstraction);
static std::string addStaticPrefix(const std::string& str, bool isStatic);
static std::string addConstPrefix(const std::string& str, bool isConst, bool atFront);
@@ -42,28 +37,46 @@ public:
virtual void startParsingFile() = 0;
virtual void finishParsingFile() = 0;
virtual Id recordSymbol(
const NameHierarchy& symbolName, SymbolKind symbolType,
AccessKind access = ACCESS_NONE, bool isImplicit = false) = 0;
virtual Id recordSymbol(
const NameHierarchy& symbolName, SymbolKind symbolType,
const ParseLocation& location,
AccessKind access = ACCESS_NONE, bool isImplicit = false) = 0;
virtual Id recordSymbol(
const NameHierarchy& symbolName, SymbolKind symbolType,
const ParseLocation& location, const ParseLocation& scopeLocation,
AccessKind access = ACCESS_NONE, bool isImplicit = false) = 0;
virtual void recordReference(
ReferenceKind referenceKind, const NameHierarchy& referencedName, const NameHierarchy& contextName,
const ParseLocation& location) = 0;
virtual void onError(const ParseLocation& location, const std::string& message, bool fatal, bool indexed) = 0;
virtual void onTypedefParsed(
const ParseLocation& location, const NameHierarchy& typedefName, AccessType access, bool isImplicit) = 0;
const ParseLocation& location, const NameHierarchy& typedefName, AccessKind access, bool isImplicit) = 0;
virtual void onClassParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessType access,
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessKind access,
const ParseLocation& scopeLocation, bool isImplicit) = 0;
virtual void onStructParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessType access,
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessKind access,
const ParseLocation& scopeLocation, bool isImplicit) = 0;
virtual void onGlobalVariableParsed(const ParseLocation& location, const NameHierarchy& variable, bool isImplicit) = 0;
virtual void onFieldParsed(const ParseLocation& location, const NameHierarchy& field, AccessType access, bool isImplicit) = 0;
virtual void onFieldParsed(const ParseLocation& location, const NameHierarchy& field, AccessKind access, bool isImplicit) = 0;
virtual void onFunctionParsed(
const ParseLocation& location, const NameHierarchy& function, const ParseLocation& scopeLocation, bool isImplicit) = 0;
virtual void onMethodParsed(
const ParseLocation& location, const NameHierarchy& method, AccessType access, AbstractionType abstraction,
const ParseLocation& location, const NameHierarchy& method, AccessKind access, AbstractionType abstraction,
const ParseLocation& scopeLocation, bool isImplicit) = 0;
virtual void onNamespaceParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy,
const ParseLocation& scopeLocation, bool isImplicit) = 0;
virtual void onEnumParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessType access,
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessKind access,
const ParseLocation& scopeLocation, bool isImplicit) = 0;
virtual void onEnumConstantParsed(const ParseLocation& location, const NameHierarchy& nameHierarchy, bool isImplicit) = 0;
virtual void onTemplateParameterTypeParsed(
@@ -76,13 +89,13 @@ public:
virtual void onInheritanceParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy,
const NameHierarchy& baseNameHierarchy, AccessType access) = 0;
const NameHierarchy& baseNameHierarchy) = 0;
virtual void onMethodOverrideParsed(
const ParseLocation& location, const NameHierarchy& overridden, const NameHierarchy& overrider) = 0;
virtual void onCallParsed(
const ParseLocation& location, const NameHierarchy& caller, const NameHierarchy& callee) = 0;
virtual void onUsageParsed(
const ParseLocation& location, const NameHierarchy& userName, SymbolType usedType, const NameHierarchy& usedName) = 0;
const ParseLocation& location, const NameHierarchy& userName, SymbolKind usedType, const NameHierarchy& usedName) = 0;
virtual void onTypeUsageParsed(const ParseLocation& location, const NameHierarchy& user, const NameHierarchy& used) = 0;
virtual void onTemplateArgumentTypeParsed(
+102 -51
View File
@@ -27,13 +27,57 @@ void ParserClientImpl::resetStorage()
void ParserClientImpl::startParsingFile()
{
m_nodeIdsToMemberEdgeIds.clear(); // remove this when one parserclient is created per file
}
void ParserClientImpl::finishParsingFile()
{
}
Id ParserClientImpl::recordSymbol(
const NameHierarchy& symbolName, SymbolKind symbolType,
AccessKind access, bool isImplicit
)
{
Id nodeId = addNodeHierarchy(symbolKindToNodeType(symbolType), symbolName, (isImplicit ? DEFINITION_IMPLICIT : DEFINITION_EXPLICIT));
addAccess(nodeId, access);
return nodeId;
}
Id ParserClientImpl::recordSymbol(
const NameHierarchy& symbolName, SymbolKind symbolType,
const ParseLocation& location,
AccessKind access, bool isImplicit
)
{
Id nodeId = recordSymbol(symbolName, symbolType, access, isImplicit);
addSourceLocation(nodeId, location, locationTypeToInt(LOCATION_TOKEN));
return nodeId;
}
Id ParserClientImpl::recordSymbol(
const NameHierarchy& symbolName, SymbolKind symbolType,
const ParseLocation& location, const ParseLocation& scopeLocation,
AccessKind access, bool isImplicit
)
{
Id nodeId = recordSymbol(symbolName, symbolType, location, access, isImplicit);
addSourceLocation(nodeId, scopeLocation, locationTypeToInt(LOCATION_SCOPE));
return nodeId;
}
void ParserClientImpl::recordReference(
ReferenceKind referenceKind, const NameHierarchy& referencedName, const NameHierarchy& contextName,
const ParseLocation& location)
{
Id contextNodeId = addNodeHierarchy(Node::NODE_UNDEFINED, contextName, DEFINITION_NONE);
Id referencedNodeId = addNodeHierarchy(Node::NODE_UNDEFINED, referencedName, DEFINITION_NONE);
Id edgeId = addEdge(referenceKindToEdgeType(referenceKind), contextNodeId, referencedNodeId);
addSourceLocation(edgeId, location, locationTypeToInt(LOCATION_TOKEN));
}
void ParserClientImpl::onError(const ParseLocation& location, const std::string& message, bool fatal, bool indexed)
{
log(std::string(fatal ? "FATAL: " : "ERROR: "), message, location);
@@ -47,7 +91,7 @@ void ParserClientImpl::onError(const ParseLocation& location, const std::string&
}
void ParserClientImpl::onTypedefParsed(
const ParseLocation& location, const NameHierarchy& typedefName, AccessType access, bool isImplicit)
const ParseLocation& location, const NameHierarchy& typedefName, AccessKind access, bool isImplicit)
{
log("typedef", typedefName.getQualifiedName(), location);
@@ -57,7 +101,7 @@ void ParserClientImpl::onTypedefParsed(
}
void ParserClientImpl::onClassParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessType access,
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessKind access,
const ParseLocation& scopeLocation, bool isImplicit)
{
log("class", nameHierarchy.getQualifiedName(), location);
@@ -73,7 +117,7 @@ void ParserClientImpl::onClassParsed(
}
void ParserClientImpl::onStructParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessType access,
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessKind access,
const ParseLocation& scopeLocation, bool isImplicit)
{
log("struct", nameHierarchy.getQualifiedName(), location);
@@ -96,7 +140,7 @@ void ParserClientImpl::onGlobalVariableParsed(const ParseLocation& location, con
addSourceLocation(nodeId, location, locationTypeToInt(LOCATION_TOKEN));
}
void ParserClientImpl::onFieldParsed(const ParseLocation& location, const NameHierarchy& field, AccessType access, bool isImplicit)
void ParserClientImpl::onFieldParsed(const ParseLocation& location, const NameHierarchy& field, AccessKind access, bool isImplicit)
{
log("field", field.getQualifiedName(), location);
@@ -116,7 +160,7 @@ void ParserClientImpl::onFunctionParsed(
}
void ParserClientImpl::onMethodParsed(
const ParseLocation& location, const NameHierarchy& method, AccessType access, AbstractionType abstraction,
const ParseLocation& location, const NameHierarchy& method, AccessKind access, AbstractionType abstraction, // todo: remove abstractio... better: remove this method!
const ParseLocation& scopeLocation, bool isImplicit)
{
log("method", method.getQualifiedNameWithSignature(), location);
@@ -142,7 +186,7 @@ void ParserClientImpl::onNamespaceParsed(
}
void ParserClientImpl::onEnumParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessType access,
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessKind access,
const ParseLocation& scopeLocation, bool isImplicit)
{
log("enum", nameHierarchy.getQualifiedName(), location);
@@ -168,7 +212,7 @@ void ParserClientImpl::onTemplateParameterTypeParsed(
Id nodeId = addNodeHierarchy(Node::NODE_TEMPLATE_PARAMETER_TYPE, templateParameterTypeNameHierarchy, (isImplicit ? DEFINITION_IMPLICIT : DEFINITION_EXPLICIT));
addSourceLocation(nodeId, location, locationTypeToInt(LOCATION_TOKEN));
addAccess(nodeId, TokenComponentAccess::ACCESS_TEMPLATE);
addAccess(nodeId, ACCESS_TEMPLATE_PARAMETER);
}
void ParserClientImpl::onLocalSymbolParsed(const std::string& name, const ParseLocation& location)
@@ -214,7 +258,7 @@ void ParserClientImpl::onCommentParsed(const ParseLocation& location)
void ParserClientImpl::onInheritanceParsed(
const ParseLocation& location, const NameHierarchy& childNameHierarchy,
const NameHierarchy& parentNameHierarchy, AccessType access)
const NameHierarchy& parentNameHierarchy)
{
log("inheritance", childNameHierarchy.getQualifiedName() + " : " + parentNameHierarchy.getQualifiedName(), location);
@@ -246,12 +290,12 @@ void ParserClientImpl::onCallParsed(const ParseLocation& location, const NameHie
}
void ParserClientImpl::onUsageParsed(
const ParseLocation& location, const NameHierarchy& userName, SymbolType usedType, const NameHierarchy& usedName)
const ParseLocation& location, const NameHierarchy& userName, SymbolKind usedType, const NameHierarchy& usedName)
{
log("usage", userName.getQualifiedNameWithSignature() + " -> " + usedName.getQualifiedName(), location);
Id userNodeId = addNodeHierarchy(Node::NODE_UNDEFINED, userName, DEFINITION_NONE);
Id usedNodeId = addNodeHierarchy(symbolTypeToNodeType(usedType), usedName, DEFINITION_NONE);
Id usedNodeId = addNodeHierarchy(symbolKindToNodeType(usedType), usedName, DEFINITION_NONE);
Id edgeId = addEdge(Edge::EDGE_USAGE, userNodeId, usedNodeId);
addSourceLocation(edgeId, location, locationTypeToInt(LOCATION_TOKEN));
}
@@ -354,10 +398,12 @@ void ParserClientImpl::onMacroExpandParsed(const ParseLocation &location, const
addSourceLocation(edgeId, location, locationTypeToInt(LOCATION_TOKEN));
}
Node::NodeType ParserClientImpl::symbolTypeToNodeType(SymbolType symbolType) const
Node::NodeType ParserClientImpl::symbolKindToNodeType(SymbolKind symbolType) const
{
switch (symbolType)
{
case SYMBOL_BUILTIN_TYPE:
return Node::NODE_BUILTIN_TYPE;
case SYMBOL_CLASS:
return Node::NODE_CLASS;
case SYMBOL_ENUM:
@@ -370,18 +416,24 @@ Node::NodeType ParserClientImpl::symbolTypeToNodeType(SymbolType symbolType) con
return Node::NODE_FUNCTION;
case SYMBOL_GLOBAL_VARIABLE:
return Node::NODE_GLOBAL_VARIABLE;
case SYMBOL_INTERFACE:
return Node::NODE_INTERFACE;
case SYMBOL_MACRO:
return Node::NODE_MACRO;
case SYMBOL_METHOD:
return Node::NODE_METHOD;
case SYMBOL_NAMESPACE:
return Node::NODE_NAMESPACE;
case SYMBOL_PACKAGE:
return Node::NODE_PACKAGE;
case SYMBOL_STRUCT:
return Node::NODE_STRUCT;
case SYMBOL_TYPEDEF:
return Node::NODE_TYPEDEF;
case SYMBOL_TEMPLATE_PARAMETER:
return Node::NODE_TEMPLATE_PARAMETER_TYPE;
case SYMBOL_TYPEDEF:
return Node::NODE_TYPEDEF;
case SYMBOL_TYPE_PARAMETER:
return Node::NODE_TYPE_PARAMETER;
case SYMBOL_UNION:
return Node::NODE_TYPE;
default:
@@ -390,34 +442,48 @@ Node::NodeType ParserClientImpl::symbolTypeToNodeType(SymbolType symbolType) con
return Node::NODE_UNDEFINED;
}
TokenComponentAccess::AccessType ParserClientImpl::convertAccessType(ParserClient::AccessType access) const
Edge::EdgeType ParserClientImpl::referenceKindToEdgeType(ReferenceKind referenceKind) const
{
switch (access)
switch (referenceKind)
{
case ACCESS_PUBLIC:
return TokenComponentAccess::ACCESS_PUBLIC;
case ACCESS_PROTECTED:
return TokenComponentAccess::ACCESS_PROTECTED;
case ACCESS_PRIVATE:
return TokenComponentAccess::ACCESS_PRIVATE;
case ACCESS_NONE:
return TokenComponentAccess::ACCESS_NONE;
case REFERENCE_TYPE_USAGE:
return Edge::EDGE_TYPE_USAGE;
case REFERENCE_USAGE:
return Edge::EDGE_USAGE;
case REFERENCE_CALL:
return Edge::EDGE_CALL;
case REFERENCE_INHERITANCE:
return Edge::EDGE_INHERITANCE;
case REFERENCE_OVERRIDE:
return Edge::EDGE_OVERRIDE;
case REFERENCE_TEMPLATE_ARGUMENT:
return Edge::EDGE_TEMPLATE_ARGUMENT;
case REFERENCE_TYPE_ARGUMENT:
return Edge::EDGE_TYPE_ARGUMENT;
case REFERENCE_TEMPLATE_DEFAULT_ARGUMENT:
return Edge::EDGE_TEMPLATE_DEFAULT_ARGUMENT;
case REFERENCE_TEMPLATE_SPECIALIZATION_OF:
return Edge::EDGE_TEMPLATE_SPECIALIZATION_OF;
case REFERENCE_TEMPLATE_MEMBER_SPECIALIZATION_OF:
return Edge::EDGE_TEMPLATE_MEMBER_SPECIALIZATION_OF;
case REFERENCE_INCLUDE:
return Edge::EDGE_INCLUDE;
case REFERENCE_IMPORT:
return Edge::EDGE_IMPORT;
case REFERENCE_MACRO_USAGE:
return Edge::EDGE_MACRO_USAGE;
default:
break;
}
return Edge::EDGE_UNDEFINED;
}
void ParserClientImpl::addAccess(Id nodeId, ParserClient::AccessType access)
void ParserClientImpl::addAccess(Id nodeId, AccessKind access)
{
addAccess(nodeId, convertAccessType(access));
}
void ParserClientImpl::addAccess(Id nodeId, TokenComponentAccess::AccessType access)
{
if (access == TokenComponentAccess::ACCESS_NONE)
if (access != ACCESS_NONE)
{
return;
addComponentAccess(nodeId, accessKindToInt(access));
}
addComponentAccess(nodeId, access);
}
Id ParserClientImpl::addNodeHierarchy(Node::NodeType nodeType, NameHierarchy nameHierarchy, DefinitionType definitionType)
@@ -493,14 +559,7 @@ Id ParserClientImpl::addEdge(int type, Id sourceId, Id targetId)
return 0;
}
Id edgeId = m_storage->addEdge(type, sourceId, targetId);
if (type == Edge::EDGE_MEMBER)
{
m_nodeIdsToMemberEdgeIds[targetId] = edgeId;
}
return edgeId;
return m_storage->addEdge(type, sourceId, targetId);
}
Id ParserClientImpl::addLocalSymbol(const std::string& name)
@@ -549,15 +608,7 @@ void ParserClientImpl::addComponentAccess(Id nodeId , int type)
return;
}
std::unordered_map<Id, Id>::const_iterator it = m_nodeIdsToMemberEdgeIds.find(nodeId);
if (it != m_nodeIdsToMemberEdgeIds.end())
{
m_storage->addComponentAccess(it->second, type);
}
else
{
LOG_ERROR_STREAM(<< "Cannot assign access" << type << " to node id " << nodeId << " because it's not a child node.");
}
m_storage->addComponentAccess(nodeId, type);
}
void ParserClientImpl::addCommentLocation(const ParseLocation& location)
+32 -13
View File
@@ -1,6 +1,8 @@
#ifndef PARSER_CLIENT_IMPL_H
#define PARSER_CLIENT_IMPL_H
#include <set>
#include "data/graph/Node.h"
#include "data/parser/ParserClient.h"
#include "data/IntermediateStorage.h"
@@ -21,28 +23,47 @@ public:
virtual void startParsingFile();
virtual void finishParsingFile();
virtual Id recordSymbol(
const NameHierarchy& symbolName, SymbolKind symbolType,
AccessKind access = ACCESS_NONE, bool isImplicit = false);
virtual Id recordSymbol(
const NameHierarchy& symbolName, SymbolKind symbolType,
const ParseLocation& location,
AccessKind access = ACCESS_NONE, bool isImplicit = false);
virtual Id recordSymbol(
const NameHierarchy& symbolName, SymbolKind symbolType,
const ParseLocation& location, const ParseLocation& scopeLocation,
AccessKind access = ACCESS_NONE, bool isImplicit = false);
virtual void recordReference(
ReferenceKind referenceKind, const NameHierarchy& referencedName, const NameHierarchy& contextName,
const ParseLocation& location);
virtual void onError(const ParseLocation& location, const std::string& message, bool fatal, bool indexed);
virtual void onTypedefParsed(
const ParseLocation& location, const NameHierarchy& typedefName, AccessType access, bool isImplicit);
const ParseLocation& location, const NameHierarchy& typedefName, AccessKind access, bool isImplicit);
virtual void onClassParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessType access,
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessKind access,
const ParseLocation& scopeLocation, bool isImplicit);
virtual void onStructParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessType access,
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessKind access,
const ParseLocation& scopeLocation, bool isImplicit);
virtual void onGlobalVariableParsed(const ParseLocation& location, const NameHierarchy& variable, bool isImplicit);
virtual void onFieldParsed(const ParseLocation& location, const NameHierarchy& field, AccessType access, bool isImplicit);
virtual void onFieldParsed(const ParseLocation& location, const NameHierarchy& field, AccessKind access, bool isImplicit);
virtual void onFunctionParsed(
const ParseLocation& location, const NameHierarchy& function, const ParseLocation& scopeLocation, bool isImplicit);
virtual void onMethodParsed(
const ParseLocation& location, const NameHierarchy& method, AccessType access, AbstractionType abstraction,
const ParseLocation& location, const NameHierarchy& method, AccessKind access, AbstractionType abstraction,
const ParseLocation& scopeLocation, bool isImplicit);
virtual void onNamespaceParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy,
const ParseLocation& scopeLocation, bool isImplicit);
virtual void onEnumParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessType access,
const ParseLocation& location, const NameHierarchy& nameHierarchy, AccessKind access,
const ParseLocation& scopeLocation, bool isImplicit);
virtual void onEnumConstantParsed(const ParseLocation& location, const NameHierarchy& nameHierarchy, bool isImplicit);
virtual void onTemplateParameterTypeParsed(
@@ -55,13 +76,13 @@ public:
virtual void onInheritanceParsed(
const ParseLocation& location, const NameHierarchy& nameHierarchy,
const NameHierarchy& baseNameHierarchy, AccessType access);
const NameHierarchy& baseNameHierarchy);
virtual void onMethodOverrideParsed(
const ParseLocation& location, const NameHierarchy& overridden, const NameHierarchy& overrider);
virtual void onCallParsed(
const ParseLocation& location, const NameHierarchy& caller, const NameHierarchy& callee);
virtual void onUsageParsed(
const ParseLocation& location, const NameHierarchy& userName, SymbolType usedType, const NameHierarchy& usedName);
const ParseLocation& location, const NameHierarchy& userName, SymbolKind usedType, const NameHierarchy& usedName);
virtual void onTypeUsageParsed(const ParseLocation& location, const NameHierarchy& user, const NameHierarchy& used);
virtual void onTemplateArgumentTypeParsed(
@@ -83,10 +104,9 @@ public:
const ParseLocation& location, const NameHierarchy& macroNameHierarchy);
private:
Node::NodeType symbolTypeToNodeType(SymbolType symbolType) const;
TokenComponentAccess::AccessType convertAccessType(ParserClient::AccessType access) const;
void addAccess(Id nodeId, ParserClient::AccessType access);
void addAccess(Id nodeId, TokenComponentAccess::AccessType access);
Node::NodeType symbolKindToNodeType(SymbolKind symbolType) const;
Edge::EdgeType referenceKindToEdgeType(ReferenceKind referenceKind) const;
void addAccess(Id nodeId, AccessKind access);
Id addNodeHierarchy(Node::NodeType nodeType, NameHierarchy nameHierarchy, DefinitionType definitionType);
Id addFile(const std::string& name, const std::string& filePath, const std::string& modificationTime);
@@ -102,7 +122,6 @@ private:
void log(std::string type, std::string str, const ParseLocation& location) const;
std::shared_ptr<IntermediateStorage> m_storage;
std::unordered_map<Id, Id> m_nodeIdsToMemberEdgeIds;
};
#endif // PARSER_CLIENT_IMPL_H
+40
View File
@@ -0,0 +1,40 @@
#include "data/parser/ReferenceKind.h"
ReferenceKind intToReferenceKind(int v)
{
switch (v)
{
case REFERENCE_TYPE_USAGE:
return REFERENCE_TYPE_USAGE;
case REFERENCE_USAGE:
return REFERENCE_USAGE;
case REFERENCE_CALL:
return REFERENCE_CALL;
case REFERENCE_INHERITANCE:
return REFERENCE_INHERITANCE;
case REFERENCE_OVERRIDE:
return REFERENCE_OVERRIDE;
case REFERENCE_TEMPLATE_ARGUMENT:
return REFERENCE_TEMPLATE_ARGUMENT;
case REFERENCE_TYPE_ARGUMENT:
return REFERENCE_TYPE_ARGUMENT;
case REFERENCE_TEMPLATE_DEFAULT_ARGUMENT:
return REFERENCE_TEMPLATE_DEFAULT_ARGUMENT;
case REFERENCE_TEMPLATE_SPECIALIZATION_OF:
return REFERENCE_TEMPLATE_SPECIALIZATION_OF;
case REFERENCE_TEMPLATE_MEMBER_SPECIALIZATION_OF:
return REFERENCE_TEMPLATE_MEMBER_SPECIALIZATION_OF;
case REFERENCE_INCLUDE:
return REFERENCE_INCLUDE;
case REFERENCE_IMPORT:
return REFERENCE_IMPORT;
case REFERENCE_MACRO_USAGE:
return REFERENCE_MACRO_USAGE;
}
return REFERENCE_UNDEFINED;
}
int referenceKindToInt(ReferenceKind t)
{
return t;
}
+25
View File
@@ -0,0 +1,25 @@
#ifndef REFERENCE_KIND_H
#define REFERENCE_KIND_H
enum ReferenceKind
{ // these values need to be the same as ReferenceKind in Java code
REFERENCE_UNDEFINED = 0,
REFERENCE_TYPE_USAGE = 1,
REFERENCE_USAGE = 2,
REFERENCE_CALL = 3,
REFERENCE_INHERITANCE = 4,
REFERENCE_OVERRIDE = 5,
REFERENCE_TEMPLATE_ARGUMENT = 6,
REFERENCE_TYPE_ARGUMENT = 7,
REFERENCE_TEMPLATE_DEFAULT_ARGUMENT = 8,
REFERENCE_TEMPLATE_SPECIALIZATION_OF = 9,
REFERENCE_TEMPLATE_MEMBER_SPECIALIZATION_OF = 10,
REFERENCE_INCLUDE = 11,
REFERENCE_IMPORT = 12,
REFERENCE_MACRO_USAGE = 13
};
ReferenceKind intToReferenceKind(int v);
int referenceKindToInt(ReferenceKind t);
#endif // REFERENCE_KIND_H
+53
View File
@@ -0,0 +1,53 @@
#include "data/parser/SymbolKind.h"
SymbolKind intToSymbolKind(int v)
{
switch (v)
{
case SYMBOL_BUILTIN_TYPE:
return SYMBOL_BUILTIN_TYPE;
case SYMBOL_CLASS:
return SYMBOL_CLASS;
case SYMBOL_ENUM:
return SYMBOL_ENUM;
case SYMBOL_ENUM_CONSTANT:
return SYMBOL_ENUM_CONSTANT;
case SYMBOL_FIELD:
return SYMBOL_FIELD;
case SYMBOL_FUNCTION:
return SYMBOL_FUNCTION;
case SYMBOL_GLOBAL_VARIABLE:
return SYMBOL_GLOBAL_VARIABLE;
case SYMBOL_INTERFACE:
return SYMBOL_INTERFACE;
case SYMBOL_LOCAL_VARIABLE:
return SYMBOL_LOCAL_VARIABLE;
case SYMBOL_MACRO:
return SYMBOL_MACRO;
case SYMBOL_METHOD:
return SYMBOL_METHOD;
case SYMBOL_NAMESPACE:
return SYMBOL_NAMESPACE;
case SYMBOL_PACKAGE:
return SYMBOL_PACKAGE;
case SYMBOL_PARAMETER:
return SYMBOL_PARAMETER;
case SYMBOL_STRUCT:
return SYMBOL_STRUCT;
case SYMBOL_TEMPLATE_PARAMETER:
return SYMBOL_TEMPLATE_PARAMETER;
case SYMBOL_TYPEDEF:
return SYMBOL_TYPEDEF;
case SYMBOL_TYPE_PARAMETER:
return SYMBOL_TYPE_PARAMETER;
case SYMBOL_UNION:
return SYMBOL_UNION;
}
return SYMBOL_KIND_MAX;
}
int symbolKindToInt(SymbolKind t)
{
return t;
}
+31
View File
@@ -0,0 +1,31 @@
#ifndef SYMBOL_KIND_H
#define SYMBOL_KIND_H
enum SymbolKind
{ // these values need to be the same as SymbolType in Java code
SYMBOL_BUILTIN_TYPE = 1,
SYMBOL_CLASS = 2,
SYMBOL_ENUM = 3,
SYMBOL_ENUM_CONSTANT = 4,
SYMBOL_FIELD = 5,
SYMBOL_FUNCTION = 6,
SYMBOL_GLOBAL_VARIABLE = 7,
SYMBOL_INTERFACE = 8,
SYMBOL_LOCAL_VARIABLE = 9,
SYMBOL_MACRO = 10,
SYMBOL_METHOD = 11,
SYMBOL_NAMESPACE = 12,
SYMBOL_PACKAGE = 13,
SYMBOL_PARAMETER = 14,
SYMBOL_STRUCT = 15,
SYMBOL_TEMPLATE_PARAMETER = 16,
SYMBOL_TYPEDEF = 17,
SYMBOL_TYPE_PARAMETER = 18,
SYMBOL_UNION = 19,
SYMBOL_KIND_MAX = 20
};
SymbolKind intToSymbolKind(int v);
int symbolKindToInt(SymbolKind t);
#endif // SYMBOL_KIND_H
-24
View File
@@ -1,24 +0,0 @@
#ifndef SYMBOL_TYPE_H
#define SYMBOL_TYPE_H
enum SymbolType
{
SYMBOL_CLASS,
SYMBOL_ENUM,
SYMBOL_ENUM_CONSTANT,
SYMBOL_FIELD,
SYMBOL_FUNCTION,
SYMBOL_GLOBAL_VARIABLE,
SYMBOL_LOCAL_VARIABLE,
SYMBOL_MACRO,
SYMBOL_METHOD,
SYMBOL_NAMESPACE,
SYMBOL_PARAMETER,
SYMBOL_STRUCT,
SYMBOL_TYPEDEF,
SYMBOL_TEMPLATE_PARAMETER,
SYMBOL_UNION,
SYMBOL_TYPE_MAX
};
#endif // SYMBOL_TYPE_H
+3 -6
View File
@@ -5,22 +5,21 @@
#include "data/parser/Parser.h"
#include "data/parser/ParserClientImpl.h"
#include "utility/scheduling/Task.h"
#include "utility/scheduling/TaskDecorator.h"
#include "utility/TimePoint.h"
class PersistentStorage;
class FileRegister;
class CxxParser;
class TaskParseWrapper
: public Task
: public TaskDecorator
{
public:
TaskParseWrapper(
std::shared_ptr<Task> child,
PersistentStorage* storage,
std::shared_ptr<FileRegister> fileRegister
);
virtual ~TaskParseWrapper();
virtual void enter();
virtual TaskState update();
@@ -30,10 +29,8 @@ public:
virtual void revert();
private:
std::shared_ptr<Task> m_child;
PersistentStorage* m_storage;
std::shared_ptr<FileRegister> m_fileRegister;
TimePoint m_start;
};
@@ -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 (int 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,170 @@
#include "data/parser/java/JavaEnvironmentFactory.h"
#include <jni.h>
#include "data/parser/java/JavaEnvironment.h"
#include "settings/ApplicationSettings.h"
#include "utility/logging/logging.h"
void JavaEnvironmentFactory::createInstance(std::string classPath)
{
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.
return;
}
}
s_classPath = classPath;
#ifdef _WIN32
{ // todo: make this windows only
std::string env1 = getenv("path");
std::string javapath = ApplicationSettings::getInstance()->getJavaPath() + "/client/";
putenv(("path=" + env1 + ";" + javapath).c_str()); // path env is only modified in the scope of this process.
}
#endif
using namespace std;
JavaVM* jvm; // Pointer to the JVM (Java Virtual Machine)
JNIEnv* env; // 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 = "-Xms1m";
std::string maximumMemoryOprionString = "-Xmx" + std::to_string(ApplicationSettings::getInstance()->getJavaMaximumMemory()) + "m";
options[2].optionString = const_cast<char*>(maximumMemoryOprionString.c_str());
// options[3].optionString = "-verbose:jni";
vm_args.version = JNI_VERSION_1_6; // minimum Java version
vm_args.nOptions = 3; // number of options
vm_args.options = options;
vm_args.ignoreUnrecognized = false; // invalid options make the JVM init fail
jint rc = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args); // YES !!
delete options;
if(rc != JNI_OK)
{
if(rc == JNI_EVERSION)
{
LOG_ERROR("JVM is oudated and doesn't meet requirements");
}
else if(rc == JNI_ENOMEM)
{
LOG_ERROR("not enough memory for JVM");
}
else if(rc == JNI_EINVAL)
{
LOG_ERROR("invalid ragument for launching JVM");
}
else if(rc == JNI_EEXIST)
{
LOG_ERROR("the process can only launch one JVM an not more");
}
else
{
LOG_ERROR_STREAM(<< "could not create the JVM instance (error code " << 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);
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
+37
View File
@@ -0,0 +1,37 @@
#ifndef TASK_PARSE_JAVA_H
#define TASK_PARSE_JAVA_H
#include <mutex>
#include "data/parser/Parser.h"
#include "utility/scheduling/Task.h"
class FileRegister;
class PersistentStorage;
class TaskParseJava
: public Task
{
public:
TaskParseJava(
PersistentStorage* storage,
std::shared_ptr<std::mutex> storageMutex,
std::shared_ptr<FileRegister> fileRegister,
const Parser::Arguments& arguments
);
virtual void enter();
virtual TaskState update();
virtual void exit();
virtual void interrupt();
virtual void revert();
private:
PersistentStorage* m_storage;
std::shared_ptr<std::mutex> m_storageMutex;
std::shared_ptr<FileRegister> m_fileRegister;
Parser::Arguments m_arguments;
};
#endif // TASK_PARSE_JAVA_H