Skip to content

Comments

Clanup AST representation of TypeDesc#174

Merged
warunalakshitha merged 1 commit intoballerina-platform:mainfrom
heshanpadmasiri:refact/ast
Feb 24, 2026
Merged

Clanup AST representation of TypeDesc#174
warunalakshitha merged 1 commit intoballerina-platform:mainfrom
heshanpadmasiri:refact/ast

Conversation

@heshanpadmasiri
Copy link
Member

@heshanpadmasiri heshanpadmasiri commented Feb 20, 2026

Purpose

Remove type descriptors from nodes that don't have type descriptors

Goals

Describe the solutions that this feature/fix will introduce to resolve the problems described above

Approach

Describe how you are implementing the solutions. Include an animated GIF or screenshot if the change affects the UI (email documentation@wso2.com to review all UI text). Include a link to a Markdown file or Google doc if the feature write-up is too long to paste here.

User stories

Summary of user stories addressed by this change>

Release note

Brief description of the new feature or bug fix as it will appear in the release notes

Documentation

Link(s) to product documentation that addresses the changes of this PR. If no doc impact, enter �N/A� plus brief explanation of why there�s no doc impact

Training

Link to the PR for changes to the training content in https://github.com/wso2/WSO2-Training, if applicable

Certification

Type �Sent� when you have provided new/updated certification questions, plus four answers for each question (correct answer highlighted in bold), based on this change. Certification questions/answers should be sent to certification@wso2.com and NOT pasted in this PR. If there is no impact on certification exams, type �N/A� and explain why.

Marketing

Link to drafts of marketing content that will describe and promote this feature, including product page changes, technical articles, blog posts, videos, etc., if applicable

Automation tests

  • Unit tests

    Code coverage information

  • Integration tests

    Details about the test cases and coverage

Security checks

Samples

Provide high-level details about the samples related to this feature

Related PRs

List any other related PRs

Migrations (if applicable)

Describe migration steps and platforms on which migration has been tested

Test environment

List all JDK versions, operating systems, databases, and browser/versions on which this feature/fix was tested

Learning

Describe the research phase and any blog posts, patterns, libraries, or add-ons you used to solve the problem.

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Improved type descriptor handling for annotations, variables, and functions.
  • Refactor

    • Simplified type system APIs by restructuring internal type representation.
    • Updated method naming for type accessors (e.g., descriptor-based methods replacing data-based accessors).
    • Enhanced variable type node support with dedicated accessors.

@coderabbitai
Copy link

coderabbitai bot commented Feb 20, 2026

📝 Walkthrough

Walkthrough

This PR refactors the AST and type system by making BLangNodeBase unexported, migrating from TypeData to TypeDescriptor for storing type information, and introducing direct type node accessors (TypeNode/SetTypeNode for variables, ValueType/SetValueType for literals). Public model interfaces are updated to align with descriptor-based typing.

Changes

