Skip to content

Commit

Permalink
fix: fix types-query-strategy for multiple namespaces for php #366
Browse files Browse the repository at this point in the history
  • Loading branch information
benedikt-mehl-mw authored and mylinhdao committed Jun 3, 2024
1 parent d4cadf2 commit f5a37ab
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 44 deletions.
28 changes: 19 additions & 9 deletions src/parser/metrics/coupling/coupling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,28 +191,35 @@ export class Coupling implements CouplingMetric {
this.addFilePathIfNotExists(couplingValues, fromFile);
this.addFilePathIfNotExists(couplingValues, toFile);

//add only +1 outgoing dependency per "toClassName" for every file
// Add only +1 outgoing dependency per "toClassName" for every file
this.updateOutgoingDependency(fromFile, couplingValues, couplingItem);
this.updateMetricsForFile(couplingItem.toSource, "incoming", couplingValues);
}

for (const [file, outgoingDependencies] of this.outgoingDependencyByFile) {
couplingValues.get(file)!.outgoing_dependencies = outgoingDependencies.size;
}
for(let file of couplingValues.keys()){

for (const file of couplingValues.keys()) {
const couplingValue = couplingValues.get(file)!;
couplingValue.coupling_between_objects = couplingValue.incoming_dependencies + couplingValue.outgoing_dependencies;
couplingValue.coupling_between_objects =
couplingValue.incoming_dependencies + couplingValue.outgoing_dependencies;
this.calculateInstability(couplingValue);
}

dlog("\n\n", couplingValues);
return couplingValues;
}

