Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 4, 2025

The semantic analyzer treated named parameters in function calls (e.g., title="Length", shorttitle="ADR") as variable references, causing false "undefined variable" errors.

Changes

  • Modified SemanticAnalyzer.ts: When visiting function call arguments, detect Assignment nodes representing named parameters and validate only their right-hand side (value), not the left-hand side (parameter name)

  • Added test coverage: 6 tests covering named parameters in indicator(), input.*(), plot(), mixed positional/named parameters, and validation that undefined variables are still caught

Example

This now transpiles successfully:

indicator("Average Day Range", shorttitle="ADR", timeframe="", timeframe_gaps=true)
lengthInput = input.int(14, title="Length", minval=1)
plot(close, title="Close", color=color.blue, linewidth=2)

Previously failed with:

Transpile errors:
Line 0: Variable 'title' is not defined
Original prompt

Fix: Semantic analyzer incorrectly flags named parameters as undefined variables

Problem

The semantic analyzer is incorrectly reporting errors for named parameters in function calls. When parsing PineScript like:

indicator("Average Day Range", shorttitle="ADR", timeframe="", timeframe_gaps=true)
lengthInput = input.int(14, title="Length")
plot(adr, title="ADR")

The analyzer treats the left-hand side of named arguments (shorttitle, timeframe, timeframe_gaps, title) as variable references and reports:

Transpile errors:
Line 0: Variable 'title' is not defined

Root Cause

In SemanticAnalyzer.ts, when visiting function call arguments, the analyzer visits each argument expression. When an argument is a named parameter (an Assignment node like title="Length"), the visitExpression method visits the left-hand side Identifier node and checks if it's defined in the symbol table - which it isn't, because it's a parameter name, not a variable reference.

The current code at lines 100-105 correctly skips IndicatorDeclaration itself:

case 'IndicatorDeclaration':
case 'LibraryDeclaration':
  // These are declarations, not executable statements
  // We skip argument validation for these as they have complex named parameter handling
  break;

But the issue occurs in visitExpression when processing Assignment nodes that are function arguments (named parameters).

Solution

Modify the semantic analyzer to recognize when an Assignment node is being used as a named parameter (inside a function call) vs. a variable assignment (at statement level).

When visiting function call arguments:

  1. If the argument is an Assignment node, it's a named parameter
  2. Skip the undefined variable check for the left-hand side identifier
  3. Only visit the right-hand side expression for validation

Implementation

In packages/pine2ts/src/transpiler/semantic/SemanticAnalyzer.ts:

  1. Modify the FunctionCall case in visitExpression to handle named arguments specially:
case 'FunctionCall':
case 'GenericFunctionCall': {
  const funcName = String(node.value || '');
  
  // ... existing function validation code ...
  
  // Visit arguments - but handle named parameters specially
  if (node.children) {
    for (const arg of node.children) {
      // Named parameter: Assignment node where left side is the param name
      if (arg.type === 'Assignment' && arg.children && arg.children.length >= 2) {
        // Only visit the right side (the value), not the left side (param name)
        this.visitExpression(arg.children[1]!);
      } else {
        this.visitExpression(arg);
      }
    }
  }
  break;
}
  1. Also handle MethodCall nodes the same way, as they can also have named parameters.

  2. Add test cases to verify:

    • indicator() with named parameters works
    • input.int(), input.float(), etc. with title= parameter works
    • plot() with title=, color= parameters works
    • Regular variable references still get checked

Affected Files

  • packages/pine2ts/src/transpiler/semantic/SemanticAnalyzer.ts

Test Cases

Add tests in packages/pine2ts/tests/semantic.test.ts:

describe('named parameters', () => {
  it('should not error on named parameters in indicator()', () => {
    const source = `indicator("Test", shorttitle="T", overlay=true)`;
    const result = transpileWithResult(source);
    expect(result.errors).toHaveLength(0);
  });

  it('should not error on named parameters in input functions', () => {
    const source = `indicator("Test")
len = input.int(14, title="Length", minval=1, maxval=100)`;
    const result = transpileWithResult(source);
    expect(result.errors).toHaveLength(0);
  });

  it('should not error on named parameters in plot()', () => {
    const source = `indicator("Test")
plot(close, title="Close", color=color.red, linewidth=2)`;
    const result = transpileWithResult(source);
    expect(result.errors).toHaveLength(0);
  });

  it('should still error on actual undefined variables', () => {
    const source = `indicator("Test")
x = undefinedVar + 1`;
    const result = transpileWithResult(source);
    expect(result.errors.length).toBeGreaterThan(0);
    expect(result.errors[0].message).toContain('undefinedVar');
  });
});

Acceptance Criteria

  • indicator() with named parameters (shorttitle=, overlay=, timeframe=, etc.) transpiles without errors
  • input.*() functions with named parameters (title=, minval=, maxval=, etc.) transpile without errors
  • plot() with named parameters (title=, color=, linewidth=, etc.) transpiles without errors
  • Actual undefined variable references still produce errors
  • All existing tests pass
  • The Generate Indicators workflow succeeds for ADR.pine

This pull request was created as a result of the following prompt from Copilot chat.

Fix: Semantic analyzer incorrectly flags named parameters as undefined variables

Problem

The semantic analyzer is incorrectly reporting errors for named parameters in function calls. When parsing PineScript like:

indicator("Average Day Range", shorttitle="ADR", timeframe="", timeframe_gaps=true)
lengthInput = input.int(14, title="Length")
plot(adr, title="ADR")