Cohort / File(s) Summary
Core AST Base Type Visibility
ast/ast.go, ast/binding_patterns.go, ast/clauses.go, ast/match_patterns.go, ast/statements.go
Replaced exported BLangNodeBase with unexported bLangNodeBase in multiple struct embeddings across annotation, pattern, clause, and statement definitions; removed SetTypeData from BLangNode interface.
Type System Migration to Descriptors
ast/ast.go, ast/expressions.go, ast/types.go
Migrated from TypeData to TypeDescriptor for BLangAnnotation, BLangInvokableNodeBase, and BLangTypedescExpr; updated accessors from GetTypeData/SetTypeData to GetTypeDescriptor/SetTypeDescriptor; added GetTypeData/SetTypeData to BType interface.
Variable and Literal Type Accessors
ast/ast.go, ast/expressions.go
Added typeNode field and TypeNode/SetTypeNode accessors to BLangVariableBase; added valueType field and GetValueType/SetValueType methods to BLangLiteral.
Type System Refactoring
ast/types.go
Renamed BTypeImpl to BTypeBasic; made BLangTypeBase unexported (bLangTypeBase); updated multiple type definitions to use bLangTypeBase embedding; adjusted constructor and method signatures accordingly.
AST Traversal and Printing
ast/walk.go, ast/pretty_printer.go
Added walkTypeDescriptor helper function to traverse TypeDescriptor nodes; updated walk logic to use new descriptors; aligned printBLangNodeBase signature with unexported base type; replaced TypeData-based type access with TypeNode-based checks.
Node Builder Updates
ast/node_builder.go
Replaced SetTypeData calls with SetTypeNode for variables and SetValueType for literals; replaced SetReturnTypeData with SetReturnTypeDescriptor; updated type node creation paths to use direct descriptor assignment.
Public Model Interface Changes
model/tree.go
Added GetTypeData to Type interface; removed GetTypeData from Node interface; replaced GetTypeData/SetTypeData with GetTypeDescriptor/SetTypeDescriptor in AnnotationNode and TypedescExpressionNode; replaced GetReturnTypeData/SetReturnTypeData with descriptor versions in InvokableNode; removed type data accessors from VariableNode and ConstantNode.
Semantic Type Resolution
semantics/semantic_analyzer.go, semantics/type_resolver.go
Replaced GetTypeData().Type access with GetDeterminedType() calls; replaced SetTypeData with SetDeterminedType; updated type resolution to use GetValueType and TypeNode accessors; added VisitTypeData method to TypeResolver; restructured DeterminedType initialization logic.
Test Updates
semantics/corpus_type_resolver_test.go
Removed validation of TypeData.Type consistency checks in expression type verification.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • warunalakshitha
  • gimantha

Poem

🐰 The types have shed their DataDust so fine,
Descriptors now in places they align,
BaseTypes rest in privacy's embrace,
While ValueTypes find their proper place,
A hop, a skip—the AST's restructured well! ✨

