Skip to content

pkg.NewTuple#566

Merged
xushiwei merged 1 commit intogoplus:mainfrom
xushiwei:q
Jan 20, 2026
Merged

pkg.NewTuple#566
xushiwei merged 1 commit intogoplus:mainfrom
xushiwei:q

Conversation

@xushiwei
Copy link
Member

No description provided.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @xushiwei, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly extends the gogen package by introducing a robust mechanism for creating and managing tuple-like struct types. The core addition is the NewTuple function, which allows developers to define structs whose fields can be referenced both by their generated ordinal identifiers and, optionally, by their original, more descriptive names. This enhancement provides greater flexibility in code generation, particularly for scenarios requiring structured data with dynamic or multiple access patterns.

Highlights

  • NewTuple Function: Introduced pkg.NewTuple to create tuple-like struct types, allowing fields to be accessed by both ordinal names (e.g., _0, _1) and, optionally, by their original names.
  • Virtual Fields Mechanism: Implemented a 'virtual fields' system (vFieldsMgr, tupleFields) to map original field names to their corresponding ordinal fields within a tuple-like struct, enhancing field access flexibility.
  • CodeBuilder Integration: Integrated the virtual field resolution logic into the CodeBuilder's fieldRef and normalField methods, enabling the code generator to correctly handle references to these new tuple fields.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@codecov
Copy link

codecov bot commented Jan 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.07%. Comparing base (6bb8a50) to head (5bffc3a).
⚠️ Report is 7 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #566      +/-   ##
==========================================
+ Coverage   96.04%   96.07%   +0.02%     
==========================================
  Files          24       25       +1     
  Lines        6727     6778      +51     
==========================================
+ Hits         6461     6512      +51     
  Misses        198      198              
  Partials       68       68              

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

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a NewTuple function to create tuple-like struct types. It also adds a "virtual fields" mechanism to allow accessing the tuple elements by their original names, not just by their ordinal _i names. The implementation is clean and the accompanying test case verifies the functionality correctly. I've made a few suggestions in type_tuple.go to improve code clarity and extensibility, mainly around using an interface for virtual fields and cleaning up some commented-out code.

Comment on lines +24 to +32
/*
// vFields defines the interface for virtual fields of a struct type.
type vFields interface { // virtual fields
FindField(cb *CodeBuilder, t *types.Struct, name string, arg *Element, src ast.Node) bool
FieldRef(cb *CodeBuilder, t *types.Struct, name string, x ast.Expr, src ast.Node) bool
}
*/

type vFields = *tupleFields
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The vFields interface is commented out and a type alias is used instead. This limits the extensibility of the virtual fields mechanism. It's recommended to use the interface to allow for different kinds of virtual fields in the future. This would make the design more robust and open for extension.

// vFields defines the interface for virtual fields of a struct type.
type vFields interface { // virtual fields
	FindField(cb *CodeBuilder, t *types.Struct, name string, arg *Element, src ast.Node) bool
	FieldRef(cb *CodeBuilder, t *types.Struct, name string, x ast.Expr, src ast.Node) bool
}

Comment on lines +59 to +64
/*
func (p *Package) vFields(t *types.Struct) (vft vFields, ok bool) {
vft, ok = p.cb.vfts[t]
return
}
*/
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This commented-out vFields function appears to be dead code. It should be removed to keep the codebase clean.

fields []*types.Var
}

func (p *tupleFields) FindField(cb *CodeBuilder, t *types.Struct, name string, arg *Element, src ast.Node) bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The t parameter is unused in this function. It's good practice to rename it to _ to make it clear that it's intentionally not used.

func (p *tupleFields) FindField(cb *CodeBuilder, _ *types.Struct, name string, arg *Element, src ast.Node) bool {

return false
}

func (p *tupleFields) FieldRef(cb *CodeBuilder, t *types.Struct, name string, x ast.Expr, src ast.Node) bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The t parameter is unused in this function. It's good practice to rename it to _ to make it clear that it's intentionally not used.

func (p *tupleFields) FieldRef(cb *CodeBuilder, _ *types.Struct, name string, x ast.Expr, src ast.Node) bool {

}
}
if p.refVField(o, name, x, src) {
return true
Copy link
Contributor

Choose a reason for hiding this comment

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

Virtual field placement issue: Virtual fields are checked after direct fields but before embedded fields. This breaks Go's field resolution semantics where embedded fields are promoted to the same level as direct fields.

If a tuple with virtual field "x" embeds a struct that also has field "x", the virtual field will incorrectly shadow the embedded field.

Recommendation: Move this virtual field check to after embedded field recursion (after the loop at lines 1587-1599) to match Go's semantics.

for i, fld := range p.fields {
if fld.Name() == name {
cb.stk.Ret(1, &Element{
Val: selector(arg, tupleFieldName(i)),
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing nil safety check: The selector() function will panic if arg is nil. Consider adding a nil check:

if arg == nil {
    return false
}

This defensive check would prevent potential nil pointer dereferences.

return false
}

// NewTuple creates a tuple type with the given fields.
Copy link
Contributor

Choose a reason for hiding this comment

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

Documentation clarity: The Godoc should clarify that with withName=true, fields can be accessed by BOTH their original names (e.g., "x", "y") AND ordinal names ("_0", "_1"). The current comment doesn't make this dual-access capability clear.

Suggested addition:

// NewTuple creates a tuple type with the given fields.
// The fields are always accessible by ordinal names: _0, _1, ...
// If withName is true, the fields are ALSO accessible by their original names
// through a virtual fields mechanism.

// virtual fields mechanism.
func (p *Package) NewTuple(withName bool, fields ...*types.Var) *types.Struct {
ordinals := make([]*types.Var, len(fields))
for i, fld := range fields {
Copy link
Contributor

Choose a reason for hiding this comment

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

Input validation: Consider adding validation for nil fields to make debugging easier:

for i, fld := range fields {
    if fld == nil {
        panic("NewTuple: nil field at index " + strconv.Itoa(i))
    }
    // ...
}

Also consider documenting the behavior when multiple fields have the same name (first match wins).

@xgopilot
Copy link
Contributor

xgopilot bot commented Jan 20, 2026

Code Review Summary

This PR implements a clean virtual fields mechanism for tuple types. The implementation is well-structured with minimal invasiveness (only 3 integration points in codebuild.go). However, there's one important issue with field resolution order that should be addressed.

Key concerns:

  1. Virtual field placement (codebuild.go:1577): Breaks Go's embedded field semantics - should resolve after embedded fields
  2. Nil safety (type_tuple.go:76): Missing nil check before selector() call
  3. Documentation (type_tuple.go:106): Should clarify dual-access capability

Positive aspects: Clean separation of concerns, proper type checking, minimal memory overhead, good recorder integration.

@xushiwei xushiwei merged commit fa9e48f into goplus:main Jan 20, 2026
23 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.

1 participant