Skip to content

feat: improve type generation#1662

Merged
HerringtonDarkholme merged 4 commits intomainfrom
feat-improve-napi-type
Dec 14, 2024
Merged

feat: improve type generation#1662
HerringtonDarkholme merged 4 commits intomainfrom
feat-improve-napi-type

Conversation

@HerringtonDarkholme
Copy link
Copy Markdown
Member

@HerringtonDarkholme HerringtonDarkholme commented Dec 14, 2024

Summary by CodeRabbit

  • New Features

    • Introduced named exports for various programming language node types, enhancing clarity and structure.
  • Bug Fixes

    • Updated method signatures in the SgNode class for improved type definitions and functionality.
    • Added error handling in the main function for better reliability during execution.
    • Added a new test case to verify functionality of finding nodes by specified range in multiline strings.
  • Chores

    • Simplified the build:debug script in the package configuration for easier execution.
    • Modified the prepublishOnly script to streamline the build process.
    • Removed unused constants to simplify the structure of exported constants.
    • Ensured proper file termination by adding newline characters where necessary.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Dec 14, 2024

Walkthrough

This pull request focuses on restructuring type exports in the @ast-grep/napi package. The changes primarily involve modifying how node type maps for various programming languages are exported in TypeScript definition files. The modifications transition from default imports to named exports, improving type clarity and consistency across the package's type definitions. The changes span multiple files including index.d.ts, package.json, and generate-types.ts, with a consistent theme of refining type export mechanisms.

Changes

File Change Summary
crates/napi/index.d.ts Replaced default imports with named exports for multiple language node type maps (JavaScript, TypeScript, Python, Rust, etc.) and updated function signatures for parsing functions to use generalized return types.
crates/napi/package.json Minor script modifications, simplifying build:debug and updating prepublishOnly script to run yarn typegen.
crates/napi/scripts/generate-types.ts Updated type export mechanisms, changing from default to named exports and modifying type generation logic, including error handling in the main function.
crates/napi/__test__/index.spec.ts Added a new test case for finding nodes by range in a multiline string and ensured proper file termination with a newline.
crates/napi/scripts/constants.ts Removed the languageLibs constant, simplifying the structure of exported constants.
crates/napi/scripts/rules.ts Added a newline character at the end of the file for formatting consistency.
crates/napi/types/node-types.ts Modified the FieldSgNode type definition, maintaining structure but ensuring a newline at the end of the file.

Possibly related PRs

  • feat: support more languages in napi #1171: This PR modifies the crates/napi/index.d.ts file to update the FrontEndLanguage enum and introduces new parsing functions, which are related to the restructuring of type exports and function signatures in the main PR.
  • [RFC] feat(napi): Typed SgNode and SgRoot #1661: This PR enhances type definitions in crates/napi/index.d.ts, including updates to the SgNode and SgRoot classes, which aligns with the main PR's focus on restructuring type exports and modifying function signatures.
  • feat: Add support for range matcher #1626: The introduction of a new feature called RangeMatcher in this PR relates to the changes in the main PR, as both involve updates to function signatures and the handling of node types, particularly in the context of parsing and matching nodes based on specific criteria.

Poem

🐰 Hop, hop, through type terrain so bright,
Named exports dancing with delight!
From default to explicit, we leap and we sing,
TypeScript's magic on a rabbit's wing!
Code clarity blooms, type maps take flight! 🚀

Tip

CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command @coderabbitai generate docstrings to have CodeRabbit automatically generate docstrings for your pull request. This feature will be included in our Pro Plan when released.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 429d740 and c4d25e8.

📒 Files selected for processing (2)
  • crates/napi/index.d.ts (7 hunks)
  • crates/napi/scripts/generate-types.ts (3 hunks)
