Skip to content

Commit d4472b0

Browse files
committed
Add fine grained DEPENDS_ON relationship weights for Typescript
1 parent ffdfded commit d4472b0

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// Add weight property for low coupling dependencies to Typescript module DEPENDS_ON relationships
2+
3+
MATCH (source:TS:Module)-[moduleDependency:DEPENDS_ON]->(target:ExternalModule)
4+
// Get the top level dependency between a Typescript module and the external modules it uses
5+
WITH source
6+
,target
7+
,moduleDependency
8+
,count(DISTINCT target) AS externalModuleCount
9+
,sum(moduleDependency.cardinality) AS externalModuleCardinalities
10+
OPTIONAL MATCH (source)-[rd:DEPENDS_ON]->(declaration:ExternalDeclaration)<-[:EXPORTS]-(target)
11+
// Get optional external (e.g. type) declarations that the external module (target) provides and the source module uses
12+
WITH source
13+
,target
14+
,moduleDependency
15+
,externalModuleCount
16+
,externalModuleCardinalities
17+
,count(DISTINCT declaration) AS declarationCount
18+
,sum(rd.cardinality) AS declarationCardinalities
19+
,collect(DISTINCT declaration.globalFqn)[0..4] AS declarationExamples
20+
OPTIONAL MATCH (source)-[:DECLARES]->(abstraction:TypeAlias|Interface)-[ra:DEPENDS_ON]->(target)
21+
// Get optional low coupling elements (TypeAlias, Interface) that the source module contains and defines (low level) that depend on the external module (target)
22+
WITH source
23+
,target
24+
,moduleDependency
25+
,externalModuleCount
26+
,externalModuleCardinalities
27+
,declarationCount
28+
,declarationCardinalities
29+
,declarationExamples
30+
,count(DISTINCT abstraction) AS abstractionCount
31+
,sum(ra.cardinality) AS abstractionCardinalities
32+
,collect(DISTINCT abstraction.globalFqn)[0..4] AS abstractionExamples
33+
OPTIONAL MATCH (source)-[:DECLARES]->(implementation:!TypeAlias&!Interface)-[ri:DEPENDS_ON]->(target)
34+
// Get optional higher coupling elements (Class, Function) that the source module contains and defines (low level) that depend on the external module (target)
35+
WITH source
36+
,target
37+
,moduleDependency
38+
,externalModuleCount
39+
,externalModuleCardinalities
40+
,declarationCount
41+
,declarationCardinalities
42+
,declarationExamples
43+
,abstractionCount
44+
,abstractionCardinalities
45+
,abstractionExamples
46+
,count(DISTINCT implementation) AS implementationCount
47+
,sum(ri.cardinality) AS implementationCardinalities
48+
,collect(DISTINCT implementation.globalFqn)[0..4] AS implementationExamples
49+
// Set additional fine grained relationship properties (weights) to distinguish low and high coupling elements.
50+
// The "cardinality" property is similar to "weight" property for Java dependencies and comes from the jQAssistant Typescript Plugin.
51+
// - "weightLowCouplingElements" is the sum of all TypeAlias, Interface and external declaration cardinalities
52+
// and corresponds to the "weightInterfaces" relationship property for Java.
53+
// - "weight25PercentLowCouplingElements" only takes 25% of the weight for elements that are considered as low coupling
54+
// like Type Declarations and Interfaces and adds the unchanged (100%) weight of "high coupling" elements like Functions and Classes.
55+
SET moduleDependency.weightDeclarations = declarationCardinalities
56+
,moduleDependency.weightAbstractions = abstractionCardinalities
57+
,moduleDependency.weightImplementations = implementationCardinalities
58+
,moduleDependency.weightLowCouplingElements = declarationCardinalities + abstractionCardinalities
59+
,moduleDependency.weight25PercentLowCouplingElements = toInteger(implementationCardinalities + round((declarationCardinalities + abstractionCardinalities) * 0.25))
60+
,moduleDependency.weight10PercentLowCouplingElements = toInteger(implementationCardinalities + round((declarationCardinalities + abstractionCardinalities) * 0.10))
61+
// Aggregate all gathered information for each (grouped by) source module
62+
WITH source
63+
,source.globalFqn AS sourceGlobalName
64+
,source.localFqn AS sourceLocalName
65+
,sum(externalModuleCount) AS externalModuleCount
66+
,sum(declarationCount) AS declarationCount
67+
,sum(abstractionCount) AS abstractionCount
68+
,sum(implementationCount) AS implementationCount
69+
,sum(externalModuleCardinalities) AS externalModuleCardinalities
70+
,sum(declarationCardinalities) AS declarationCardinalities
71+
,sum(abstractionCardinalities) AS abstractionCardinalities
72+
,sum(implementationCardinalities) AS implementationCardinalities
73+
,collect(DISTINCT target.globalFqn)[0..4] AS externalModuleExamples
74+
,apoc.coll.flatten(collect(declarationExamples))[0..4] AS declarationExamples
75+
,apoc.coll.flatten(collect(abstractionExamples))[0..4] AS abstractionExamples
76+
,apoc.coll.flatten(collect(implementationExamples))[0..4] AS implementationExamples
77+
SET source.outgoingDependencies = declarationCount + abstractionCount + implementationCount
78+
,source.outgoingDependenciesWeight = declarationCardinalities + abstractionCardinalities + implementationCardinalities
79+
,source.outgoingDependentImplementations = implementationCount
80+
,source.outgoingDependentLowCouplingElements = declarationCount + abstractionCount
81+
,source.outgoingDependentModules = externalModuleCount
82+
RETURN sourceGlobalName
83+
,sourceLocalName
84+
,externalModuleCount
85+
,declarationCount
86+
,abstractionCount
87+
,implementationCount
88+
,externalModuleCardinalities
89+
,declarationCardinalities
90+
,abstractionCardinalities
91+
,implementationCardinalities
92+
,externalModuleExamples
93+
,declarationExamples
94+
,abstractionExamples
95+
,implementationExamples
96+
ORDER BY sourceGlobalName ASC

0 commit comments

Comments
 (0)