Skip to content

Comments

feat: Implement structured CodeCall fields (Issue #41 Part E)#47

Closed
phodal wants to merge 4 commits intomasterfrom
feat/toplevel-scope
Closed

feat: Implement structured CodeCall fields (Issue #41 Part E)#47
phodal wants to merge 4 commits intomasterfrom
feat/toplevel-scope

Conversation

@phodal
Copy link
Owner

@phodal phodal commented Jan 20, 2026

Description

This PR implements Issue #41 Part E: Call semantics structuring - adding structured fields to CodeCall and adapting all language parsers to populate them.

Changes

Core Domain Changes

  • Added 5 new structured fields to CodeCall:
    • ReceiverExpr: Original receiver expression text
    • ReceiverType: Resolved receiver type (CodeTypeRef)
    • Callee: Function/method name being called
    • IsOptionalChain: Optional chaining flag (TypeScript ?.)
    • Chain: List of method names in chained calls

Parser Adaptations

All language parsers have been updated to populate the new structured fields:

  • TypeScript: Full support with chain extraction and optional chaining detection
  • Go: Receiver expression and type resolution
  • Rust: Receiver expression extraction
  • Java: Method calls, field calls, and method references
  • Kotlin: Navigation and call suffix handling
  • Python: Function call receiver extraction
  • C#: Member access and object creation
  • Scala: Stable ID, infix expressions, and constructor calls

Testing

  • Added comprehensive tests for new CodeCall fields
  • All existing tests pass
  • Backward compatibility maintained with legacy fields

Related Issue

Closes #41 (Part E)

Checklist

  • Code follows project style guidelines
  • Tests added/updated and passing
  • Documentation updated (inline comments)
  • Backward compatibility maintained
  • All language parsers adapted

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced call tracking with structured field data for improved call analysis across supported languages.
    • Added optional chaining support for TypeScript.
  • Tests

    • Added comprehensive test coverage for new call analysis fields and backward compatibility.

✏️ Tip: You can customize this high-level summary in your review settings.

Add TopLevelScope structure to replace the legacy `default` node pattern
for representing file-level/module-level declarations across languages.

New types:
- TopLevelScope: container for top-level functions, fields, exports, type aliases
- CodeTypeAlias: represents type alias declarations (TypeScript, Rust, Go, C++)

CodeContainer additions:
- TopLevel field for structured top-level declarations
- getTopLevelFunctions(): combines TopLevel and legacy default nodes
- getTopLevelFields(): combines multiple sources
- getTopLevelExports(): returns exports from TopLevel
- getActualDataStructures(): excludes default nodes
- hasTopLevelDeclarations(): checks for any top-level content
- migrateDefaultNodesToTopLevel(): migration helper for parsers

This implements issue #41 section B (统一 top-level) while maintaining
full backward compatibility with existing code using default nodes.

Refs #41
- Fix isEmpty() to also check Extension map
- Fix KDoc for isEmpty() - now correctly says "has no declarations"
- Fix KDoc for isNotEmpty() - now says "has any declarations (i.e., is not empty)"
- Add isLegacyTopLevelContainer() method to CodeDataStruct for better
  identification of legacy top-level containers
- Update CodeContainer methods to use isLegacyTopLevelContainer()
- Add tests for Extension in isEmpty() check
- Add tests for isLegacyTopLevelContainer() method
…sers

Implements Issue #41 part E: Call semantics structuring

- Add structured fields to CodeCall:
  * ReceiverExpr: original receiver expression text
  * ReceiverType: resolved receiver type (CodeTypeRef)
  * Callee: function/method name being called
  * IsOptionalChain: optional chaining flag (TypeScript ?.)
  * Chain: list of method names in chained calls

- Adapt all language parsers to populate new fields:
  * TypeScript: full support with chain extraction and optional chaining
  * Go: receiver expression and type resolution
  * Rust: receiver expression extraction
  * Java: method calls, field calls, and method references
  * Kotlin: navigation and call suffix handling
  * Python: function call receiver extraction
  * C#: member access and object creation
  * Scala: stable ID, infix expressions, and constructor calls

- Add comprehensive tests for new CodeCall fields
- Maintain backward compatibility with legacy fields

Closes #41
Copilot AI review requested due to automatic review settings January 20, 2026 00:14
@coderabbitai
Copy link

coderabbitai bot commented Jan 20, 2026

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Adds structured ReceiverExpr and Callee fields to the CodeCall data structure across all language AST parsers and updates the core domain model with supporting documentation and tests.

Changes

Cohort / File(s) Summary
Core Domain Model
chapi-domain/src/main/kotlin/chapi/domain/core/CodeCall.kt, chapi-domain/src/test/kotlin/chapi/domain/core/CodeCallTest.kt
Adds public Callee: String field to CodeCall data class; updates documentation to establish Callee as the structured callee name (preferred over legacy FunctionName); introduces four new unit tests covering structured fields (ReceiverExpr, ReceiverType, Callee, Chain), optional chaining, and backward compatibility.
C# AST Listener
chapi-ast-csharp/src/main/kotlin/chapi/ast/csharpast/CSharpFullIdentListener.kt
Populates ReceiverExpr (from method identifier or type text) and Callee (from method name or "<init>") in Method_invocation and ObjectCreationExpression code call paths.
Go AST Listener & Tests
chapi-ast-go/src/main/kotlin/chapi/ast/goast/GoFullIdentListener.kt, chapi-ast-go/src/test/kotlin/chapi/ast/goast/GoAnalyserTest.kt
Populates ReceiverExpr (extracted target path), ReceiverType (resolved receiver type), and Callee (function name) across codeCallFromExprListWithPath, codeCallFromExprList, and direct operand/function call paths; updates test expectations.
Java AST Listener
chapi-ast-java/src/main/kotlin/chapi/ast/javaast/JavaFullIdentListener.kt
Populates ReceiverExpr (target type or method name source) and Callee (method name) in method call handling, field access, and lambda/method-reference paths.
Kotlin AST Listener
chapi-ast-kotlin/src/main/kotlin/chapi/ast/kotlinast/KotlinFullIdentListener.kt
Populates ReceiverExpr (from lastNodeName or lastIdentifier) and Callee (from lastIdentifier or navigationName) in CallSuffixContext and NavigationSuffixContext code call construction.
Python AST Listener
chapi-ast-python/src/main/kotlin/chapi/ast/pythonast/PythonAstBaseListener.kt
Populates ReceiverExpr (from nodeName) and Callee (from caller) in buildAtomExpr CodeCall instantiation.
Rust AST Listener
chapi-ast-rust/src/main/kotlin/chapi/ast/rustast/RustFullIdentListener.kt
Populates ReceiverExpr (nodeName or instanceVar) and Callee (function/macro name) in enterCallExpression, enterMethodCallExpression, and enterMacroInvocationSemi paths.
Scala AST Listener
chapi-ast-scala/src/main/kotlin/chapi/ast/scalaast/ScalaFullIdentListener.kt
Populates ReceiverExpr (from nodeName or receiver text) and Callee (function name or "<init>" for constructors) across direct function calls, infix method calls, and constructor invocations.
TypeScript AST Listener
chapi-ast-typescript/src/main/kotlin/chapi/ast/typescriptast/TypeScriptFullIdentListener.kt
Introduces private CallInfo data holder and extractCallInfo() helper to compute structured call metadata; refactors OptionalCallExpressionContext, MemberDotExpressionContext, and related paths to populate ReceiverExpr, Callee, Chain, and IsOptional fields consistently across optional and chained call expressions.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

🐰 A rabbit hops through parser trees so fine,
Receiver here, and Callee there align—
From Go to Rust, from Java's distant shore,
Each tongue now speaks what it was meant to store!
No more just strings, now structure rings clear—
The call is whole, and meaning draws near! 🎯

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 29.41% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main objective: implementing structured CodeCall fields as part of Issue #41. It clearly indicates this is part of a phased effort and directly reflects the primary change.
Linked Issues check ✅ Passed The PR successfully implements Objective E (Call semantics structuring) from Issue #41 by adding ReceiverExpr, ReceiverType, Callee, IsOptionalChain, and Chain fields to CodeCall across all language parsers with comprehensive test coverage.
Out of Scope Changes check ✅ Passed All changes are strictly in scope: CodeCall field additions and parser adaptations for C#, Go, Java, Kotlin, Python, Rust, Scala, and TypeScript align with Issue #41 Part E requirements; no unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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 implements structured call semantics by adding five new fields to CodeCall (ReceiverExpr, ReceiverType, Callee, IsOptionalChain, Chain) and updating all eight language parsers to populate these fields. Additionally, it introduces TopLevelScope to replace the legacy "default" node pattern for representing file-level declarations.

Changes:

  • Added structured fields to CodeCall for better representation of method calls, receivers, and call chains
  • Introduced TopLevelScope data class and CodeTypeAlias for top-level declarations
  • Updated all language parsers (TypeScript, Go, Rust, Java, Kotlin, Python, C#, Scala) to populate new structured fields
  • Added comprehensive tests for new domain classes and backward compatibility

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
chapi-domain/src/main/kotlin/chapi/domain/core/CodeCall.kt Added 5 new structured fields (ReceiverExpr, ReceiverType, Callee, IsOptionalChain, Chain) with detailed documentation
chapi-domain/src/main/kotlin/chapi/domain/core/TopLevelScope.kt New data class representing file-level declarations with helper methods
chapi-domain/src/main/kotlin/chapi/domain/core/CodeDataStruct.kt Added isLegacyTopLevelContainer() method to detect legacy top-level patterns
chapi-domain/src/main/kotlin/chapi/domain/core/CodeContainer.kt Added TopLevel field and helper methods for backward compatibility
chapi-domain/src/test/kotlin/chapi/domain/core/CodeCallTest.kt Added tests for new structured CodeCall fields and backward compatibility
chapi-domain/src/test/kotlin/chapi/domain/core/TopLevelScopeTest.kt Comprehensive tests for TopLevelScope across multiple languages
chapi-ast-typescript/src/main/kotlin/chapi/ast/typescriptast/TypeScriptFullIdentListener.kt Updated to populate structured call fields with chain extraction and optional chaining support
chapi-ast-go/src/main/kotlin/chapi/ast/goast/GoFullIdentListener.kt Updated to extract receiver expressions and resolve receiver types
chapi-ast-rust/src/main/kotlin/chapi/ast/rustast/RustFullIdentListener.kt Updated to populate ReceiverExpr and Callee fields
chapi-ast-java/src/main/kotlin/chapi/ast/javaast/JavaFullIdentListener.kt Updated to set structured fields for method calls and field accesses
chapi-ast-kotlin/src/main/kotlin/chapi/ast/kotlinast/KotlinFullIdentListener.kt Updated to populate ReceiverExpr and Callee for navigation expressions
chapi-ast-python/src/main/kotlin/chapi/ast/pythonast/PythonAstBaseListener.kt Updated to extract receiver information from function calls
chapi-ast-csharp/src/main/kotlin/chapi/ast/csharpast/CSharpFullIdentListener.kt Updated to populate structured fields for member access and object creation
chapi-ast-scala/src/main/kotlin/chapi/ast/scalaast/ScalaFullIdentListener.kt Updated to set ReceiverExpr and Callee for various call types
chapi-ast-go/src/test/kotlin/chapi/ast/goast/GoAnalyserTest.kt Updated test to include Callee field verification

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

@@ -521,15 +541,21 @@ class GoFullIdentListener(var fileName: String) : GoAstListener() {
val nodeName = handleForPrimary(child).orEmpty()

// if nodeName ends with $.functionName, the functionName should be remove
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

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

The comment says "if nodeName ends with $.functionName" but the code checks for ".$funcName". The dollar sign in the comment should be a period to match the actual code logic.

Suggested change
// if nodeName ends with $.functionName, the functionName should be remove
// if nodeName ends with .${funcName}, the functionName should be removed

Copilot uses AI. Check for mistakes.
Comment on lines 105 to 110
// Heuristic: Rust/Go module files often start with lowercase (e.g., "main", "file_mod")
// while actual classes/structs start with uppercase
val firstChar = NodeName.firstOrNull()
if (firstChar != null && firstChar.isLowerCase() && Type == DataStructType.OBJECT) {
return true
}
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

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

The heuristic for detecting legacy top-level containers based on lowercase first character may incorrectly flag legitimate lowercase-named types in languages like Rust where primitive types or type aliases can start with lowercase (e.g., "u32", "i64", "str"). Consider refining this heuristic to be more specific or adding additional checks to reduce false positives.

Copilot uses AI. Check for mistakes.
Comment on lines 879 to 883

// Create a CodeCall with IsOptionalChain = true
val callInfo = extractCallInfo(targetExpr)
val callee = targetExpr?.text?.substringAfterLast(".")?.substringBefore("(") ?: ""

Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

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

In the OptionalCallExpressionContext handling, the callee extraction logic may not correctly handle all cases. The expression targetExpr?.text?.substringAfterLast(".")?.substringBefore("(") assumes there's always a dot before the method name, but optional calls can also be simple function calls like foo?.(). Consider adding a fallback when no dot is present to use the full expression text or the last identifier.

Suggested change
// Create a CodeCall with IsOptionalChain = true
val callInfo = extractCallInfo(targetExpr)
val callee = targetExpr?.text?.substringAfterLast(".")?.substringBefore("(") ?: ""
// Create a CodeCall with IsOptionalChain = true
val callInfo = extractCallInfo(targetExpr)
val callee = targetExpr?.text?.let { text ->
// Strip off any argument list, then take the last identifier if dotted
val base = text.substringBefore("(")
val lastDotIndex = base.lastIndexOf('.')
if (lastDotIndex >= 0 && lastDotIndex < base.length - 1) {
base.substring(lastDotIndex + 1)
} else {
base
}
} ?: ""

Copilot uses AI. Check for mistakes.
Comment on lines +1043 to +1050
if (e.singleExpression().size >= 2) {
collectChain(e.singleExpression(0))
// The second singleExpression is the property being accessed
val propExpr = e.singleExpression(1)
if (propExpr is IdentifierExpressionContext) {
chain.add(propExpr.identifierName().text)
}
}
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

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

The extractCallInfo function's collectChain logic for OptionalChainExpressionContext checks if e.singleExpression().size >= 2, but this may not correctly handle all optional chaining scenarios. The grammar structure for optional chaining should be verified to ensure this indexing approach is always safe and correct.

Copilot uses AI. Check for mistakes.
Comment on lines +497 to +498
// Set ReceiverType if we can resolve it
currentCall.ReceiverType = CodeTypeRef.simple(resolvedFirst)
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

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

The ReceiverType is being set to CodeTypeRef.simple(resolvedFirst) where resolvedFirst is the type string from local variable lookup. However, if the variable is not found in localVars, resolvedFirst will be null and this will create a CodeTypeRef with a null name. This could lead to unexpected behavior. Consider adding a null check before setting ReceiverType.

Copilot uses AI. Check for mistakes.
- Merge master branch changes into feat/toplevel-scope
- Use IsOptional instead of IsOptionalChain (aligned with master)
- Add ChainArguments and ReturnType fields from master
- Keep Callee field from our implementation
- Update TypeScript parser to use IsOptional field
- Update tests to use IsOptional instead of IsOptionalChain
- Preserve all helper methods from master (allMethodNames, isChainedCall, etc.)
@codecov
Copy link

codecov bot commented Jan 20, 2026

Codecov Report

❌ Patch coverage is 71.96262% with 60 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.61%. Comparing base (c5ab35a) to head (dc116bf).
⚠️ Report is 3 commits behind head on master.

Files with missing lines Patch % Lines
...main/kotlin/chapi/ast/goast/GoFullIdentListener.kt 34.48% 19 Missing ⚠️
...i/ast/typescriptast/TypeScriptFullIdentListener.kt 76.62% 13 Missing and 5 partials ⚠️
...src/main/kotlin/chapi/domain/core/CodeContainer.kt 66.66% 1 Missing and 8 partials ⚠️
...otlin/chapi/ast/scalaast/ScalaFullIdentListener.kt 33.33% 6 Missing ⚠️
...src/main/kotlin/chapi/domain/core/TopLevelScope.kt 81.25% 3 Missing and 3 partials ⚠️
.../kotlin/chapi/ast/javaast/JavaFullIdentListener.kt 85.71% 0 Missing and 1 partial ⚠️
...rc/main/kotlin/chapi/domain/core/CodeDataStruct.kt 87.50% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master      #47      +/-   ##
============================================
+ Coverage     67.39%   67.61%   +0.21%     
- Complexity     1386     1436      +50     
============================================
  Files            77       78       +1     
  Lines          6548     6731     +183     
  Branches       1248     1275      +27     
============================================
+ Hits           4413     4551     +138     
- Misses         1402     1430      +28     
- Partials        733      750      +17     

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@phodal phodal closed this Jan 20, 2026
Copy link

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
chapi-ast-kotlin/src/main/kotlin/chapi/ast/kotlinast/KotlinFullIdentListener.kt (1)

199-210: Update Callee field in refineWithClass() to maintain consistency with FunctionName.

When refineWithClass() detects a creator and sets FunctionName = PRIMARY_CONSTRUCTOR (line 122), the Callee field is not updated. Since Callee is the preferred field in newer code (see allMethodNames() which uses Callee.ifEmpty { FunctionName }), this creates an inconsistency where:

  • FunctionName = "PrimaryConstructor"
  • Callee = original function name (unchanged)

Update refineWithClass() to also set Callee:

Suggested fix
private fun CodeCall.refineWithClass(it: CodeDataStruct): CodeCall? {
    if (FunctionName[0].isUpperCase()) {
        if (it.NodeName == FunctionName) {
            Type = CallType.CREATOR
            Package = it.Package
            NodeName = it.NodeName
            this.FunctionName = PRIMARY_CONSTRUCTOR
            this.Callee = PRIMARY_CONSTRUCTOR  // Add this
            return null
        }
    }
    return this
}
🤖 Fix all issues with AI agents
In `@chapi-ast-go/src/test/kotlin/chapi/ast/goast/GoAnalyserTest.kt`:
- Around line 30-36: The test's CodeCall instance is missing the ReceiverExpr
field which the Go parser sets; update the CodeCall (in the GoAnalyserTest
CodeCall with NodeName="fmt", FunctionName="Println", Callee="Println") to
include ReceiverExpr = "fmt" so the expected object matches the parser output.
♻️ Duplicate comments (3)
chapi-ast-typescript/src/main/kotlin/chapi/ast/typescriptast/TypeScriptFullIdentListener.kt (1)

875-890: Verify callee extraction for edge cases in optional calls.

The callee extraction at line 882 uses substringAfterLast(".")?.substringBefore("("), which assumes there's a dot in the expression. For simple optional calls like foo?.() (calling a nullable function directly), this would return the full expression text rather than just the function name.

Consider using the callInfo.callee if available, or falling back to a more robust extraction:

                 // Create a CodeCall with IsOptional = true
                 val callInfo = extractCallInfo(targetExpr)
-                val callee = targetExpr?.text?.substringAfterLast(".")?.substringBefore("(") ?: ""
+                val callee = callInfo.callee.ifBlank {
+                    targetExpr?.text?.let { text ->
+                        val base = text.substringBefore("(")
+                        if (base.contains('.')) base.substringAfterLast('.') else base
+                    } ?: ""
+                }
chapi-ast-go/src/main/kotlin/chapi/ast/goast/GoFullIdentListener.kt (2)

496-498: ReceiverType is safely set within null check.

The resolvedFirst variable is guaranteed non-null at line 498 because it's inside the if (resolvedFirst != null) block (line 486). The CodeTypeRef.simple(resolvedFirst) call is safe.


543-558: Comment typo: $ should be . to match the code logic.

The comment at line 543 says "if nodeName ends with $.functionName" but the code checks for ".$funcName". This was flagged in a previous review.

Comment on lines 30 to 36
CodeCall(
NodeName = "fmt",
FunctionName = "Println",
Parameters = listOf(CodeProperty(TypeValue = "hello world", TypeType = "string"))
Parameters = listOf(CodeProperty(TypeValue = "hello world", TypeType = "string")),
// New structured field
Callee = "Println"
)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, let's find the CodeCall class definition
fd -e kt -e java | xargs grep -l "class CodeCall" | head -5

Repository: phodal/chapi

Length of output: 177


🏁 Script executed:

# Search for ReceiverExpr in the codebase
rg "ReceiverExpr" --type=kt -B2 -A2

Repository: phodal/chapi

Length of output: 82


🏁 Script executed:

# Look at the test file to understand context better
cat -n chapi-ast-go/src/test/kotlin/chapi/ast/goast/GoAnalyserTest.kt | head -50

Repository: phodal/chapi

Length of output: 1834


🏁 Script executed:

# Check if there are other test cases in the same file that show ReceiverExpr usage
rg "CodeCall" chapi-ast-go/src/test/kotlin/chapi/ast/goast/GoAnalyserTest.kt -B1 -A6

Repository: phodal/chapi

Length of output: 469


🏁 Script executed:

# Read the CodeCall class definition
cat chapi-domain/src/main/kotlin/chapi/domain/core/CodeCall.kt

Repository: phodal/chapi

Length of output: 8600


🏁 Script executed:

# Search for ReceiverExpr in all files (without type filter)
rg "ReceiverExpr" -B2 -A2

Repository: phodal/chapi

Length of output: 26265


🏁 Script executed:

# Check for other CodeCall instances in Go tests
rg "CodeCall(" chapi-ast-go/src/test/kotlin -B1 -A8 | head -100

Repository: phodal/chapi

Length of output: 124


Test is incomplete - add ReceiverExpr field to match Go parser output.

The CodeCall should include ReceiverExpr = "fmt" alongside the existing Callee = "Println". The Go parser implementation populates ReceiverExpr with the receiver expression (the package/object the method is called on), and the CodeCall documentation for Go shows this pattern: ReceiverExpr="v1" for v1.Group(...). Without it, the test expectation won't match the actual parser output.

🤖 Prompt for AI Agents
In `@chapi-ast-go/src/test/kotlin/chapi/ast/goast/GoAnalyserTest.kt` around lines
30 - 36, The test's CodeCall instance is missing the ReceiverExpr field which
the Go parser sets; update the CodeCall (in the GoAnalyserTest CodeCall with
NodeName="fmt", FunctionName="Println", Callee="Println") to include
ReceiverExpr = "fmt" so the expected object matches the parser output.

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.

chapi-domain 核心模型:面向多语言 parser 的结构化改进(namespace/module、import/export、type、call、top-level)

1 participant