🧰 Additional context used
📓 Learnings (2)
crates/napi/scripts/generate-types.ts (2)
Learnt from: HerringtonDarkholme
PR: ast-grep/ast-grep#1662
File: crates/napi/scripts/generate-types.ts:49-49
Timestamp: 2024-12-14T18:57:37.142Z
Learning: In `crates/napi/scripts/generate-types.ts`, it's expected to assign the output of `JSON.stringify(nodeTypeMap, null, 2)` directly to a TypeScript type alias using `export type` syntax.
Learnt from: HerringtonDarkholme
PR: ast-grep/ast-grep#1662
File: crates/napi/scripts/generate-types.ts:128-129
Timestamp: 2024-12-14T18:57:47.685Z
Learning: In `crates/napi/scripts/generate-types.ts`, when re-exporting modules that only export types (e.g., `./types/${lang}-node-types`), use `export type { ... }` to correctly re-export the types in TypeScript.
crates/napi/index.d.ts (2)
Learnt from: HerringtonDarkholme
PR: ast-grep/ast-grep#1662
File: crates/napi/index.d.ts:2-23
Timestamp: 2024-12-14T18:56:38.743Z
Learning: In TypeScript declaration files (`.d.ts`), constants cannot be exported; only types and declarations can be exported.
Learnt from: HerringtonDarkholme
PR: ast-grep/ast-grep#1662
File: crates/napi/scripts/generate-types.ts:128-129
Timestamp: 2024-12-14T18:57:47.685Z
Learning: In `crates/napi/scripts/generate-types.ts`, when re-exporting modules that only export types (e.g., `./types/${lang}-node-types`), use `export type { ... }` to correctly re-export the types in TypeScript.
🔇 Additional comments (7)
crates/napi/scripts/generate-types.ts (4)

47-47: LGTM! Type export implementation is correct.

The implementation correctly exports node types as TypeScript type definitions, which aligns with the expected behavior for type generation.


Line range hint 62-94: LGTM! Type parameter simplification improves clarity.

The changes effectively simplify the type structure while maintaining type safety:

  • Removes redundant type parameters
  • Updates method signatures with more precise types
  • Maintains type safety with specific return types

Line range hint 124-124: LGTM! Import statements are properly structured.

The implementation correctly uses type-only imports and follows TypeScript best practices.


134-137: LGTM! Proper error handling implementation.

The error handling is well-implemented:

  • Catches potential errors from async operations
  • Logs errors to console for debugging
  • Exits with non-zero status code on failure
crates/napi/index.d.ts (3)

Line range hint 166-184: LGTM! HTML namespace type definitions are properly simplified.

The changes correctly simplify the return types while maintaining type safety, aligning with the type generation improvements.


Line range hint 188-206: LGTM! JavaScript namespace type definitions are consistent.

The changes maintain consistency with other namespaces while simplifying the type definitions.


Line range hint 210-294: LGTM! Consistent type definitions across all namespaces.

The changes maintain consistency and proper type definitions across all language namespaces (JSX, TypeScript, TSX, and CSS), following the same pattern of type simplification while preserving type safety.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@codecov
Copy link
Copy Markdown

codecov bot commented Dec 14, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 87.11%. Comparing base (dcb7916) to head (c4d25e8).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1662   +/-   ##
=======================================
  Coverage   87.11%   87.11%           
=======================================
  Files          96       96           
  Lines       15458    15458           
=======================================
  Hits        13467    13467           
  Misses       1991     1991           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dcb7916 and d52d857.

📒 Files selected for processing (3)
  • crates/napi/index.d.ts (2 hunks)
  • crates/napi/package.json (2 hunks)
  • crates/napi/scripts/generate-types.ts (4 hunks)
🔇 Additional comments (2)
crates/napi/scripts/generate-types.ts (1)

141-141: 🛠️ Refactor suggestion

Update inserted export statements to match corrected syntax

At line 141, the insertedText includes the exportStatements. Ensure that the export statements use the correct syntax for re-exporting constants:

Revise the insertedText as follows to reflect the changes:

{
  startPos: 0,
  endPos: 0,
- insertedText: exportStatements.join("\n") + "\n",
+ insertedText: exportStatements.join("\n") + "\n",
}

After applying the previous fix, the exportStatements variable will contain the correct export syntax.

Likely invalid or redundant comment.

crates/napi/package.json (1)

45-47: Verify the execution order of scripts involving type generation