The analyzer treats the left-hand side of named arguments (shorttitle, timeframe, timeframe_gaps, title) as variable references and reports:

Transpile errors:
Line 0: Variable 'title' is not defined

Root Cause

In SemanticAnalyzer.ts, when visiting function call arguments, the analyzer visits each argument expression. When an argument is a named parameter (an Assignment node like title="Length"), the visitExpression method visits the left-hand side Identifier node and checks if it's defined in the symbol table - which it isn't, because it's a parameter name, not a variable reference.

The current code at lines 100-105 correctly skips IndicatorDeclaration itself:

case 'IndicatorDeclaration':
case 'LibraryDeclaration':
  // These are declarations, not executable statements
  // We skip argument validation for these as they have complex named parameter handling
  break;

But the issue occurs in visitExpression when processing Assignment nodes that are function arguments (named parameters).

Solution

Modify the semantic analyzer to recognize when an Assignment node is being used as a named parameter (inside a function call) vs. a variable assignment (at statement level).

When visiting function call arguments:

  1. If the argument is an Assignment node, it's a named parameter
  2. Skip the undefined variable check for the left-hand side identifier
  3. Only visit the right-hand side expression for validation

Implementation

In packages/pine2ts/src/transpiler/semantic/SemanticAnalyzer.ts:

  1. Modify the FunctionCall case in visitExpression to handle named arguments specially:
case 'FunctionCall':
case 'GenericFunctionCall': {
  const funcName = String(node.value || '');
  
  // ... existing function validation code ...
  
  // Visit arguments - but handle named parameters specially
  if (node.children) {
    for (const arg of node.children) {
      // Named parameter: Assignment node where left side is the param name
      if (arg.type === 'Assignment' && arg.children && arg.children.length >= 2) {
        // Only visit the right side (the value), not the left side (param name)
        this.visitExpression(arg.children[1]!);
      } else {
        this.visitExpression(arg);
      }
    }
  }
  break;
}
  1. Also handle MethodCall nodes the same way, as they can also have named parameters.

  2. Add test cases to verify:

    • indicator() with named parameters works
    • input.int(), input.float(), etc. with title= parameter works
    • plot() with title=, color= parameters works
    • Regular variable references still get checked

Affected Files

  • packages/pine2ts/src/transpiler/semantic/SemanticAnalyzer.ts

Test Cases

Add tests in packages/pine2ts/tests/semantic.test.ts:

describe('named parameters', () => {
  it('should not error on named parameters in indicator()', () => {
    const source = `indicator("Test", shorttitle="T", overlay=true)`;
    const result = transpileWithResult(source);
    expect(result.errors).toHaveLength(0);
  });

  it('should not error on named parameters in input functions', () => {
    const source = `indicator("Test")
len = input.int(14, title="Length", minval=1, maxval=100)`;
    const result = transpileWithResult(source);
    expect(result.errors).toHaveLength(0);
  });

  it('should not error on named parameters in plot()', () => {
    const source = `indicator("Test")
plot(close, title="Close", color=color.red, linewidth=2)`;
    const result = transpileWithResult(source);
    expect(result.errors).toHaveLength(0);
  });

  it('should still error on actual undefined variables', () => {
    const source = `indicator("Test")
x = undefinedVar + 1`;
    const result = transpileWithResult(source);
    expect(result.errors.length).toBeGreaterThan(0);
    expect(result.errors[0].message).toContain('undefinedVar');
  });
});

Acceptance Criteria

  • indicator() with named parameters (shorttitle=, overlay=, timeframe=, etc.) transpiles without errors
  • input.*() functions with named parameters (title=, minval=, maxval=, etc.) transpile without errors
  • plot() with named parameters (title=, color=, linewidth=, etc.) transpiles without errors
  • Actual undefined variable references still produce errors
  • All existing tests pass
  • The Generate Indicators workflow succeeds for ADR.pine

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 2 commits December 4, 2025 21:56
Co-authored-by: deepentropy <8287111+deepentropy@users.noreply.github.com>
Co-authored-by: deepentropy <8287111+deepentropy@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix semantic analyzer for named parameters Fix semantic analyzer incorrectly flagging named parameters as undefined variables Dec 4, 2025
Copilot AI requested a review from deepentropy December 4, 2025 22:01
@deepentropy deepentropy marked this pull request as ready for review December 4, 2025 22:13
Copilot AI review requested due to automatic review settings December 4, 2025 22:13
@deepentropy deepentropy merged commit 0bec211 into main Dec 4, 2025
0 of 2 checks passed
@chatgpt-codex-connector
Copy link

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@deepentropy deepentropy deleted the copilot/fix-semantic-analyzer-errors branch December 4, 2025 22:13
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a bug where the semantic analyzer incorrectly treated named parameters in function calls (e.g., title="Length", shorttitle="ADR") as variable references, causing false "undefined variable" errors. The fix modifies the argument visiting logic to recognize Assignment nodes as named parameters and validate only their values, not the parameter names themselves.

Key Changes:

  • Modified SemanticAnalyzer.ts to detect Assignment nodes in function call arguments and validate only the right-hand side (value) while skipping the left-hand side (parameter name)
  • Added 6 comprehensive tests covering named parameters in various functions (indicator(), input.*(), plot()) and edge cases

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
packages/pine2ts/src/transpiler/semantic/SemanticAnalyzer.ts Added special handling for named parameters (Assignment nodes) in function call argument validation
packages/pine2ts/tests/semantic.test.ts Added comprehensive test suite for named parameter validation covering multiple scenarios and edge cases

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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