private addFilePathIfNotExists(couplingValues: Map<string, CouplingMetrics>, filePath: FilePath) {
private addFilePathIfNotExists(
couplingValues: Map<string, CouplingMetrics>,
filePath: FilePath,
): void {
if (!couplingValues.has(filePath)) {
couplingValues.set(filePath, this.getNewCouplingMetrics());
}
if(!this.outgoingDependencyByFile.has(filePath)){

if (!this.outgoingDependencyByFile.has(filePath)) {
this.outgoingDependencyByFile.set(filePath, new Set());
}
}
Expand All @@ -221,10 +228,11 @@ export class Coupling implements CouplingMetric {
fromFile: string,
couplingValues: Map<string, CouplingMetrics>,
couplingItem: Relationship,
) {
): void {
if (!this.outgoingDependencyByFile.has(fromFile)) {
this.outgoingDependencyByFile.set(fromFile, new Set());
}

this.outgoingDependencyByFile.get(fromFile)!.add(couplingItem.toNamespace);
}

Expand All @@ -236,7 +244,8 @@ export class Coupling implements CouplingMetric {
if (!this.outgoingDependencyByFile.has(filePath)) {
this.outgoingDependencyByFile.set(filePath, new Set());
}
let couplingMetrics = this.getCouplingMetricForFile(filePath, couplingValues);

const couplingMetrics = this.getCouplingMetricForFile(filePath, couplingValues);

const parsedFile = parseSync(filePath, this.config);
if (!(parsedFile instanceof ParsedFile)) {
Expand All @@ -253,7 +262,7 @@ export class Coupling implements CouplingMetric {
] += 1;
}

private calculateInstability(couplingMetrics: CouplingMetrics) {
private calculateInstability(couplingMetrics: CouplingMetrics): void {
if (
couplingMetrics.outgoing_dependencies === 0 &&
couplingMetrics.incoming_dependencies === 0
Expand All @@ -269,12 +278,13 @@ export class Coupling implements CouplingMetric {
private getCouplingMetricForFile(
filePath: string,
couplingValues: Map<FilePath, CouplingMetrics>,
) {
): CouplingMetrics {
let couplingMetrics = couplingValues.get(filePath);
if (couplingMetrics === undefined) {
couplingMetrics = this.getNewCouplingMetrics();
couplingValues.set(filePath, couplingMetrics);
}

return couplingMetrics;
}

Expand Down
45 changes: 21 additions & 24 deletions src/parser/resolver/types/php-collector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,27 @@ import { AbstractCollector, type TypesResolvingStrategy } from "./abstract-colle
export class PHPCollector extends AbstractCollector {
public getTypesQuery(): Query {
const queryString = `
((namespace_definition
name: (namespace_name) @namespace_definition_name
)
(class_declaration
(name) @class_name
(base_clause (name) @extended_class)?
(class_interface_clause
(name)+ @implemented_class ("," (name) @implemented_class)*
)?
) @type_node
)
(
(namespace_definition
name: (namespace_name) @namespace_definition_name
)
(interface_declaration
"interface" @class_type
(name) @class_name
(base_clause
(name)+ @implemented_class ("," (name) @implemented_class)*
)?
) @type_node
)
(
(namespace_definition
name: (namespace_name) @namespace_definition_name
)
[
(class_declaration
(name) @class_name
(base_clause (name) @extended_class)?
(class_interface_clause
(name)+ @implemented_class ("," (name) @implemented_class)*
)?
) @type_node
(interface_declaration
"interface" @class_type
(name) @class_name
(base_clause
(name)+ @implemented_class ("," (name) @implemented_class)*
)?
) @type_node
]+
)
`;

const queryStatement = new SimpleLanguageSpecificQueryStatement(
Expand Down
45 changes: 34 additions & 11 deletions src/parser/resolver/types/resolver-strategy/types-query-strategy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type Query, type QueryMatch, SyntaxNode } from "tree-sitter";
import { type Query, type QueryMatch } from "tree-sitter";
import { type ClassType, type TypeInfo } from "../abstract-collector.js";
import { type ParsedFile } from "../../../metrics/metric.js";

Expand All @@ -24,26 +24,25 @@ export class TypesQueryStrategy {
matches = typesQuery.matches(tree.rootNode);
}

matches.map((match) => {
const typeInfo = this.buildTypeInfo(match, filePath, namespaceDelimiter);
typesMap!.set(typeInfo.namespace + namespaceDelimiter + typeInfo.typeName, typeInfo);
return typeInfo;
});
for (const match of matches) {
this.buildTypeInfos(match, filePath, namespaceDelimiter, typesMap);
}

this.fileToTypesMapCache.set(filePath, typesMap);

return typesMap;
}

private buildTypeInfo(
private buildTypeInfos(
match: QueryMatch,
filePath: string,
namespaceDelimiter: string,
): TypeInfo {
typesMap: Map<FQTN, TypeInfo>,
): void {
let namespace = "";
let classType: ClassType = "class";
let extendedFrom: string | undefined;
const implementedFrom: string[] = [];
let implementedFrom: string[] = [];
let typeName = "";
let node;

Expand All @@ -55,6 +54,7 @@ export class TypesQueryStrategy {
namespace = capture.node.text;
namespaceNotFoundYet = false;
}

break;
}

Expand All @@ -79,6 +79,28 @@ export class TypesQueryStrategy {
}

case "type_node": {
if (node !== undefined) {
const typeInfo: TypeInfo = {
node,
namespace,
typeName,
classType,
sourceFile: filePath,
namespaceDelimiter,
implementedFrom,
extendedFrom,
};
typesMap.set(
typeInfo.namespace + namespaceDelimiter + typeInfo.typeName,
typeInfo,
);

classType = "class";
extendedFrom = undefined;
implementedFrom = [];
typeName = "";
}

node = capture.node;
break;
}
Expand All @@ -89,8 +111,8 @@ export class TypesQueryStrategy {
}
}

return {
node: node!,
const typeInfo: TypeInfo = {
node,
namespace,
typeName,
classType,
Expand All @@ -99,5 +121,6 @@ export class TypesQueryStrategy {
implementedFrom,
extendedFrom,
};
typesMap.set(typeInfo.namespace + namespaceDelimiter + typeInfo.typeName, typeInfo);
}
}

0 comments on commit f5a37ab

Please sign in to comment.