Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Add fine grained weight properties for dependencies between internal Typescript modules

// Get the top level dependency between a Typescript module and the external modules it uses
MATCH (source:TS:Module)-[moduleDependency:DEPENDS_ON]->(target:Module)
// Exclude all targets where an ExternalModule was found that resolves to them
// because those are covered in the fine grained weights for "ExternalModule"s.
WHERE NOT EXISTS { (target)<-[:RESOLVES_TO]-(resolvedTarget:ExternalModule) }
WITH source
,target
,moduleDependency
OPTIONAL MATCH (source)-[elementDependency:DEPENDS_ON]->(elementType:TS)<-[:EXPORTS]-(target)
WITH source
,target
,moduleDependency
,count(DISTINCT elementType.globalFqn) AS elementTypeCount
,sum(elementDependency.cardinality) AS elementTypeCardinality
,collect(DISTINCT elementType.globalFqn)[0..4] AS elementTypeExamples
OPTIONAL MATCH (source)-[abstractDependency:DEPENDS_ON]->(abstractType:TypeAlias|Interface)<-[:EXPORTS]-(target)
WITH source
,target
,moduleDependency
,elementTypeCount
,elementTypeCardinality
,elementTypeExamples
,count(DISTINCT abstractType.globalFqn) AS abstractTypeCount
,sum(abstractDependency.cardinality) AS abstractTypeCardinality
,collect(DISTINCT abstractType.globalFqn)[0..4] AS abstractTypeExamples
// Set additional fine grained relationship properties (weights) to distinguish low and high coupling elements.
// The "cardinality" property is similar to "weight" property for Java dependencies and comes from the jQAssistant Typescript Plugin.
// - "abstractTypeCardinality" is the sum of all TypeAlias and Interface cardinality properties (if available)
// and corresponds to the "weightInterfaces" relationship property for Java.
// - "declarationCardinality" is the sum of all cardinality properties (including available Interface and TypeAlias)
// and is the same as the already existing "cardinality" of the moduleDependency. Thats why its left out.
// - "lowCouplingElement25PercentWeight" subtracts 75% of the weights for abstract types like Interfaces and Type aliases
// to compensate for their low coupling influence. Not included "high coupling" elements like Functions and Classes
// remain in the weight as they were. The same applies for "lowCouplingElement10PercentWeight" but with in a stronger manner.
SET moduleDependency.abstractTypeCount = abstractTypeCount
,moduleDependency.abstractTypeCardinality = abstractTypeCardinality
,moduleDependency.lowCouplingElement25PercentWeight =
toInteger(elementTypeCardinality - round(abstractTypeCardinality * 0.75))
,moduleDependency.lowCouplingElement10PercentWeight =
toInteger(elementTypeCardinality - round(abstractTypeCardinality * 0.90))
RETURN source.globalFqn AS sourceName
,target.globalFqn AS targetName
,abstractTypeCount
,elementTypeCount
,moduleDependency.cardinality AS externalModuleCardinality
,abstractTypeCardinality
,elementTypeCardinality
,moduleDependency.lowCouplingElement25PercentWeight
,moduleDependency.lowCouplingElement10PercentWeight
,abstractTypeExamples
,elementTypeExamples
ORDER BY sourceName ASC
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// Explore Typescript elements with same globalFqn

MATCH (ts1:TS)
WHERE ts1.globalFqn CONTAINS '"'
WHERE ts1.globalFqn IS NOT NULL
MATCH (ts2:TS)
WHERE ts2.globalFqn CONTAINS '"'
AND (ts2.globalFqn = ts1.globalFqn
OR toLower(ts2.globalFqn) = toLower(ts1.globalFqn))
WHERE ts2.globalFqn IS NOT NULL
AND ts2.globalFqn = ts1.globalFqn
AND ts1 <> ts2
RETURN labels(ts1), labels(ts2), count(*)
,collect(ts1.globalFqn)[0..4] AS examples1
,collect(ts2.globalFqn)[0..4] AS examples2
LIMIT 30
18 changes: 18 additions & 0 deletions cypher/Node_Embeddings/Node_Embeddings_0a_Query_Calculated.cypher
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Query already calculated and written node embeddings on nodes with label in parameter $dependencies_projection_node including a communityId and centrality. Variables: dependencies_projection_node, dependencies_projection_write_property

MATCH (codeUnit)
WHERE $dependencies_projection_node IN LABELS(codeUnit)
AND codeUnit[$dependencies_projection_write_property] IS NOT NULL
// AND codeUnit.notExistingToForceRecalculation IS NOT NULL // uncomment this line to force recalculation
OPTIONAL MATCH (artifact:Java:Artifact)-[:CONTAINS]->(codeUnit)
WITH *, replace(last(split(artifact.fileName, '/')), '.jar', '') AS artifactName
OPTIONAL MATCH (projectRoot:Directory)<-[:HAS_ROOT]-(proj:TS:Project)-[:CONTAINS]->(codeUnit)
WITH *, last(split(projectRoot.absoluteFileName, '/')) AS projectName
RETURN DISTINCT
coalesce(codeUnit.fqn, codeUnit.globalFqn, codeUnit.fileName, codeUnit.signature, codeUnit.name) AS codeUnitName
,coalesce(codeUnit.name, replace(last(split(codeUnit.fileName, '/')), '.jar', '')) AS shortCodeUnitName
,coalesce(artifactName, projectName) AS projectName
,coalesce(codeUnit.communityLeidenId, 0) AS communityId
,coalesce(codeUnit.centralityPageRank, 0.01) AS centrality
,codeUnit[$dependencies_projection_write_property] AS embedding
ORDER BY communityId
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
CALL gds.fastRP.stream.estimate(
$dependencies_projection + '-cleaned', {
embeddingDimension: toInteger($dependencies_projection_embedding_dimension)
,randomSeed: 30
,relationshipWeightProperty: $dependencies_projection_weight_property
}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
CALL gds.fastRP.stats(
$dependencies_projection + '-cleaned', {
embeddingDimension: toInteger($dependencies_projection_embedding_dimension)
,randomSeed: 30
,relationshipWeightProperty: $dependencies_projection_weight_property
}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
CALL gds.fastRP.mutate(
$dependencies_projection + '-cleaned', {
embeddingDimension: toInteger($dependencies_projection_embedding_dimension)
,randomSeed: 30
,relationshipWeightProperty: $dependencies_projection_weight_property
,mutateProperty: $dependencies_projection_write_property
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,21 @@
CALL gds.fastRP.stream(
$dependencies_projection + '-cleaned', {
embeddingDimension: toInteger($dependencies_projection_embedding_dimension)
,randomSeed: 30
,relationshipWeightProperty: $dependencies_projection_weight_property
}
)
YIELD nodeId, embedding
WITH gds.util.asNode(nodeId) AS codeUnit
,embedding
OPTIONAL MATCH (artifact:Artifact)-[:CONTAINS]->(codeUnit)
RETURN DISTINCT coalesce(codeUnit.fqn, codeUnit.fileName, codeUnit.signature, codeUnit.name) AS codeUnitName
,coalesce(codeUnit.communityLeidenId, 0) AS communityId
,coalesce(codeUnit.centralityPageRank, 0.01) AS centrality
,replace(last(split(artifact.fileName, '/')), '.jar', '') AS artifactName
,embedding
OPTIONAL MATCH (artifact:Java:Artifact)-[:CONTAINS]->(codeUnit)
WITH *, replace(last(split(artifact.fileName, '/')), '.jar', '') AS artifactName
OPTIONAL MATCH (projectRoot:Directory)<-[:HAS_ROOT]-(proj:TS:Project)-[:CONTAINS]->(codeUnit)
WITH *, last(split(projectRoot.absoluteFileName, '/')) AS projectName
RETURN DISTINCT
coalesce(codeUnit.fqn, codeUnit.globalFqn, codeUnit.fileName, codeUnit.signature, codeUnit.name) AS codeUnitName
,coalesce(codeUnit.name, replace(last(split(codeUnit.fileName, '/')), '.jar', '')) AS shortCodeUnitName
,coalesce(artifactName, projectName) AS projectName
,coalesce(codeUnit.communityLeidenId, 0) AS communityId
,coalesce(codeUnit.centralityPageRank, 0.01) AS centrality
,embedding
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
CALL gds.fastRP.write(
$dependencies_projection + '-cleaned', {
embeddingDimension: toInteger($dependencies_projection_embedding_dimension)
,randomSeed: 30
,relationshipWeightProperty: $dependencies_projection_weight_property
,writeProperty: $dependencies_projection_write_property
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ CALL gds.beta.hashgnn.stream.estimate(
,iterations: 3
,generateFeatures: {
dimension: toInteger($dependencies_projection_embedding_dimension) * 4
,densityLevel: 1
,densityLevel: 3
}
,outputDimension: toInteger($dependencies_projection_embedding_dimension)
,neighborInfluence: 0.9
,randomSeed: 30
}
)
YIELD requiredMemory, nodeCount, relationshipCount, bytesMin, bytesMax, heapPercentageMin, heapPercentageMax, treeView
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ CALL gds.beta.hashgnn.mutate(
,iterations: 3
,generateFeatures: {
dimension: toInteger($dependencies_projection_embedding_dimension) * 4
,densityLevel: 1
,densityLevel: 3
}
,outputDimension: toInteger($dependencies_projection_embedding_dimension)
,neighborInfluence: 0.9
,randomSeed: 30
,mutateProperty: $dependencies_projection_write_property
}
)
Expand Down
15 changes: 11 additions & 4 deletions cypher/Node_Embeddings/Node_Embeddings_2d_Hash_GNN_Stream.cypher
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,24 @@ CALL gds.beta.hashgnn.stream(
,iterations: 3
,generateFeatures: {
dimension: toInteger($dependencies_projection_embedding_dimension) * 4
,densityLevel: 1
,densityLevel: 3
}
,outputDimension: toInteger($dependencies_projection_embedding_dimension)
,neighborInfluence: 0.9
,randomSeed: 30
}
)
YIELD nodeId, embedding
WITH gds.util.asNode(nodeId) AS codeUnit
,embedding
OPTIONAL MATCH (artifact:Artifact)-[:CONTAINS]->(codeUnit)
RETURN DISTINCT coalesce(codeUnit.fqn, codeUnit.fileName, codeUnit.signature, codeUnit.name) AS codeUnitName
OPTIONAL MATCH (artifact:Java:Artifact)-[:CONTAINS]->(codeUnit)
WITH *, replace(last(split(artifact.fileName, '/')), '.jar', '') AS artifactName
OPTIONAL MATCH (projectRoot:Directory)<-[:HAS_ROOT]-(proj:TS:Project)-[:CONTAINS]->(codeUnit)
WITH *, last(split(projectRoot.absoluteFileName, '/')) AS projectName
RETURN DISTINCT
coalesce(codeUnit.fqn, codeUnit.globalFqn, codeUnit.fileName, codeUnit.signature, codeUnit.name) AS codeUnitName
,coalesce(codeUnit.name, replace(last(split(codeUnit.fileName, '/')), '.jar', '')) AS shortCodeUnitName
,coalesce(artifactName, projectName) AS projectName
,coalesce(codeUnit.communityLeidenId, 0) AS communityId
,coalesce(codeUnit.centralityPageRank, 0.01) AS centrality
,replace(last(split(artifact.fileName, '/')), '.jar', '') AS artifactName
,embedding
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ CALL gds.node2vec.write.estimate(
$dependencies_projection + '-cleaned', {
,embeddingDimension: toInteger($dependencies_projection_embedding_dimension)
,iterations: 3
,randomSeed: 30
,relationshipWeightProperty: $dependencies_projection_weight_property
,writeProperty: $dependencies_projection_write_property
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ CALL gds.node2vec.mutate(
$dependencies_projection + '-cleaned', {
,embeddingDimension: toInteger($dependencies_projection_embedding_dimension)
,iterations: 3
,randomSeed: 30
,relationshipWeightProperty: $dependencies_projection_weight_property
,mutateProperty: $dependencies_projection_write_property
}
Expand Down
12 changes: 9 additions & 3 deletions cypher/Node_Embeddings/Node_Embeddings_3d_Node2Vec_Stream.cypher
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,21 @@ CALL gds.node2vec.stream(
$dependencies_projection + '-cleaned', {
,embeddingDimension: toInteger($dependencies_projection_embedding_dimension)
,iterations: 3
,randomSeed: 30
,relationshipWeightProperty: $dependencies_projection_weight_property
}
)
YIELD nodeId, embedding
WITH gds.util.asNode(nodeId) AS codeUnit
,embedding
OPTIONAL MATCH (artifact:Artifact)-[:CONTAINS]->(codeUnit)
RETURN DISTINCT coalesce(codeUnit.fqn, codeUnit.fileName, codeUnit.signature, codeUnit.name) AS codeUnitName
OPTIONAL MATCH (artifact:Java:Artifact)-[:CONTAINS]->(codeUnit)
WITH *, replace(last(split(artifact.fileName, '/')), '.jar', '') AS artifactName
OPTIONAL MATCH (projectRoot:Directory)<-[:HAS_ROOT]-(proj:TS:Project)-[:CONTAINS]->(codeUnit)
WITH *, last(split(projectRoot.absoluteFileName, '/')) AS projectName
RETURN DISTINCT
coalesce(codeUnit.fqn, codeUnit.globalFqn, codeUnit.fileName, codeUnit.signature, codeUnit.name) AS codeUnitName
,coalesce(codeUnit.name, replace(last(split(codeUnit.fileName, '/')), '.jar', '')) AS shortCodeUnitName
,coalesce(artifactName, projectName) AS projectName
,coalesce(codeUnit.communityLeidenId, 0) AS communityId
,coalesce(codeUnit.centralityPageRank, 0.01) AS centrality
,replace(last(split(artifact.fileName, '/')), '.jar', '') AS artifactName
,embedding
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ CALL gds.node2vec.write(
$dependencies_projection + '-cleaned', {
,embeddingDimension: toInteger($dependencies_projection_embedding_dimension)
,iterations: 3
,randomSeed: 30
,relationshipWeightProperty: $dependencies_projection_weight_property
,writeProperty: $dependencies_projection_write_property
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// Adds a relation "RESOLVES_TO" from a Typescript element to an external declaration if their global fully qualified names match.
// Inspired by https://github.com/jQAssistant/jqa-java-plugin/blob/f092122b62bb13d597840b64b73b2010bd074d1f/src/main/resources/META-INF/jqassistant-rules/java-classpath.xml#L5
// Related to https://github.com/jqassistant-plugin/jqassistant-typescript-plugin/issues/35

MATCH (element:TS&!ExternalDeclaration)
WHERE element.globalFqn IS NOT NULL
MATCH (external:TS&ExternalDeclaration)
WHERE element.globalFqn IS NOT NULL
AND (element.globalFqn = external.globalFqn
OR toLower(element.globalFqn) = toLower(external.globalFqn))
AND element <> external
AND element.globalFqn = external.globalFqn
AND element <> external
CALL { WITH element, external
MERGE (external)-[:RESOLVES_TO]->(element)
} IN TRANSACTIONS
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// Adds a relation "RESOLVES_TO" from an external module to a module if their global fully qualified names match.
// Inspired by https://github.com/jQAssistant/jqa-java-plugin/blob/f092122b62bb13d597840b64b73b2010bd074d1f/src/main/resources/META-INF/jqassistant-rules/java-classpath.xml#L5
// Related to https://github.com/jqassistant-plugin/jqassistant-typescript-plugin/issues/35

MATCH (module:TS:Module)
WHERE module.globalFqn IS NOT NULL
MATCH (externalModule:TS:ExternalModule)
WHERE module.globalFqn IS NOT NULL
AND (toLower(module.globalFqn) = toLower(externalModule.globalFqn)
OR toLower(module.globalFqn) = split(toLower(externalModule.globalFqn), '/index.')[0]
OR toLower(externalModule.globalFqn) = split(toLower(module.globalFqn), '/index.')[0]
AND (module.globalFqn = externalModule.globalFqn
OR module.globalFqn = split(externalModule.globalFqn, '/index.')[0]
OR externalModule.globalFqn = split(module.globalFqn, '/index.')[0]
)
AND module <> externalModule
CALL { WITH module, externalModule
Expand Down
Loading