Skip to content
Open
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
8 changes: 4 additions & 4 deletions src/analyze_functions/process_functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,15 +251,15 @@ function processVariables(m: ContainerTypes, fmxScope: Famix.ScriptEntity | Fami
// Check each VariableDeclaration for object literal methods
v.getDeclarations().forEach(varDecl => {
const varName = varDecl.getName();
console.log(`Checking variable: ${varName} at pos=${varDecl.getStart()}`);
// console.log(`Checking variable: ${varName} at pos=${varDecl.getStart()}`);
const initializer = varDecl.getInitializer();
if (initializer && Node.isObjectLiteralExpression(initializer)) {
initializer.getProperties().forEach(prop => {
if (Node.isPropertyAssignment(prop)) {
const nested = prop.getInitializer();
if (nested && Node.isObjectLiteralExpression(nested)) {
nested.getDescendantsOfKind(SyntaxKind.MethodDeclaration).forEach(method => {
console.log(`Found object literal method: ${method.getName()} at pos=${method.getStart()}`);
// console.log(`Found object literal method: ${method.getName()} at pos=${method.getStart()}`);
entityDictionary.createOrGetFamixMethod(method, currentCC);
});
}
Expand Down Expand Up @@ -590,15 +590,15 @@ function convertParameterToPropertyRepresentation(param: ParameterDeclaration) {
const paramType = param.getType().getText(param);

// Determine visibility
let scope: Scope;
let scope: Scope = Scope.Public;
if (param.hasModifier(SyntaxKind.PrivateKeyword)) {
scope = Scope.Private;
} else if (param.hasModifier(SyntaxKind.ProtectedKeyword)) {
scope = Scope.Protected;
} else if (param.hasModifier(SyntaxKind.PublicKeyword)) {
scope = Scope.Public;
} else {
throw new Error(`Parameter property ${paramName} in constructor does not have a visibility modifier.`);
console.log(`[convertParameterToPropertyRepresentation] Parameter ${paramName} has no visibility modifier, defaulting to public.`);
}

// Determine if readonly
Expand Down
103 changes: 56 additions & 47 deletions src/famix_functions/EntityDictionary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1031,10 +1031,10 @@ export class EntityDictionary {
ancestor = this.createOrGetFamixType(typeAncestor.getText(), typeAncestor.getType(), typeAncestor as TSMorphTypeDeclaration);
// console.log('Ancestor not found in repo, creating it');
} else {
console.log(`Found ancestor in famixRep: ${ancestor.fullyQualifiedName}`);
// console.log(`Found ancestor in famixRep: ${ancestor.fullyQualifiedName}`);
}
} else {
console.log(`No type ancestor found for ${typeName} - proceeding without container`);
// console.log(`No type ancestor found for ${typeName} - proceeding without container`);
}
}

Expand Down Expand Up @@ -1180,55 +1180,64 @@ export class EntityDictionary {
return fmxType;
}

/**
* Creates a Famix access
* @param node A node
* @param id An id of a parameter, a variable, a property or an enum member
*/
public createFamixAccess(node: Identifier, id: number): void {
const fmxVar = this.famixRep.getFamixEntityById(id) as Famix.StructuralEntity;
if (!fmxVar) {
throw new Error(`Famix entity with id ${id} not found, for node ${node.getText()} in ${node.getSourceFile().getBaseName()} at line ${node.getStartLineNumber()}.`);
}

logger.debug(`Creating FamixAccess. Node: [${node.getKindName()}] '${node.getText()}' at line ${node.getStartLineNumber()} in ${node.getSourceFile().getBaseName()}, id: ${id} refers to fmxVar '${fmxVar.fullyQualifiedName}'.`);

const nodeReferenceAncestor = Helpers.findAncestor(node);
if (!nodeReferenceAncestor) {
logger.error(`No ancestor found for node '${node.getText()}'`);
return;
}

const ancestorFullyQualifiedName = FQNFunctions.getFQN(nodeReferenceAncestor);
const accessor = this.famixRep.getFamixEntityByFullyQualifiedName(ancestorFullyQualifiedName) as Famix.ContainerEntity;
if (!accessor) {
logger.error(`Ancestor ${ancestorFullyQualifiedName} of kind ${nodeReferenceAncestor.getKindName()} not found.`);
return; // Bail out for now
} else {
logger.debug(`Found accessor to be ${accessor.fullyQualifiedName}.`);
}

// Ensure accessor is a method, function, script, or module
if (!(accessor instanceof Famix.Method) && !(accessor instanceof Famix.ArrowFunction) && !(accessor instanceof Famix.Function) && !(accessor instanceof Famix.ScriptEntity) && !(accessor instanceof Famix.Module)) {
logger.error(`Accessor ${accessor.fullyQualifiedName} is not a method, function, etc.`);
return;
}

// Avoid duplicates
const foundAccess = this.famixRep.getFamixAccessByAccessorAndVariable(accessor, fmxVar);
if (foundAccess) {
logger.debug(`FamixAccess already exists for accessor ${accessor.fullyQualifiedName} and variable ${fmxVar.fullyQualifiedName}.`);
/**
* Creates a Famix access
* @param node A node
* @param id An id of a parameter, a variable, a property or an enum member
*/
public createFamixAccess(node: Identifier, id: number): void {
const fmxVar = this.famixRep.getFamixEntityById(id) as Famix.StructuralEntity;
if (!fmxVar) {
throw new Error(`Famix entity with id ${id} not found, for node ${node.getText()} in ${node.getSourceFile().getBaseName()} at line ${node.getStartLineNumber()}.`);
}

logger.debug(`Creating FamixAccess. Node: [${node.getKindName()}] '${node.getText()}' at line ${node.getStartLineNumber()} in ${node.getSourceFile().getBaseName()}, id: ${id} refers to fmxVar '${fmxVar.fullyQualifiedName}'.`);

const nodeReferenceAncestor = Helpers.findAncestor(node);
if (!nodeReferenceAncestor) {
logger.error(`No ancestor found for node '${node.getText()}'`);
return;
}

const ancestorFullyQualifiedName = FQNFunctions.getFQN(nodeReferenceAncestor);
const accessor = this.famixRep.getFamixEntityByFullyQualifiedName(ancestorFullyQualifiedName) as Famix.ContainerEntity;
if (!accessor) {
logger.error(`Ancestor ${ancestorFullyQualifiedName} of kind ${nodeReferenceAncestor.getKindName()} not found.`);
return;
} else {
logger.debug(`Found accessor to be ${accessor.fullyQualifiedName}.`);
}

// Check if the accessor is a valid type (method, function, script, module, or class for specific cases)
if (!(accessor instanceof Famix.Method) &&
!(accessor instanceof Famix.ArrowFunction) &&
!(accessor instanceof Famix.Function) &&
!(accessor instanceof Famix.ScriptEntity) &&
!(accessor instanceof Famix.Module)) {
// Handle class-level accesses (e.g., decorators, DI)
if (accessor instanceof Famix.Class) {
logger.debug(`Skipping FamixAccess for class accessor ${accessor.fullyQualifiedName} (node: '${node.getText()}', parent: ${node.getParent()?.getKindName() || 'unknown'}). Likely decorator or DI reference.`);
return;
}

const fmxAccess = new Famix.Access();
fmxAccess.accessor = accessor;
fmxAccess.variable = fmxVar;
this.famixRep.addElement(fmxAccess);
this.fmxElementObjectMap.set(fmxAccess, node);
logger.debug(`Created access: ${accessor.fullyQualifiedName} -> ${fmxVar.fullyQualifiedName}`);
logger.error(`Accessor ${accessor.fullyQualifiedName} is not a method, function, etc.`);
return;
}

// Avoid duplicates
const foundAccess = this.famixRep.getFamixAccessByAccessorAndVariable(accessor, fmxVar);
if (foundAccess) {
logger.debug(`FamixAccess already exists for accessor ${accessor.fullyQualifiedName} and variable ${fmxVar.fullyQualifiedName}.`);
return;
}

const fmxAccess = new Famix.Access();
fmxAccess.accessor = accessor;
fmxAccess.variable = fmxVar;
this.famixRep.addElement(fmxAccess);
this.fmxElementObjectMap.set(fmxAccess, node);
logger.debug(`Created access: ${accessor.fullyQualifiedName} -> ${fmxVar.fullyQualifiedName}`);
}

/**
* Creates a Famix invocation
* @param nodeReferringToInvocable A node
Expand Down
2 changes: 1 addition & 1 deletion src/famix_functions/helpers_creation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export function findAncestor(node: Identifier): Node {
export function findTypeAncestor(element: Node): Node | undefined {
let ancestor: Node | undefined;
const ancestors = element.getAncestors();
console.log(`Ancestors count: ${ancestors.length}`);
// console.log(`Ancestors count: ${ancestors.length}`);

ancestor = ancestors.find(a => {
const kind = a.getKind();
Expand Down
Loading