diff --git a/docs/building-with-codegen/external-modules.mdx b/docs/building-with-codegen/external-modules.mdx new file mode 100644 index 000000000..a3f0ce2ae --- /dev/null +++ b/docs/building-with-codegen/external-modules.mdx @@ -0,0 +1,119 @@ +--- +title: "External Modules" +sidebarTitle: "External Modules" +icon: "box-archive" +iconType: "solid" +--- + +Codegen provides a way to handle imports from external packages and modules through the [ExternalModule](/api-reference/core/ExternalModule) class. + +```python +# Python examples +import datetime +from requests import get + +# TypeScript/JavaScript examples +import React from 'react' +import { useState, useEffect } from 'react' +import type { ReactNode } from 'react' +import axios from 'axios' +``` + +## What are External Modules? + +When writing code, you often import from packages that aren't part of your project - like `datetime` and `requests` in Python, or `react` and `axios` in TypeScript. In Codegen, these are represented as [ExternalModule](/api-reference/core/ExternalModule) instances. + +```python +for imp in codebase.imports: + if isinstance(imp.symbol, ExternalModule): + print(f"Importing from external package: {imp.resolved_symbol.source}") +``` + + + External modules are read-only - you can analyze them but can't modify their + implementation. This makes sense since they live in your project's + dependencies! + + +## Working with External Modules + +The most common use case is handling external modules differently from your project's code: + +### Identifying Function Calls as External Modules + +For [FunctionCall](/api-reference/core/FunctionCall) instances, you can check if the function definition is an [ExternalModule](/api-reference/core/ExternalModule) via the [FunctionCall.function_definition](/api-reference/core/FunctionCall#function-definition) property: + +```python +for fcall in file.function_calls: + definition = fcall.function_definition + if isinstance(definition, ExternalModule): + # Skip external functions + print(f'External function: {definition.name}') + else: + # Process local functions... + print(f'Local function: {definition.name}') +``` + +### Import Resolution + +Similarly, when working with imports, you can determine if they resolve to external modules by checking the [Import.resolved_symbol](/api-reference/core/Import#resolved-symbol) property: + +```python +for imp in file.imports: + resolved = imp.resolved_symbol + if isinstance(resolved, ExternalModule): + print(f"Import from external package: from {imp.module} import {imp.name}") +``` + + + Use `isinstance(symbol, ExternalModule)` to reliably identify external + modules. This works better than checking names or paths since it handles all + edge cases. + + +## Properties and Methods + +External modules provide several useful properties: + +```python +# Get the module name +module_name = external_module.name # e.g. "datetime" or "useState" + +# Check if it's from node_modules (TypeScript/JavaScript) +if external_module.filepath == "": + print("This is an external package from node_modules") +``` + +## Common Patterns + +Here are some typical ways you might work with external modules: + +### Skip External Processing: + +When modifying function calls or imports, skip external modules since they can't be changed: + +```python +# Example from a codemod that adds type hints +def add_type_hints(function): + if isinstance(function.definition, ExternalModule): + return # Can't add type hints to external modules like React.FC + # Add type hints to local functions... +``` + +### Analyze Dependencies + +Track which external packages your code uses: + +```python +# Find all external package dependencies +external_deps = set() +for imp in codebase.imports: + if isinstance(imp.resolved_symbol, ExternalModule): + external_deps.add(imp.resolved_symbol.source) + # Will find things like 'react', 'lodash', 'datetime', etc. +``` + + + When working with imports, always handle external modules as a special case. + This ensures your codemods work correctly with both local and external code. + diff --git a/docs/mint.json b/docs/mint.json index 7c67d84c3..6d2f38396 100644 --- a/docs/mint.json +++ b/docs/mint.json @@ -102,6 +102,7 @@ "building-with-codegen/variable-assignments", "building-with-codegen/local-variables", "building-with-codegen/comments-and-docstrings", + "building-with-codegen/external-modules", "building-with-codegen/moving-symbols", "building-with-codegen/collections", "building-with-codegen/traversing-the-call-graph",