The build:debug and prepublishOnly scripts have been updated to include yarn typegen:

"build:debug": "napi build --no-const-enum --platform && yarn typegen",
"prepublishOnly": "yarn typegen && napi prepublish -t npm --skip-gh-release",

Ensure that yarn typegen runs after the build process if it depends on build artifacts. Verify that the type generation works as expected in both debug and prepublish scenarios.

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Herrington Darkholme <2883231+HerringtonDarkholme@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (1)
crates/napi/scripts/generate-types.ts (1)

Line range hint 16-54: Consider architectural improvements for robustness

The type generation implementation could benefit from the following improvements:

  1. Add request timeouts for network calls to prevent hanging:
const timeout = 30000; // 30 seconds
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
const nodeTypesResponse = await fetch(url, { signal: controller.signal });
clearTimeout(timeoutId);
  1. Consider parallelizing type generation for better performance:
await Promise.all(
  Object.entries(languagesNodeTypesUrls).map(([lang, urlTemplate]) =>
    generateLangNodeType(lang, urlTemplate).catch(e => {
      console.error(`Error generating types for ${lang}:`, e);
    })
  )
);
  1. Add retry logic for network failures:
const retry = async (fn: () => Promise<any>, attempts = 3) => {
  for (let i = 0; i < attempts; i++) {
    try {
      return await fn();
    } catch (e) {
      if (i === attempts - 1) throw e;
      await new Promise(resolve => setTimeout(resolve, 1000 * Math.pow(2, i)));
    }
  }
};

Would you like me to provide a complete implementation of these improvements?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d52d857 and 8f9149b.

📒 Files selected for processing (1)
  • crates/napi/scripts/generate-types.ts (4 hunks)
🔇 Additional comments (3)
crates/napi/scripts/generate-types.ts (3)

162-165: LGTM: Proper error handling implemented

The error handling implementation for the main function looks good. It properly catches errors, logs them, and exits with a non-zero status code on failure.


49-49: ⚠️ Potential issue

Invalid TypeScript type assignment with JSON object

The current implementation attempts to assign a JSON object to a type alias, which is incorrect in TypeScript.

Apply this fix to correctly define the type:

-export type ${lang}NodeTypesMap = ${JSON.stringify(nodeTypeMap, null, 2)};
+export const ${lang}NodeTypesMap = ${JSON.stringify(nodeTypeMap, null, 2)} as const;
+export type ${lang}NodeTypesMapType = typeof ${lang}NodeTypesMap;

128-129: ⚠️ Potential issue

Incorrect re-export of types from modules

This issue is related to the previous type export problem. Once the node types are exported as constants, these re-exports need to be adjusted accordingly.

Apply this fix to correctly re-export the types:

const exportStatements = Object.keys(languagesNodeTypesUrls)
-  .map((lang) => `export type { ${lang}NodeTypesMap } from "./types/${lang}-node-types";`)
+  .map((lang) => [
+    `export { ${lang}NodeTypesMap } from "./types/${lang}-node-types";`,
+    `export type { ${lang}NodeTypesMapType } from "./types/${lang}-node-types";`
+  ].join('\n'))

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (1)
crates/napi/index.d.ts (1)

Line range hint 188-206: Consider retaining specific node type information in function return types for enhanced type safety.

The return types of functions like parse, parseAsync, and findInFiles have been generalized to SgRoot and SgNode[] across various language namespaces (html, js, jsx, ts, tsx, css). While this simplifies the function signatures, it may reduce type safety and make it more challenging for users to work with language-specific node types.

Consider parameterizing these functions with generic types or returning more specific types to retain detailed type information, which can help users leverage type checking and IntelliSense features in their development environment.

Also applies to: 210-228, 232-250, 254-272, 276-294, 298-316

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8f9149b and 429d740.

📒 Files selected for processing (6)
  • crates/napi/__test__/index.spec.ts (1 hunks)
  • crates/napi/index.d.ts (8 hunks)
  • crates/napi/scripts/constants.ts (1 hunks)
  • crates/napi/scripts/generate-types.ts (5 hunks)
  • crates/napi/scripts/rules.ts (1 hunks)
  • crates/napi/types/node-types.ts (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • crates/napi/scripts/rules.ts
  • crates/napi/types/node-types.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • crates/napi/scripts/generate-types.ts
🧰 Additional context used
📓 Learnings (1)
crates/napi/index.d.ts (2)
Learnt from: HerringtonDarkholme
PR: ast-grep/ast-grep#1662
File: crates/napi/index.d.ts:2-23
Timestamp: 2024-12-14T18:56:38.743Z
Learning: In TypeScript declaration files (`.d.ts`), constants cannot be exported; only types and declarations can be exported.
Learnt from: HerringtonDarkholme
PR: ast-grep/ast-grep#1662
File: crates/napi/scripts/generate-types.ts:128-129
Timestamp: 2024-12-14T18:57:47.685Z
Learning: In `crates/napi/scripts/generate-types.ts`, when re-exporting modules that only export types (e.g., `./types/${lang}-node-types`), use `export type { ... }` to correctly re-export the types in TypeScript.
🔇 Additional comments (2)
crates/napi/index.d.ts (1)

2-23: Exporting types correctly with export type statements.

The use of export type { ... } statements to re-export types from individual language node types is appropriate in TypeScript declaration files (.d.ts). This ensures that only type information is exported, adhering to TypeScript best practices.

crates/napi/scripts/constants.ts (1)

84-84: Verify that all references to languageLibs have been updated or removed.

The languageLibs constant has been removed. Please ensure that any references to languageLibs elsewhere in the codebase are also removed or updated to prevent potential runtime errors or broken functionality.

You can run the following script to search for any remaining references:

✅ Verification successful

No references to languageLibs found in the codebase

The comprehensive search across the codebase shows no remaining references to languageLibs. This indicates that all references have been properly removed along with the constant itself.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for references to 'languageLibs' in the codebase.

rg 'languageLibs' --type ts --type js

Length of output: 37


Script:

#!/bin/bash
# Let's try a more comprehensive search without type filters
# as the file might be in a different location or have a different extension

# First, let's use ripgrep without type filters
rg "languageLibs" -l

# Also search using ast-grep to catch any variable declarations or usages
ast-grep --pattern 'const languageLibs = $_'

# And search for any potential imports that might reference it
ast-grep --pattern 'import { $$$languageLibs$$$ } from $_'

Length of output: 128

const byKind = sg.root().find(js.kind("template_string"))
t.is(node!.id(), byKind!.id())
})
}) No newline at end of file
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot Dec 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Replace row with line in range positions to match the expected API properties.

In the test case starting at line 397, the start and end positions use row instead of line. The API expects the property line for specifying positions. Using row may lead to incorrect behavior or test failures.

Apply this diff to correct the property names:

-      range: {
-        start: { row: 0, column: 16 },
-        end: { row: 4, column: 1 },
-      }
+      range: {
+        start: { line: 0, column: 16 },
+        end: { line: 4, column: 1 },
+      }

Committable suggestion skipped: line range outside the PR's diff.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will address it later. This is an inconsistent naming in ast-grep node's interface and rule. Node has the naming line instead of row. And we should keep consistent naming here. cc @mohebifar

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@coderabbitai please open a follow-up GitHub issue for this inconsistency.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@HerringtonDarkholme, I've created a GitHub issue to track this inconsistency: #1663.

🔗 Analysis chain
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
gh issue create \
  --title "Inconsistent naming: 'line' vs 'row' in ast-grep node's interface and rule" \
  --body "There is an inconsistency between the use of \`line\` and \`row\` in the ast-grep node's interface and rule parameters. The node uses \`line\`, while the rule uses \`row\`, which may lead to confusion. This inconsistency should be addressed.

**References:**
- PR: https://github.com/ast-grep/ast-grep/pull/1662
- Comment: https://github.com/ast-grep/ast-grep/pull/1662#discussion_r1885373639

Reported by: @HerringtonDarkholme" \
  --assignee HerringtonDarkholme

Length of output: 629

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant