-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pull Types For File #95
Comments
@imwalterbot thoughts on how to go about this? |
Queued for processing... |
Processing this now |
Based on the provided context, you can create a subclass of class TypeOnlyDependencyGraphParser extends DependencyGraphParser {
constructor(gitHubFileUrl: string) {
super(gitHubFileUrl);
}
public async build(): Promise<DepGraph<ts.SourceFile>> {
Log.info(
`Building type-only dependency graph for ${this.targetFile.url} excluding target`
);
const deps = await this.getDependencies(this.targetFile);
for (const dep of deps.deps) {
await this.processFileForTypes(dep);
}
return this.graph;
}
private async processFileForTypes(url: ParsedGitHubURL): Promise<void> {
Log.info(`Processing file for types ${url.url}`);
if (this.graph.hasNode(url.url)) {
Log.info(`Node exists ${url.url}`);
return;
}
const src = await this.getDependencies(url);
const typeOnlySourceFile = this.extractTypeDeclarations(src.sourceFile);
this.graph.addNode(url.url, typeOnlySourceFile);
for (const dep of src.deps) {
await this.processFileForTypes(dep);
Log.info(`Adding edge ${src.url.url} -> ${dep.url}`);
this.graph.addDependency(src.url.url, dep.url);
}
}
private extractTypeDeclarations(sourceFile: ts.SourceFile): ts.SourceFile {
// Pseudocode for extracting only type declarations from the source file
// 1. Iterate through the nodes of the source file
// 2. If the node is a type declaration, add it to a new source file
// 3. Return the new source file containing only type declarations
// Implement the actual logic for extracting type declarations here
}
} This subclass, |
Could we use the typescript compiler in extractTypeDeclarations ? |
Queued for processing... |
Processing this now |
Yes, you can use the TypeScript compiler in the private extractTypeDeclarations(sourceFile: ts.SourceFile): ts.SourceFile {
const typeDeclarations: ts.Node[] = [];
const visitNode = (node: ts.Node): void => {
if (ts.isTypeAliasDeclaration(node) || ts.isInterfaceDeclaration(node) || ts.isEnumDeclaration(node)) {
typeDeclarations.push(node);
} else {
ts.forEachChild(node, visitNode);
}
};
ts.forEachChild(sourceFile, visitNode);
// Create a new source file with only type declarations
const typeDeclarationSourceFile = ts.updateSourceFileNode(sourceFile, typeDeclarations);
return typeDeclarationSourceFile;
} In this example, we define a You can then use this |
What if we only waned the types that the |
Queued for processing... |
Processing this now |
If you want to modify the
Here's an example of how to modify the private async getDependencies(targetFile: ParsedGitHubURL): Promise<{
sourceFile: ts.SourceFile;
deps: ParsedGitHubURL[];
url: ParsedGitHubURL;
}> {
Log.info(`Getting dependencies for ${targetFile.url}`);
const fileContent = await utils.getFileFromUrl(targetFile.url);
const sourceFile = ts.createSourceFile(
fileContent.parsedUrl.filePath,
fileContent.body,
ts.ScriptTarget.ES2015,
true
);
const deps: ParsedGitHubURL[] = [];
const branch = this.branch;
sourceFile.forEachChild((node) => {
if (ts.isImportDeclaration(node)) {
const importPath = (node.moduleSpecifier as ts.StringLiteral).text;
if (!importPath.startsWith(".") && !importPath.startsWith("/")) {
Log.info(`Skipping import ${importPath}`);
return;
}
// Check if the import declaration imports a type
const importClause = node.importClause;
if (importClause && importClause.namedBindings) {
const namedBindings = importClause.namedBindings;
if (ts.isNamedImports(namedBindings)) {
for (const element of namedBindings.elements) {
if (element.name && ts.isIdentifier(element.name)) {
// If the imported element has a type keyword, add it to deps
if (element.typeKeyword) {
const imported = calculateAbsolutePath(
targetFile.filePath,
importPath + ".ts"
);
Log.info(`Adding import ${imported}`);
deps.push(branch.urlForPath(imported));
}
}
}
}
}
}
});
return {
sourceFile,
deps,
url: targetFile,
};
} This modification will ensure that the |
Ok summarize what we are looking to do. |
Queued for processing... |
Processing this now |
Based on the provided Here's a summary of the steps:
Here's an example of the class TypeDependencyGraphParser extends DependencyGraphParser {
constructor(gitHubFileUrl: string) {
super(gitHubFileUrl);
}
public async build(): Promise<DepGraph<ts.SourceFile>> {
Log.info(
`Building type dependency graph for ${this.targetFile.url} excluding target`
);
const deps = await this.getDependencies(this.targetFile);
for (const dep of deps.deps) {
await this.processFileForTypes(dep);
}
return this.graph;
}
private async processFileForTypes(url: ParsedGitHubURL): Promise<void> {
Log.info(`Processing file for types ${url.url}`);
if (this.graph.hasNode(url.url)) {
Log.info(`Node exists ${url.url}`);
return;
}
const src = await this.getDependencies(url);
this.graph.addNode(url.url, src.sourceFile);
for (const dep of src.deps) {
await this.processFileForTypes(dep);
Log.info(`Adding edge ${src.url.url} -> ${dep.url}`);
this.graph.addDependency(src.url.url, dep.url);
}
}
// Modify the getDependencies function to only include type dependencies
private async getDependencies(targetFile: ParsedGitHubURL): Promise<{
sourceFile: ts.SourceFile;
deps: ParsedGitHubURL[];
url: ParsedGitHubURL;
}> {
// (Include the modified getDependencies function from the previous answer here)
}
} This subclass, |
Seems like you can use the existing getDependencies right? |
Queued for processing... |
Processing this now |
Yes, you're right. You can use the existing Here's an example of the class TypeDependencyGraphParser extends DependencyGraphParser {
constructor(gitHubFileUrl: string) {
super(gitHubFileUrl);
}
public async build(): Promise<DepGraph<ts.SourceFile>> {
Log.info(
`Building type dependency graph for ${this.targetFile.url} excluding target`
);
const deps = await this.getDependencies(this.targetFile);
for (const dep of deps.deps) {
await this.processFileForTypes(dep);
}
return this.graph;
}
private async processFileForTypes(url: ParsedGitHubURL): Promise<void> {
Log.info(`Processing file for types ${url.url}`);
if (this.graph.hasNode(url.url)) {
Log.info(`Node exists ${url.url}`);
return;
}
const src = await this.getDependencies(url);
const typeOnlySourceFile = this.extractTypeDeclarations(src.sourceFile);
this.graph.addNode(url.url, typeOnlySourceFile);
for (const dep of src.deps) {
await this.processFileForTypes(dep);
Log.info(`Adding edge ${src.url.url} -> ${dep.url}`);
this.graph.addDependency(src.url.url, dep.url);
}
}
private extractTypeDeclarations(sourceFile: ts.SourceFile): ts.SourceFile {
// (Include the extractTypeDeclarations function from the previous answer here)
}
} This subclass, |
Queued for processing... |
Processing this now |
Will extractTypeDeclarations also include function declarations? I'm trying to build a type hint system and it would be good to have those as well. |
Queued for processing... |
Processing this now |
To include function declarations in the private extractTypeDeclarations(sourceFile: ts.SourceFile): ts.SourceFile {
const typeDeclarations: ts.Node[] = [];
const visitNode = (node: ts.Node): void => {
if (
ts.isTypeAliasDeclaration(node) ||
ts.isInterfaceDeclaration(node) ||
ts.isEnumDeclaration(node) ||
ts.isFunctionDeclaration(node)
) {
typeDeclarations.push(node);
} else {
ts.forEachChild(node, visitNode);
}
};
ts.forEachChild(sourceFile, visitNode);
// Create a new source file with only type declarations and function declarations
const typeDeclarationSourceFile = ts.updateSourceFileNode(sourceFile, typeDeclarations);
return typeDeclarationSourceFile;
} In this updated version, we've added |
@imwalterbot given the above how would we output the only the definitions (not the full function) in the toString method on the class? |
Queued for processing... |
Processing this now |
To output only the definitions (and not the full function) in the Here's an example of a custom printing function called private printTypeAndFunctionSignatures(sourceFile: ts.SourceFile): string {
const printer = ts.createPrinter();
let signatures: string[] = [];
const visitNode = (node: ts.Node): void => {
if (
ts.isTypeAliasDeclaration(node) ||
ts.isInterfaceDeclaration(node) ||
ts.isEnumDeclaration(node) ||
ts.isFunctionDeclaration(node)
) {
signatures.push(printer.printNode(ts.EmitHint.Unspecified, node, sourceFile));
} else {
ts.forEachChild(node, visitNode);
}
};
ts.forEachChild(sourceFile, visitNode);
return signatures.join("\n");
} Now, modify the public toStrings(): string[] {
const order = this.graph.overallOrder();
let out: string[] = [];
for (const node of order) {
const data = this.graph.getNodeData(node);
out.push(`// SOURCE_FILE: ${node}`);
out.push(this.printTypeAndFunctionSignatures(data));
out.push(`// END: ${node}`);
}
return out;
} With these changes, the |
We need to create a subclass of
DependencyGraphParser
herehttps://github.com/octaviuslabs/walter/blob/main/src/dependency-graph-parser.ts#L49 where the
build
function pulls in the types (not the full code blocks) for the target file.The text was updated successfully, but these errors were encountered: