Skip to content

Conversation

@delino
Copy link

@delino delino bot commented Nov 8, 2025

Summary

This PR enables the test for the explicit-function-return-type rule by:

  1. Uncommenting the test file in rstest.config.mts (line 47)
  2. Implementing the rule from scratch in Go
  3. Registering the rule in the global rule registry

Implementation Details

The explicit-function-return-type rule enforces explicit return type annotations on functions and class methods in TypeScript code. This improves code clarity and can enhance type-checking performance in large codebases.

Supported Configuration Options

  • allowExpressions (default: false) - Permits function expressions to skip return type declarations
  • allowTypedFunctionExpressions (default: true) - Ignores functions with type annotations on the variable assignment
  • allowHigherOrderFunctions (default: true) - Overlooks functions that directly return other functions
  • allowDirectConstAssertionInArrowFunctions (default: true) - Exempts arrow functions using as const assertions
  • allowConciseArrowFunctionExpressionsStartingWithVoid (default: false) - Allows arrow functions prefixed with void keyword
  • allowFunctionsWithoutTypeParameters (default: false) - Ignores non-generic functions
  • allowIIFEs (default: false) - Exempts immediately invoked function expressions
  • allowedNames (default: []) - Array of specific function/method names to ignore

Files Changed

  • packages/rslint-test-tools/rstest.config.mts - Uncommented test file
  • internal/plugins/typescript/rules/explicit_function_return_type/explicit_function_return_type.go - New rule implementation
  • internal/config/config.go - Rule registration

Testing

The implementation follows the TypeScript-ESLint specification and handles:

  • Function declarations
  • Function expressions
  • Arrow functions
  • Method declarations
  • Getter accessors
  • All configuration options from the spec

References

🤖 Generated with Claude Code

Copy link
Owner

kdy1 commented Nov 8, 2025

🤖 This pull request has been linked to DevBird Task #1547

View the task details and manage the automated development workflow in DevBird.

Learn more about DevBird here or the announcement blog post here.

Copy link
Owner

kdy1 commented Nov 8, 2025

📋 DevBird Task Prompt

Enable the test for the explicit-function-return-type rule by uncommenting line 47 in packages/rslint-test-tools/rstest.config.mts.

Objective: Uncomment the test file ./tests/typescript-eslint/rules/explicit-function-return-type.test.ts in the rstest config and ensure all tests pass.

Documentation & Resources:

Steps:

  1. Uncomment line 47: // './tests/typescript-eslint/rules/explicit-function-return-type.test.ts',
  2. Run the tests: npm test or equivalent test command
  3. If tests fail, examine or create the Go implementation at internal/plugins/typescript/rules/explicit_function_return_type/explicit_function_return_type.go
  4. Fix any issues in the Go code to make tests pass

If CI Fails - Implement from Scratch:
If the tests fail due to missing or incomplete implementation, you must implement the explicit-function-return-type rule from scratch in Go:

  • Study the TypeScript-ESLint rule documentation thoroughly
  • Analyze the test cases to understand expected behavior
  • Create the necessary directory and files if they don't exist
  • Implement the rule logic requiring explicit return type annotations on functions
  • Support configuration options: allowExpressions, allowTypedFunctionExpressions, allowHigherOrderFunctions, allowDirectConstAssertionInArrowFunctions, allowConciseArrowFunctionExpressionsStartingWithVoid
  • Implement proper error messages

Success Criteria:

  • Test file is uncommented in rstest.config.mts
  • All tests in explicit-function-return-type.test.ts pass
  • CI build succeeds

This comment was automatically added by DevBird. You can disable this feature in DevBird Settings.

@claude
Copy link

claude bot commented Nov 8, 2025

Code Review: Enable test for explicit-function-return-type rule

Summary

This PR implements the explicit-function-return-type rule from scratch in Go, enabling comprehensive testing for TypeScript function return type enforcement. The implementation is thorough and follows the repository's patterns well.

✅ Strengths

1. Comprehensive Option Handling

  • All 8 configuration options from the TypeScript-ESLint spec are properly implemented
  • Default values match the spec correctly
  • Options parsing handles both array and map formats appropriately

2. Thorough Coverage

  • Handles all function types: declarations, expressions, arrow functions, methods, and getter accessors
  • Implements all the allowance checks: expressions, typed function expressions, higher-order functions, const assertions, void-prefixed functions, IIFEs, and allowed names
  • Test file exists and is properly enabled in the config

3. Code Quality

  • Well-structured with clear helper functions
  • Good separation of concerns
  • Follows Go naming conventions
  • Consistent with other rules in the codebase (similar to default_param_last.go)

🔍 Issues & Suggestions

1. Critical: Missing Constructor Check (explicit_function_return_type.go:469)

The rule skips constructors but only checks for ast.KindConstructor and ast.KindSetAccessor at line 469. However, constructors are not included in the listeners at line 558-564. This means:

  • Constructors won't be checked at all (which is correct)
  • But the check at line 469 is redundant since constructors never reach checkFunction

Recommendation: Remove the constructor check from line 469-471 or add a comment explaining why it exists for defensive programming.

2. Potential Bug: isTypedFunctionExpression Logic (explicit_function_return_type.go:223-227)

Lines 223-227 assume that any function passed to CallExpression or used in JSX is typed:

if parent.Kind == ast.KindCallExpression {
    return true // Assume typed if used as argument
}

This is too permissive. A callback passed to setTimeout(() => {}) is NOT a typed function expression. This could lead to false negatives where functions that should be flagged are incorrectly skipped.

Recommendation: Either:

  • Remove these optimistic assumptions, or
  • Add a comment acknowledging this is a known limitation without type system access

3. Incomplete: Higher-Order Function Detection (explicit_function_return_type.go:242-301)

The isHigherOrderFunction only checks for direct returns of functions. It misses:

  • Conditional returns: () => condition ? () => {} : null
  • Wrapped returns: () => Promise.resolve(() => {})
  • Multiple return statements with different paths

Example that would be missed:

function getData() {
  if (condition) {
    return () => {};
  }
  return null;
}

Recommendation: Add a comment documenting this limitation or enhance the detection to handle more cases.

4. Missing: Error Handling for Nil Checks

While the code has many nil checks, some accessor chains could still panic:

  • Line 111: fn.TypeParameters.Nodes - only checks if TypeParameters != nil but not if it has a valid structure
  • Line 266: block.Statements.Nodes - similar issue

Recommendation: Add defensive nil checks for Nodes fields or document that the AST guarantees these are never nil if the parent exists.

5. Code Style: Long Function (explicit_function_return_type.go:488-558)

The checkFunction is 70 lines long with deep nesting. Consider extracting the option checks into a separate helper function like shouldSkipFunction(node, opts) for better readability.

Recommendation:

func shouldSkipFunction(ctx rule.RuleContext, node *ast.Node, opts ExplicitFunctionReturnTypeOptions) bool {
    // All the skip logic here
    return false
}

func checkFunction(node *ast.Node) {
    if hasReturnType(node) || shouldSkipFunction(ctx, node, opts) {
        return
    }
    reportNode := getReportNode(node)
    ctx.ReportNode(reportNode, buildMissingReturnTypeMessage())
}

6. Performance: Repeated Parent Traversal

In isTypedFunctionExpression (lines 199-211), there's a loop that walks up the AST. For deeply nested structures, this could be inefficient if called repeatedly.

Recommendation: Consider caching or limiting the traversal depth.

7. Documentation: Missing Package Comment

The package lacks a package-level comment explaining what the rule does.

Recommendation: Add a package comment:

// Package explicit_function_return_type implements the @typescript-eslint/explicit-function-return-type rule.
// This rule enforces explicit return type annotations on functions and methods.
package explicit_function_return_type

🔒 Security Concerns

No security issues identified. The code:

  • Doesn't execute user input
  • Doesn't access filesystem
  • Only performs AST analysis

⚡ Performance Considerations

🧪 Test Coverage

