Description (a bit outdated after the last commit)
This PR introduces the mechanism to identify classes extending or implementing the o1js SmartContract class in a given JavaScript file that are scanned using pattern ./build/**/*.js.
The core method findIfClassExtendsOrImplementsSmartContract(entryFilePath) performs this operation.
Below is a step-by-step breakdown of how this method works, with explanations of the intermediate methods it invokes, using an example:
./build/src/SomeZkApp.js
import { someOtherLib } from 'someOtherLib';
import { SmartContract } from 'o1js';
export class TestZkApp extends SmartContract {}
export class AnotherTestZkApp extends TestZkApp {}
export class SomethingElse extends Parent {}
This method identifies all classes in the provided file that extend or implement the SmartContract class (Note: the o1js belonging is yet to be fixed).
It is being invoked with the file path to process like this:
const result = findIfClassExtendsOrImplementsSmartContract('./build/src/SomeZkApp.js');
This data then used by zkapp-cli deploy method to proceed (if only 1 SC is available) or prompt user to select which SC to deploy.
Steps:
Build class hierarchy: Calls buildClassHierarchy(entryFilePath) to generate a map of class names to class information.
Resolve imports: Calls resolveImports(entryFilePath) to map local import names to their resolved file paths.
Check inheritance: Iterates over the classes found in the class hierarchy and checks if they extend or implement SmartContract by calling checkClassInheritance().
Intermediate methods involved
buildClassHierarchy(filePath):
Purpose: To parse the file and create a map of class declarations.
Reason: Essential for understanding the structure of classes within the file, including their inheritance and implemented interfaces.
This function parses the file to build a hierarchy of class declarations.
Purpose: To recursively check if a given class (or its ancestors) extends or implements the target class.
Reason: Ensures comprehensive detection of inheritance chains, even when they span multiple files.
This recursive function checks if a given class (or its ancestors) extends or implements the target class.
const result = checkClassInheritance(
"AnotherTestZkApp",
"SmartContract",
classesMap,
new Set(),
importMappings
);
Returns:
true
Steps
Avoid infinite loops: Checks if the class has already been visited to prevent infinite loops.
Extend class hierarchy: If the class is not found in the current hierarchy, it tries to extend the hierarchy using the resolved imports.
Direct check: Checks if the class directly extends or implements the SmartContract class.
Recursive check: Recursively checks the parent class and implemented interfaces.
Other code segments
if (!classesMap[className]) {
let resolvedPath = importMappings[className];
if (!resolvedPath) return false;
Object.assign(classesMap, buildClassHierarchy(resolvedPath));
}
Purpose:
This block handles cases where the class being checked (className) is not found in the current class hierarchy map (classesMap).
It attempts to resolve the file path of the class from the import mappings (importMappings) and then extends the class hierarchy by parsing the resolved file.
Reason:
This code ensures that even if the class hierarchy is split across multiple files, all relevant classes are considered.
It allows the method to dynamically build a comprehensive class hierarchy that includes classes defined across multiple files.
Closes #636
Includes dependencies and tests upgrade/update.
Description (a bit outdated after the last commit)
This PR introduces the mechanism to identify classes extending or implementing the o1js
SmartContract
class in a given JavaScript file that are scanned using pattern./build/**/*.js
. The core methodfindIfClassExtendsOrImplementsSmartContract(entryFilePath)
performs this operation. Below is astep-by-step
breakdown of how this method works, with explanations of the intermediate methods it invokes, using an example:./build/src/SomeZkApp.js
findIfClassExtendsOrImplementsSmartContract(entryFilePath)
This method identifies all classes in the provided file that extend or implement the
SmartContract
class (Note
: theo1js
belonging is yet to be fixed). It is being invoked with the file path to process like this:It returns:
This data then used by zkapp-cli
deploy
method to proceed (if only 1 SC is available) or prompt user to select which SC to deploy.Steps:
buildClassHierarchy(entryFilePath)
to generate a map of class names to class information.resolveImports(entryFilePath)
to map local import names to their resolved file paths.SmartContract
by callingcheckClassInheritance()
.Intermediate methods involved
buildClassHierarchy(filePath)
:This function parses the file to build a hierarchy of class declarations.
Returns:
resolveImports(filePath)
:SmartContract
indirectly through imports from other files.This function parses the file to resolve import statements to their respective file paths.
Returns:
resolveModulePath(moduleName, basePath)
:checkClassInheritance(className, targetClass, classesMap, visitedClasses, importMappings)
:This recursive function checks if a given class (or its ancestors) extends or implements the target class.
Returns:
Steps
Other code segments
className
) is not found in the current class hierarchy map (classesMap
).importMappings
) and then extends the class hierarchy by parsing the resolved file.