Initial commit
This commit is contained in:
314
skills/c4model-c4/signature-analysis.md
Normal file
314
skills/c4model-c4/signature-analysis.md
Normal file
@@ -0,0 +1,314 @@
|
||||
# Signature Analysis Methodology
|
||||
|
||||
This guide provides methodology for extracting and documenting function, method, and interface signatures at the C4 Code level.
|
||||
|
||||
---
|
||||
|
||||
## Parameter Extraction
|
||||
|
||||
### Required Information
|
||||
|
||||
For each parameter, extract:
|
||||
|
||||
| Field | Description | Example |
|
||||
|-------|-------------|---------|
|
||||
| `name` | Parameter name (original case) | `userId`, `options` |
|
||||
| `type` | Full type including generics | `string`, `UserOptions<T>` |
|
||||
| `optional` | Whether parameter is optional | `true`, `false` |
|
||||
| `default` | Default value if any | `{}`, `null`, `10` |
|
||||
|
||||
### TypeScript Examples
|
||||
|
||||
```typescript
|
||||
// Required parameter
|
||||
function getUser(userId: string) { }
|
||||
// → { name: "userId", type: "string", optional: false }
|
||||
|
||||
// Optional parameter
|
||||
function getUser(userId: string, includeDeleted?: boolean) { }
|
||||
// → { name: "includeDeleted", type: "boolean", optional: true }
|
||||
|
||||
// Default parameter
|
||||
function getUsers(limit: number = 10) { }
|
||||
// → { name: "limit", type: "number", optional: true, default: "10" }
|
||||
|
||||
// Generic parameter
|
||||
function transform<T>(input: T[]): T { }
|
||||
// → { name: "input", type: "T[]", optional: false }
|
||||
|
||||
// Object destructuring
|
||||
function create({ name, age }: UserInput) { }
|
||||
// → { name: "{ name, age }", type: "UserInput", optional: false }
|
||||
|
||||
// Rest parameters
|
||||
function concat(...items: string[]) { }
|
||||
// → { name: "...items", type: "string[]", optional: false }
|
||||
```
|
||||
|
||||
### Python Examples
|
||||
|
||||
```python
|
||||
# Required parameter
|
||||
def get_user(user_id: str) -> User:
|
||||
# → { name: "user_id", type: "str", optional: false }
|
||||
|
||||
# Optional parameter (with default)
|
||||
def get_users(limit: int = 10) -> List[User]:
|
||||
# → { name: "limit", type: "int", optional: true, default: "10" }
|
||||
|
||||
# Optional type hint
|
||||
def find_user(user_id: Optional[str]) -> Optional[User]:
|
||||
# → { name: "user_id", type: "Optional[str]", optional: false }
|
||||
|
||||
# *args and **kwargs
|
||||
def call_api(*args, **kwargs):
|
||||
# → { name: "*args", type: "Any", optional: true }
|
||||
# → { name: "**kwargs", type: "Any", optional: true }
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Return Type Analysis
|
||||
|
||||
### TypeScript Return Types
|
||||
|
||||
```typescript
|
||||
// Simple return
|
||||
function getName(): string { }
|
||||
// → return_type: "string"
|
||||
|
||||
// Promise return (async)
|
||||
async function getUser(): Promise<User> { }
|
||||
// → return_type: "Promise<User>", async: true
|
||||
|
||||
// Void return
|
||||
function logMessage(msg: string): void { }
|
||||
// → return_type: "void"
|
||||
|
||||
// Union return
|
||||
function find(): User | null { }
|
||||
// → return_type: "User | null"
|
||||
|
||||
// Generic return
|
||||
function first<T>(arr: T[]): T | undefined { }
|
||||
// → return_type: "T | undefined"
|
||||
|
||||
// No explicit return (inferred)
|
||||
function calculate() { return 42; }
|
||||
// → return_type: "number" (inferred)
|
||||
```
|
||||
|
||||
### Python Return Types
|
||||
|
||||
```python
|
||||
# Simple return
|
||||
def get_name() -> str:
|
||||
# → return_type: "str"
|
||||
|
||||
# Optional return
|
||||
def find_user() -> Optional[User]:
|
||||
# → return_type: "Optional[User]"
|
||||
|
||||
# Async return
|
||||
async def get_user() -> User:
|
||||
# → return_type: "User", async: true
|
||||
|
||||
# No return type (None)
|
||||
def log_message(msg: str) -> None:
|
||||
# → return_type: "None"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Async Detection
|
||||
|
||||
### Patterns to Detect
|
||||
|
||||
| Language | Pattern | Example |
|
||||
|----------|---------|---------|
|
||||
| TypeScript | `async` keyword | `async function fetchData()` |
|
||||
| TypeScript | Returns `Promise<T>` | `function fetch(): Promise<Data>` |
|
||||
| Python | `async def` | `async def fetch_data():` |
|
||||
| Java | Returns `CompletableFuture<T>` | `CompletableFuture<Data> fetchData()` |
|
||||
|
||||
### Examples
|
||||
|
||||
```typescript
|
||||
// Explicit async
|
||||
async function fetchUser(id: string): Promise<User> { }
|
||||
// → async: true, return_type: "Promise<User>"
|
||||
|
||||
// Returns Promise but not async keyword
|
||||
function fetchUser(id: string): Promise<User> {
|
||||
return fetch(`/users/${id}`).then(r => r.json());
|
||||
}
|
||||
// → async: false, return_type: "Promise<User>"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Generic Type Parameters
|
||||
|
||||
### Extracting Generics
|
||||
|
||||
```typescript
|
||||
// Single generic
|
||||
function identity<T>(value: T): T { }
|
||||
// → generic_params: ["T"]
|
||||
|
||||
// Multiple generics
|
||||
function map<T, U>(arr: T[], fn: (item: T) => U): U[] { }
|
||||
// → generic_params: ["T", "U"]
|
||||
|
||||
// Constrained generic
|
||||
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] { }
|
||||
// → generic_params: ["T", "K extends keyof T"]
|
||||
|
||||
// Default generic
|
||||
function createArray<T = string>(length: number): T[] { }
|
||||
// → generic_params: ["T = string"]
|
||||
```
|
||||
|
||||
### Python Generics
|
||||
|
||||
```python
|
||||
from typing import TypeVar, Generic
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
def identity(value: T) -> T:
|
||||
return value
|
||||
# → generic_params: ["T"]
|
||||
|
||||
class Container(Generic[T]):
|
||||
def get(self) -> T: ...
|
||||
# → generic_params: ["T"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Decorator Extraction
|
||||
|
||||
### TypeScript/JavaScript Decorators
|
||||
|
||||
```typescript
|
||||
@Injectable()
|
||||
@Singleton()
|
||||
class UserService { }
|
||||
// → decorators: ["@Injectable()", "@Singleton()"]
|
||||
|
||||
@Get('/users/:id')
|
||||
@UseGuards(AuthGuard)
|
||||
async getUser(@Param('id') id: string) { }
|
||||
// → decorators: ["@Get('/users/:id')", "@UseGuards(AuthGuard)"]
|
||||
```
|
||||
|
||||
### Python Decorators
|
||||
|
||||
```python
|
||||
@classmethod
|
||||
def from_dict(cls, data: dict) -> 'User':
|
||||
# → decorators: ["@classmethod"]
|
||||
|
||||
@staticmethod
|
||||
def validate(data: dict) -> bool:
|
||||
# → decorators: ["@staticmethod"]
|
||||
|
||||
@property
|
||||
def full_name(self) -> str:
|
||||
# → decorators: ["@property"]
|
||||
|
||||
@app.route('/users/<id>')
|
||||
@require_auth
|
||||
def get_user(id: str):
|
||||
# → decorators: ["@app.route('/users/<id>')", "@require_auth"]
|
||||
```
|
||||
|
||||
### Java Annotations
|
||||
|
||||
```java
|
||||
@Override
|
||||
public String toString() { }
|
||||
// → decorators: ["@Override"]
|
||||
|
||||
@GetMapping("/users/{id}")
|
||||
@PreAuthorize("hasRole('USER')")
|
||||
public User getUser(@PathVariable String id) { }
|
||||
// → decorators: ["@GetMapping(\"/users/{id}\")", "@PreAuthorize(\"hasRole('USER')\")"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Visibility Modifiers
|
||||
|
||||
### TypeScript/JavaScript
|
||||
|
||||
| Modifier | Visibility |
|
||||
|----------|------------|
|
||||
| `public` | public |
|
||||
| `private` | private |
|
||||
| `protected` | protected |
|
||||
| `#field` (private field) | private |
|
||||
| (no modifier) | public |
|
||||
|
||||
### Python
|
||||
|
||||
| Pattern | Visibility |
|
||||
|---------|------------|
|
||||
| `_method` | internal (convention) |
|
||||
| `__method` | private (name mangling) |
|
||||
| (no prefix) | public |
|
||||
|
||||
### Java
|
||||
|
||||
| Modifier | Visibility |
|
||||
|----------|------------|
|
||||
| `public` | public |
|
||||
| `private` | private |
|
||||
| `protected` | protected |
|
||||
| (package-private) | internal |
|
||||
|
||||
---
|
||||
|
||||
## Complete Signature Example
|
||||
|
||||
```json
|
||||
{
|
||||
"signature": {
|
||||
"parameters": [
|
||||
{
|
||||
"name": "userId",
|
||||
"type": "string",
|
||||
"optional": false
|
||||
},
|
||||
{
|
||||
"name": "options",
|
||||
"type": "GetUserOptions",
|
||||
"optional": true,
|
||||
"default": "{}"
|
||||
}
|
||||
],
|
||||
"return_type": "Promise<User>",
|
||||
"async": true,
|
||||
"generic_params": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
### ✅ DO:
|
||||
- Extract full type information including generics
|
||||
- Note optional parameters and defaults
|
||||
- Identify async functions correctly
|
||||
- Preserve exact decorator syntax
|
||||
- Document visibility modifiers
|
||||
|
||||
### ❌ DON'T:
|
||||
- Skip type information
|
||||
- Ignore generic parameters
|
||||
- Miss async/Promise patterns
|
||||
- Forget decorators that indicate behavior
|
||||
- Assume visibility without checking
|
||||
Reference in New Issue
Block a user