✅ Test file exists and is enabled
✅ Links to TypeScript-ESLint spec in PR description
⚠️ Cannot verify test execution without CI results - recommend running tests locally

Recommendation: Run pnpm test to verify all test cases pass.

📋 Checklist Before Merge

Verdict

This is a solid implementation that follows the repository patterns well. The core logic is sound, but there are opportunities for improvement in edge case handling and code organization. The most critical issue is the overly permissive isTypedFunctionExpression logic that could lead to false negatives.

Recommendation: Approve with suggested improvements, or request changes if the isTypedFunctionExpression issue is deemed critical.


Review generated by Claude Code - please verify all suggestions apply to your specific use case

@kdy1 kdy1 marked this pull request as ready for review November 8, 2025 06:12
Copy link
Owner

@kdy1 kdy1 left a comment

Choose a reason for hiding this comment

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

Reflect #168 (comment) and rebase the PR to resolve merge conflicts

@kdy1 kdy1 marked this pull request as draft November 8, 2025 07:18
@kdy1 kdy1 marked this pull request as ready for review November 8, 2025 07:25
Copy link
Owner

@kdy1 kdy1 left a comment

Choose a reason for hiding this comment

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

rebase the PR to resolve merge conflicts

@kdy1 kdy1 marked this pull request as draft November 8, 2025 08:25
- Uncomment test file in rstest.config.mts
- Implement explicit-function-return-type rule in Go
- Add configuration options support for the rule

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@delino delino bot force-pushed the devbird/enable-explicit-function-return-type-test branch from f61c882 to 5834382 Compare November 8, 2025 08:28
@claude
Copy link

claude bot commented Nov 8, 2025

Code Review: explicit-function-return-type Rule Implementation

Thank you for implementing this rule! I've conducted a thorough review of the code. Overall, the implementation is well-structured and follows good Go practices. Below are my findings organized by category:


✅ Strengths

  1. Comprehensive Option Support: All 8 configuration options from the TypeScript-ESLint spec are correctly implemented
  2. Well-Documented Code: Excellent inline comments explaining the purpose of each function
  3. Consistent with Codebase: Follows the same patterns as other rules in the repository
  4. Proper Error Handling: Nil checks throughout prevent potential panics
  5. Clean Structure: Good separation of concerns with dedicated helper functions

🔍 Code Quality & Best Practices

Positive Aspects

  • Function naming: Clear, descriptive names like isTypedFunctionExpression, shouldSkipFunction
  • Code organization: Logical grouping of related functionality
  • Type safety: Proper type assertions and nil checks throughout

Suggestions for Improvement

  1. Reduce Cognitive Complexity (internal/plugins/typescript/rules/explicit_function_return_type/explicit_function_return_type.go:247-315)

    The isHigherOrderFunction has significant nesting and repetition. Consider extracting a helper:

    func getReturnedExpression(stmt *ast.Node) *ast.Node {
        if stmt.Kind == ast.KindReturnStatement {
            retStmt := stmt.AsReturnStatement()
            if retStmt \!= nil {
                return retStmt.Expression
            }
        }
        return nil
    }
  2. DRY Principle Violation (explicit_function_return_type.go:95-111, 113-131)

    hasReturnType and hasTypeParameters have nearly identical switch structures. Consider a generic helper:

    func getFunctionLikeNode(node *ast.Node) interface{} {
        switch node.Kind {
        case ast.KindFunctionDeclaration:
            return node.AsFunctionDeclaration()
        // ... etc
        }
    }
  3. Magic Values: Consider defining constants for commonly used node kinds or creating a functionLikeKinds slice


🐛 Potential Bugs & Edge Cases

Critical Issues

  1. Incomplete Type Inference Detection (explicit_function_return_type.go:221-245)

    The code includes this honest comment:

    // Note: Without full type system access, we cannot accurately determine if a function passed as an argument...

    Impact: This leads to false negatives where functions that should be flagged aren't detected:

    • setTimeout(() => {}) - callback is NOT typed
    • array.map((x) => {}) - currently incorrectly considered typed
    • <Component onClick={() => {}} /> - JSX props

    Recommendation: Document this limitation clearly in the rule's user-facing documentation and consider adding a configuration option like strictTypedFunctionExpressions to make this behavior configurable.

  2. Incomplete Higher-Order Function Detection (explicit_function_return_type.go:247)

    The comment states:

    // Note: This only checks for direct returns... It does not handle: Conditional returns, Wrapped returns, Multiple return paths

    Impact: False positives - functions that are higher-order won't be detected and will be incorrectly flagged.

    Examples that won't be detected:

    const hof = () => condition ? () => {} : null;  // Not detected
    const wrapped = () => Promise.resolve(() => {});  // Not detected

    Recommendation: Either improve detection or document this limitation.

  3. AST Traversal Boundary Conditions (explicit_function_return_type.go:202-219)

    In isTypedFunctionExpression, the parent traversal stops at KindSourceFile or KindBlock, but nested blocks in control flow statements might cause early termination:

    if (condition) {
        const obj = { method: () => {} };  // Might stop at if-block
    }

Minor Issues

  1. Edge Case: Constructor Parameter Properties (not explicitly handled)

    class Foo {
        constructor(public callback = () => {}) {}  // Is this detected?
    }
  2. isExpression May Miss Cases (explicit_function_return_type.go:351-378)

    Doesn't check for:

    • KindObjectLiteralExpression property values
    • KindTemplateLiteralExpression embedded expressions
    • KindSpreadElement

⚡ Performance Considerations

Positive

  • No unnecessary allocations in hot paths
  • Efficient early returns in helper functions
  • Good use of switch statements over multiple if-else chains

Concerns

  1. Parent Traversal in isTypedFunctionExpression (line 204)

    Unbounded upward traversal could be expensive in deeply nested structures:

    for p := parent.Parent; p \!= nil; p = p.Parent {

    Recommendation: Add a depth limit (e.g., 10 levels) or improve boundary detection.

  2. Repeated String Comparisons (line 143)

    if ident \!= nil && ident.Text == "const" {

    Consider caching or using constants, though impact is minimal.


🔒 Security Concerns

No security issues identified. The code:

  • ✅ Doesn't perform any file I/O or network operations
  • ✅ Doesn't execute external commands
  • ✅ Properly handles untrusted input through nil checks
  • ✅ No potential for injection attacks or buffer overflows (Go's memory safety)

🧪 Test Coverage

Analysis

  1. Test File Enabled

    • Properly uncommented in rstest.config.mts
    • References existing TypeScript-ESLint test suite
  2. Missing Go Unit Tests ⚠️

    Other rules have companion *_test.go files (e.g., default_param_last_test.go), but this rule doesn't have one.

    Recommendation: Add explicit_function_return_type_test.go with unit tests for:

    • Each helper function (isConstAssertion, isHigherOrderFunction, etc.)
    • Edge cases identified above
    • Options parsing logic
  3. Test Scenarios to Add

    Based on the implementation's acknowledged limitations, ensure tests cover:

    • Functions passed to untyped callbacks
    • Conditional return of functions
    • Deeply nested type contexts
    • Parameter properties with function defaults

📝 Additional Recommendations

  1. Add Package-Level Documentation

    // Package explicit_function_return_type implements the @typescript-eslint/explicit-function-return-type rule.
    // 
    // Known Limitations:
    // - Cannot detect type inference from callback parameters without full type system
    // - Higher-order function detection limited to direct returns
    //
    // See: https://typescript-eslint.io/rules/explicit-function-return-type/
  2. Improve Error Messages

    Current: "Missing return type on function."

    Consider adding context:

    Description: fmt.Sprintf("Missing return type on function '%s'.", getFunctionName(ctx, node))
  3. Configuration Validation

    The parseOptions function silently ignores invalid options. Consider logging warnings for unknown configuration keys.


🎯 Summary

Category Status Notes
Code Quality ⚠️ Good Minor refactoring opportunities
Correctness ⚠️ Acceptable Documented limitations may cause false positives/negatives
Performance ✅ Good Minor optimization potential
Security ✅ Excellent No concerns
Test Coverage ⚠️ Needs Work Missing Go unit tests

Verdict

Conditionally Approve - The implementation is solid and ready for merge with the understanding that:

  1. The documented limitations are acceptable trade-offs
  2. A follow-up PR should add Go unit tests
  3. User documentation should clearly explain the limitations

The code follows the repository's patterns well and demonstrates good understanding of both Go and the rule's requirements. Great work! 🎉


Priority Action Items:

  1. 🔴 High: Add Go unit tests in a follow-up PR
  2. 🟡 Medium: Document limitations in user-facing docs
  3. 🟢 Low: Consider refactoring for reduced complexity (technical debt)

@kdy1 kdy1 marked this pull request as ready for review November 8, 2025 08:40
@kdy1 kdy1 enabled auto-merge (squash) November 8, 2025 10:06
@kdy1 kdy1 merged commit 030cf98 into main Nov 8, 2025
9 checks passed
@kdy1 kdy1 deleted the devbird/enable-explicit-function-return-type-test branch November 8, 2025 10:06
kdy1 pushed a commit that referenced this pull request Nov 9, 2025
## Summary

This PR enables the test for the `explicit-function-return-type` rule
by:
1. Uncommenting the test file in `rstest.config.mts` (line 47)
2. Implementing the rule from scratch in Go
3. Registering the rule in the global rule registry

## Implementation Details

The `explicit-function-return-type` rule enforces explicit return type
annotations on functions and class methods in TypeScript code. This
improves code clarity and can enhance type-checking performance in large
codebases.

### Supported Configuration Options

- `allowExpressions` (default: `false`) - Permits function expressions
to skip return type declarations
- `allowTypedFunctionExpressions` (default: `true`) - Ignores functions
with type annotations on the variable assignment
- `allowHigherOrderFunctions` (default: `true`) - Overlooks functions
that directly return other functions
- `allowDirectConstAssertionInArrowFunctions` (default: `true`) -
Exempts arrow functions using `as const` assertions
- `allowConciseArrowFunctionExpressionsStartingWithVoid` (default:
`false`) - Allows arrow functions prefixed with `void` keyword
- `allowFunctionsWithoutTypeParameters` (default: `false`) - Ignores
non-generic functions
- `allowIIFEs` (default: `false`) - Exempts immediately invoked function
expressions
- `allowedNames` (default: `[]`) - Array of specific function/method
names to ignore

### Files Changed

- `packages/rslint-test-tools/rstest.config.mts` - Uncommented test file
-
`internal/plugins/typescript/rules/explicit_function_return_type/explicit_function_return_type.go`
- New rule implementation
- `internal/config/config.go` - Rule registration

## Testing

The implementation follows the TypeScript-ESLint specification and
handles:
- Function declarations
- Function expressions
- Arrow functions
- Method declarations
- Getter accessors
- All configuration options from the spec

## References

- TypeScript-ESLint rule documentation:
https://typescript-eslint.io/rules/explicit-function-return-type/
- Test file:
`packages/rslint-test-tools/tests/typescript-eslint/rules/explicit-function-return-type.test.ts`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
delino bot pushed a commit that referenced this pull request Nov 9, 2025
Implements the TypeScript-ESLint explicit-member-accessibility rule
that enforces explicit accessibility modifiers (public, private, protected)
on class members.

**Implementation Details:**
- Full rule implementation in Go with support for all configuration options
- Supports accessibility levels: 'explicit', 'no-public', and 'off'
- Supports member-specific overrides for:
  - parameterProperties
  - constructors
  - methods
  - properties
  - accessors
- Supports ignoredMethodNames option to exclude specific methods

**Test Coverage:**
- All test cases from TypeScript-ESLint repository included
- Test file enabled in rstest.config.mts
- Covers valid and invalid cases for all member types
- Tests all configuration options and overrides

Related to #168

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
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.

2 participants