🚥 Pre-merge checks | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description follows the template structure but is largely incomplete, containing only the 'Purpose' section ('Remove type descriptors from nodes that don't have type descriptors') while all other required sections remain as placeholder text requesting information. Complete all required sections: Goals (explain what this refactoring achieves), Approach (describe implementation strategy), include test details, security checks status, and relevant documentation/release notes. At minimum, fill Goals, Approach, Automation tests, and Security checks sections.
Docstring Coverage ⚠️ Warning Docstring coverage is 22.22% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Clanup AST representation of TypeDesc' contains a typo ('Clanup' instead of 'Cleanup') and is vague about the specific changes, though it does reference the main area being modified (AST TypeDesc representation). Correct the typo to 'Cleanup AST representation of TypeDesc' or provide a more specific title describing the refactoring scope (e.g., 'Refactor AST TypeDesc: remove unnecessary type descriptors from base nodes').

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

@codecov
Copy link

codecov bot commented Feb 20, 2026

Codecov Report

❌ Patch coverage is 61.83206% with 50 lines in your changes missing coverage. Please review.
✅ Project coverage is 27.65%. Comparing base (28f0f56) to head (070f277).
⚠️ Report is 47 commits behind head on main.

Files with missing lines Patch % Lines
ast/types.go 20.68% 23 Missing ⚠️
ast/node_builder.go 79.31% 6 Missing ⚠️
ast/walk.go 50.00% 4 Missing and 2 partials ⚠️
semantics/type_resolver.go 72.22% 3 Missing and 2 partials ⚠️
ast/ast.go 75.00% 4 Missing ⚠️
ast/expressions.go 50.00% 4 Missing ⚠️
ast/pretty_printer.go 75.00% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #174      +/-   ##
==========================================
- Coverage   27.80%   27.65%   -0.16%     
==========================================
  Files         253      253              
  Lines       53810    53801       -9     
==========================================
- Hits        14963    14879      -84     
- Misses      37911    37994      +83     
+ Partials      936      928       -8     

☔ 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.

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

🧹 Nitpick comments (1)
ast/types.go (1)

61-76: Extract shared type fields into a private base.

bLangTypeBase and BTypeBasic both carry ty/tag/name/flags and duplicate their getters/setters. A small private base struct would remove duplication and keep the shared-field rule intact.

♻️ Suggested structure
+type bTypeBase struct {
+    ty    model.TypeData
+    tag   model.TypeTags
+    name  model.Name
+    flags uint64
+}
+
+func (b *bTypeBase) GetTypeData() model.TypeData { return b.ty }
+func (b *bTypeBase) SetTypeData(ty model.TypeData) { b.ty = ty }
+func (b *bTypeBase) BTypeGetTag() model.TypeTags { return b.tag }
+func (b *bTypeBase) bTypeSetTag(tag model.TypeTags) { b.tag = tag }
+func (b *bTypeBase) bTypeGetName() model.Name { return b.name }
+func (b *bTypeBase) bTypeSetName(name model.Name) { b.name = name }
+func (b *bTypeBase) bTypeGetFlags() uint64 { return b.flags }
+func (b *bTypeBase) bTypeSetFlags(flags uint64) { b.flags = flags }
+
 type bLangTypeBase struct {
     bLangNodeBase
-    ty      model.TypeData
+    bTypeBase
     FlagSet common.UnorderedSet[model.Flag]
     Grouped bool
     tags    model.TypeTags
     name    model.Name
     flags   uint64
 }
 
 type BTypeBasic struct {
-    ty    model.TypeData
-    tag   model.TypeTags
-    name  model.Name
-    flags uint64
+    bTypeBase
 }

As per coding guidelines: "If multiple structs need to hold same set of fields and implement methods on those fields, add a *Base struct and use type inclusion on other structs. Make this base struct private and implement the relevant methods on the base struct."

Also applies to: 305-351, 373-379

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ast/types.go` around lines 61 - 76, Create a private base struct to hold the
repeated fields (ty, tag, name, flags) and implement the shared getters/setters
on that base, then embed it into bLangTypeBase and BTypeBasic to remove
duplicated fields and methods; specifically, add a private type (e.g., type
typeBase struct { ty model.TypeData; tag model.TypeTags; name model.Name; flags
uint64 }) with methods for the existing getters/setters, replace the explicit
ty/tag/name/flags fields in bLangTypeBase and BTypeBasic with an embedded
typeBase, and update all methods currently implemented on bLangTypeBase and
BTypeBasic (including the other occurrences around the referenced ranges) to
call the base methods so behavior and visibility remain unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ast/ast.go`:
- Around line 408-412: BLangVariableBase.typeNode is declared as BType but may
be assigned a BTypeBasic (from NewBType) which does not implement BLangNode and
will cause panics where code casts typeNode to BLangNode (e.g., in
pretty_printer.go and walk.go). Fix by narrowing the field to the proper node
interface (e.g., change BLangVariableBase.typeNode from BType to BLangNode or a
new BLangType interface that excludes BTypeBasic) OR keep the BType but add safe
type assertions where typeNode is cast (guard the casts with an "ok" check and
handle the non-BLangNode case). Update references to BLangVariableBase.typeNode
and the casts in pretty_printer.go and walk.go accordingly.

---

Nitpick comments:
In `@ast/types.go`:
- Around line 61-76: Create a private base struct to hold the repeated fields
(ty, tag, name, flags) and implement the shared getters/setters on that base,
then embed it into bLangTypeBase and BTypeBasic to remove duplicated fields and
methods; specifically, add a private type (e.g., type typeBase struct { ty
model.TypeData; tag model.TypeTags; name model.Name; flags uint64 }) with
methods for the existing getters/setters, replace the explicit ty/tag/name/flags
fields in bLangTypeBase and BTypeBasic with an embedded typeBase, and update all
methods currently implemented on bLangTypeBase and BTypeBasic (including the
other occurrences around the referenced ranges) to call the base methods so
behavior and visibility remain unchanged.

We should have type descriptors only for nodes that needs them
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.

Caution

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

⚠️ Outside diff range comments (2)
ast/node_builder.go (1)

34-69: ⚠️ Potential issue | 🟠 Major

Handle BYTE (and BYTE_ARRAY) in the type table to avoid panics.

createSimpleLiteralInner can set typeTag to BYTE or BYTE_ARRAY, but getTypeFromTag only handles boolean/int/nil/string/float/decimal, so valid literals will panic.

🔧 Proposed fix (add missing tags to typeTable)
 type typeTable struct {
 	booleanType *BTypeBasic
 	intType     *BTypeBasic
+	byteType    *BTypeBasic
 	nilType     *BTypeBasic
 	stringType  *BTypeBasic
 	floatType   *BTypeBasic
 	decimalType *BTypeBasic
+	byteArrayType *BTypeBasic
 }
 
 func newTypeTable() typeTable {
 	return typeTable{
 		booleanType: &BTypeBasic{tag: model.TypeTags_BOOLEAN, flags: Flags_READONLY},
 		intType:     &BTypeBasic{tag: model.TypeTags_INT, flags: Flags_READONLY},
+		byteType:    &BTypeBasic{tag: model.TypeTags_BYTE, flags: Flags_READONLY},
 		nilType:     &BTypeBasic{tag: model.TypeTags_NIL, flags: Flags_READONLY},
 		stringType:  &BTypeBasic{tag: model.TypeTags_STRING, flags: Flags_READONLY},
 		floatType:   &BTypeBasic{tag: model.TypeTags_FLOAT, flags: Flags_READONLY},
 		decimalType: &BTypeBasic{tag: model.TypeTags_DECIMAL, flags: Flags_READONLY},
+		byteArrayType: &BTypeBasic{tag: model.TypeTags_BYTE_ARRAY, flags: Flags_READONLY},
 	}
 }
 
 func (t *typeTable) getTypeFromTag(tag model.TypeTags) model.TypeDescriptor {
 	switch tag {
 	case model.TypeTags_BOOLEAN:
 		return t.booleanType
 	case model.TypeTags_INT:
 		return t.intType
+	case model.TypeTags_BYTE:
+		return t.byteType
 	case model.TypeTags_NIL:
 		return t.nilType
 	case model.TypeTags_STRING:
 		return t.stringType
 	case model.TypeTags_FLOAT:
 		return t.floatType
 	case model.TypeTags_DECIMAL:
 		return t.decimalType
+	case model.TypeTags_BYTE_ARRAY:
+		return t.byteArrayType
 	default:
 		panic("not implemented")
 	}
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ast/node_builder.go` around lines 34 - 69, The typeTable currently lacks
entries for BYTE and BYTE_ARRAY which makes createSimpleLiteralInner panics when
it sets typeTag to TypeTags_BYTE or TypeTags_BYTE_ARRAY; add two fields (e.g.,
byteType *BTypeBasic and byteArrayType *BTypeBasic) to the typeTable struct,
initialize them in newTypeTable with tag: model.TypeTags_BYTE and
model.TypeTags_BYTE_ARRAY (flags: Flags_READONLY), and extend getTypeFromTag to
return t.byteType for model.TypeTags_BYTE and t.byteArrayType for
model.TypeTags_BYTE_ARRAY instead of falling through to panic.
ast/expressions.go (1)

185-412: ⚠️ Potential issue | 🟠 Major

Add SetValueType calls for literal constructions in desugar/statement.go.

Found uninitialized valueType in literal constructions at desugar/statement.go:260 (oneLiteral) and desugar/statement.go:340 (zeroLiteral). Both create BLangNumericLiteral instances but only call SetDeterminedType(), leaving valueType as nil. This creates gaps where GetValueType() will return nil, potentially causing type information loss.

Literals in ast/node_builder.go are properly covered via a switch statement (lines 1131–1133) that calls SetValueType on all literal types.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ast/expressions.go` around lines 185 - 412, The BLangNumericLiteral instances
created in oneLiteral and zeroLiteral are missing a SetValueType call, leaving
valueType nil; after you call SetDeterminedType (or determine the BType used
there) on the BLangNumericLiteral, also invoke SetValueType with the same BType
(e.g., for the BLangNumericLiteral variable created in oneLiteral and
zeroLiteral call lit.SetValueType(determinedType) or lit.SetValueType(bt)
immediately after SetDeterminedType) so GetValueType() will return the correct
BType.
🧹 Nitpick comments (2)
semantics/type_resolver.go (2)

1040-1041: Same implicit type cast as in resolveSimpleVariable.

Apply the same explicit cast pattern here for consistency:

Suggested change
 	if typeNode := constant.TypeNode(); typeNode != nil {
-		expectedType = t.resolveBType(typeNode, 0)
+		expectedType = t.resolveBType(typeNode.(ast.BType), 0)
 	} else {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@semantics/type_resolver.go` around lines 1040 - 1041, The code in resolve of
constant.TypeNode() uses an implicit assignment to expectedType via
t.resolveBType(typeNode, 0); mirror the explicit cast pattern used in
resolveSimpleVariable by explicitly casting the returned value to the expected
BType type (or the concrete type used elsewhere) before assigning to
expectedType; update the line using resolveBType in the same function (reference
constant.TypeNode(), resolveBType) to perform the explicit cast so the types are
consistent with resolveSimpleVariable.

208-213: Fallback to NEVER may mask missing handler cases.

Setting DeterminedType to NEVER as a blanket fallback ensures all visited nodes have a type, but it could silently hide cases where a specific node type should have been handled in the switch but wasn't. Consider whether logging or tracking unhandled node types during development would help catch missing cases.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@semantics/type_resolver.go` around lines 208 - 213, The blanket fallback that
sets node.SetDeterminedType(&semtypes.NEVER) when node.GetDeterminedType() ==
nil can mask missing switch/case handling; change this to record or surface
unhandled node kinds before assigning NEVER: detect the node kind (e.g., via
node.GetKind()/node.Type() or similar), emit a development-level warning or
append the kind to an unhandledNodes tracker (or trigger a panic/assert in dev
builds), and then set the fallback to semtypes.NEVER; ensure references to
node.GetDeterminedType, node.SetDeterminedType and semtypes.NEVER are used so
you only alter the fallback path and add logging/tracking without changing
existing typing logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@ast/expressions.go`:
- Around line 185-412: The BLangNumericLiteral instances created in oneLiteral
and zeroLiteral are missing a SetValueType call, leaving valueType nil; after
you call SetDeterminedType (or determine the BType used there) on the
BLangNumericLiteral, also invoke SetValueType with the same BType (e.g., for the
BLangNumericLiteral variable created in oneLiteral and zeroLiteral call
lit.SetValueType(determinedType) or lit.SetValueType(bt) immediately after
SetDeterminedType) so GetValueType() will return the correct BType.

In `@ast/node_builder.go`:
- Around line 34-69: The typeTable currently lacks entries for BYTE and
BYTE_ARRAY which makes createSimpleLiteralInner panics when it sets typeTag to
TypeTags_BYTE or TypeTags_BYTE_ARRAY; add two fields (e.g., byteType *BTypeBasic
and byteArrayType *BTypeBasic) to the typeTable struct, initialize them in
newTypeTable with tag: model.TypeTags_BYTE and model.TypeTags_BYTE_ARRAY (flags:
Flags_READONLY), and extend getTypeFromTag to return t.byteType for
model.TypeTags_BYTE and t.byteArrayType for model.TypeTags_BYTE_ARRAY instead of
falling through to panic.

---

Duplicate comments:
In `@ast/ast.go`:
- Around line 408-413: BLangVariableBase currently stores typeNode as BType
which leads to unsafe casts to BLangNode later; change the field to a concrete
AST node type (e.g., rename and type it as BLangNode or a dedicated interface
like BTypeNode that embeds both BType and BLangNode) so callers don't need to
cast. Update all places that set or read BLangVariableBase.typeNode (and any
constructors/factory functions) to assign and consume the new BLangNode-typed
field, and remove unsafe type assertions that cast BType->BLangNode; ensure
model.AnnotationAttachmentNode usage (AnnAttachments) is unchanged.

In `@ast/node_builder.go`:
- Around line 1473-1499: The code unsafely asserts
createTypeNode(typeDesc).(BType) which can panic if createTypeNode returns nil
or a different type; update the block around
variable.(*BLangSimpleVariable).SetTypeNode to call n.createTypeNode(typeDesc),
check the result is non-nil and of type BType (or handle non-BType
appropriately), and only then call SetTypeNode; reference the createTypeNode
function, the typeDesc variable, the isDeclaredWithVar check, and the
variable.(*BLangSimpleVariable).SetTypeNode call so you locate and replace the
unchecked assertion with a safe type check and appropriate error handling or
fallback.
- Around line 1841-1861: The code is unsafely asserting
n.createTypeNode(typeDescriptor).(BType) which can panic if createTypeNode
returns nil or a non-BType; replace the direct assertion in the constant
handling block by capturing the returned value, checking for nil and a
successful type assertion (e.g. v, ok := n.createTypeNode(typeDescriptor); if ok
{ constantNode.SetTypeNode(v.(BType)) } ), and handle the non-BType case
gracefully (skip setting the type or log/error as appropriate) so SetTypeNode is
only called with a valid BType; reference symbols: createTypeNode,
TypeDescriptor, constantDeclarationNode, constantNode.SetTypeNode, BType.
- Around line 1058-1134: The code can panic when encountering BYTE or BYTE_ARRAY
literals because typeTag isn't set to model.TypeTags_BYTE or
model.TypeTags_BYTE_ARRAY (or getTypeFromTag can't handle them); update the
literal handling in the function that builds literals so it explicitly sets
typeTag = model.TypeTags_BYTE for byte literals and typeTag =
model.TypeTags_BYTE_ARRAY for byte-array/binary literals (the branch handling
common.BINARY_EXPRESSION and common.BYTE_ARRAY_LITERAL) and ensure the retrieved
BType from n.types.getTypeFromTag(typeTag) is valid (add a nil-check or
fallback) before calling bType.bTypeSetTag and bl.SetValueType; reference
getTypeFromTag, the BType variable bType, the bLiteral branches (BLangLiteral /
BLangNumericLiteral), and isNumericLiteral when making these changes.

In `@ast/pretty_printer.go`:
- Around line 406-415: printSimpleVariable currently calls node.TypeNode() and
directly casts it to BLangNode which can panic if TypeNode() is nil or not a
BLangNode; update printSimpleVariable to first retrieve tn := node.TypeNode(),
check tn != nil, then use a safe type assertion (bn, ok := tn.(BLangNode))
before calling p.PrintInner(bn) and only call p.PrintInner when ok is true,
ensuring you also preserve the existing indentation and closing printSticky(")")
behavior; reference: function printSimpleVariable, method TypeNode(), type
BLangNode, and method PrintInner.
- Around line 580-589: The code in printConstant uses an unchecked cast
node.TypeNode().(BLangNode) which can panic; change it to perform a safe type
assertion (e.g. tnode, ok := node.TypeNode().(BLangNode)) and only call
p.PrintInner(tnode) when ok, otherwise handle the non-BLangNode case via a safe
fallback (e.g. call a generic printer method or print a placeholder) so the
function never panics; also ensure p.indentLevel is incremented/decremented in
all branches to keep indentation balanced.

---

Nitpick comments:
In `@semantics/type_resolver.go`:
- Around line 1040-1041: The code in resolve of constant.TypeNode() uses an
implicit assignment to expectedType via t.resolveBType(typeNode, 0); mirror the
explicit cast pattern used in resolveSimpleVariable by explicitly casting the
returned value to the expected BType type (or the concrete type used elsewhere)
before assigning to expectedType; update the line using resolveBType in the same
function (reference constant.TypeNode(), resolveBType) to perform the explicit
cast so the types are consistent with resolveSimpleVariable.
- Around line 208-213: The blanket fallback that sets
node.SetDeterminedType(&semtypes.NEVER) when node.GetDeterminedType() == nil can
mask missing switch/case handling; change this to record or surface unhandled
node kinds before assigning NEVER: detect the node kind (e.g., via
node.GetKind()/node.Type() or similar), emit a development-level warning or
append the kind to an unhandledNodes tracker (or trigger a panic/assert in dev
builds), and then set the fallback to semtypes.NEVER; ensure references to
node.GetDeterminedType, node.SetDeterminedType and semtypes.NEVER are used so
you only alter the fallback path and add logging/tracking without changing
existing typing logic.

Copy link
Contributor

@warunalakshitha warunalakshitha left a comment

Choose a reason for hiding this comment

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

LGTM

@warunalakshitha warunalakshitha merged commit 248d5c6 into ballerina-platform:main Feb 24, 2026
5 of 6 checks passed
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