Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(gnovm): sync code AssignStmt - ValueDecl #3017

Open
wants to merge 24 commits into
base: master
Choose a base branch
from

Conversation

hthieu1110
Copy link
Contributor

@hthieu1110 hthieu1110 commented Oct 24, 2024

This PR aims at fixing this issue 1958

Contributors' checklist...
  • Added new tests, or not needed, or not feasible
  • Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory
  • Updated the official documentation or not needed
  • No breaking changes were made, or a BREAKING CHANGE: xxx message was included in the description
  • Added references to related issues and PRs
  • Provided any useful hints for running manual tests

@github-actions github-actions bot added the 📦 🤖 gnovm Issues or PRs gnovm related label Oct 24, 2024
Copy link

codecov bot commented Oct 24, 2024

Codecov Report

Attention: Patch coverage is 95.27559% with 6 lines in your changes missing coverage. Please review.

Project coverage is 63.32%. Comparing base (367408a) to head (daf9766).

Files with missing lines Patch % Lines
gnovm/pkg/gnolang/preprocess.go 95.27% 4 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3017      +/-   ##
==========================================
- Coverage   63.33%   63.32%   -0.01%     
==========================================
  Files         548      548              
  Lines       78601    78559      -42     
==========================================
- Hits        49780    49751      -29     
+ Misses      25466    25454      -12     
+ Partials     3355     3354       -1     
Flag Coverage Δ
contribs/gnodev 61.11% <ø> (ø)
contribs/gnofaucet 15.77% <ø> (+0.94%) ⬆️
gno.land 67.37% <ø> (ø)
misc/genstd 79.72% <ø> (ø)
tm2 62.39% <ø> (+0.08%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

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

@hthieu1110 hthieu1110 changed the title Feat/sync assignstmt valuedecl 1958 feat(gnovm) sync assignstmt - valuedecl Oct 25, 2024
@hthieu1110 hthieu1110 changed the title feat(gnovm) sync assignstmt - valuedecl feat(gnovm): sync assignstmt - valuedecl Oct 25, 2024
@hthieu1110 hthieu1110 changed the title feat(gnovm): sync assignstmt - valuedecl feat(gnovm): sync AssignStmt - ValueDecl Oct 25, 2024
@hthieu1110 hthieu1110 changed the title feat(gnovm): sync AssignStmt - ValueDecl feat(gnovm): sync code AssignStmt - ValueDecl Oct 25, 2024
Copy link
Contributor

@MikaelVallenet MikaelVallenet left a comment

Choose a reason for hiding this comment

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

Looks good to me 🔥

gnovm/pkg/gnolang/preprocess.go Outdated Show resolved Hide resolved
hthieu1110 and others added 2 commits October 26, 2024 08:10
Co-authored-by: Mikael VALLENET <mikael.vallenetpro@gmail.com>
nx.Path = last.GetPathForName(nil, nx.Name)
}
}
if len(n.Values) != 1 && len(n.Values) != 0 && len(n.NameExprs) != len(n.Values) {
Copy link
Member

@omarsy omarsy Oct 29, 2024

Choose a reason for hiding this comment

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

why this len(n.Values) != 1 && len(n.Values) != 0 ?
I think this will not handle this case:

package main

var a, b = 1

func main() {
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Originally, there were 3 cases:

if numNames > 1 && len(n.Values) == 1 {
...
} else if len(n.Values) != 0 && numNames != len(n.Values) { 
...
} else {
...
}

To be able to refactor the code, I've moved this check first then 2 others. So I've added the condition but it looks strange like that, I've pushed the change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@omarsy I've checked, actually the errors for var a, b = 1 vs a, b := 1 are identical with Golang

Copy link
Member

Choose a reason for hiding this comment

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

Yes don't know why but I cannot resolve the comment :/

@hthieu1110 hthieu1110 marked this pull request as ready for review November 1, 2024 01:34
@jefft0 jefft0 added the review/triage-pending PRs opened by external contributors that are waiting for the 1st review label Nov 5, 2024
Copy link
Contributor

@mvertes mvertes left a comment

Choose a reason for hiding this comment

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

Overall, this refactoring is on the good track, and I agree with the general direction. Nice work.

In addition to the remarks in the code, could you please add a few more tests to cover some corner cases such as:

Mixing single and multiple return expression in the same assignment:

func f() (a, b int) {return 1, 2}
var x, y, z = 1, f()

Or covering slices, arrays, type conversions, etc.

Thanks

// - `a, b, c T := f()`
// - `a, b := n.(T)`
// - `a, b := n[i], where n is a map`
func specialParseTypeVals(
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
func specialParseTypeVals(
func parseMultipleAssignFromOneExp(

specialParseTypeVals is unclear. Please use a descriptive function name as suggested.

Also, for the function comment, please follow Go conventions to describe the function:

// parseMultimpleAssignFromOneExp parses assignment to multiple variables from a single expression, etc...

Copy link
Contributor Author

@hthieu1110 hthieu1110 Nov 6, 2024

Choose a reason for hiding this comment

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

I've updated the function name + comment

// - `var a, b = n.(T)`
// - `var a, b = n[i], where n is a map`
// Assign
// - `a, b, c T := f()`
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// - `a, b, c T := f()`
// - `a, b, c := f()`

Type name makes no sense in short declarations.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've updated :)

// var a, b, c T = f()
// a, b, c := f()
valueType := evalStaticTypeOfRaw(store, bn, valueExpr)
tuple = valueType.(*tupleType)
Copy link
Contributor

Choose a reason for hiding this comment

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

Should not you check this type assertion? Are you sure that valueType is always a tuple?

Also keep in mind that CallExpr may also refer to a type conversion, not only a function call: var a = int8(b), and that should be covered (maybe not here).

Copy link
Contributor Author

@hthieu1110 hthieu1110 Nov 6, 2024

Choose a reason for hiding this comment

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

According to the doc of evalStaticTypeOfRaw: like evalStaticTypeOf() but returns the raw *tupleType for *CallExpr., so I think we can expect a raw tuple here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The case var a = int8(b) is not handled here because we process only multi assignments from 1 expression

tuple = &tupleType{Elts: []Type{tt, BoolType}}
expr.HasOK = true
case *IndexExpr:
// Map index case:
Copy link
Contributor

Choose a reason for hiding this comment

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

IndexExpr may refer either to a slice, an array or a map. Please make sure you handle also slice and array types here. I understand it was not covered prior to your change (so it's not your fault :), but I see no reason not to do the job here also for slices/arrays.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The scope of this function handles only multi assignments from 1 expression, so arrays/slides index is not consider as this case, there is already a check to ensure that we process only map

mt, ok := baseOf(dt).(*MapType)
if !ok {
    panic(fmt.Sprintf("invalid index expression on %T", dt))
}


for i := 0; i < numNames; i++ {
if st != nil {
// TODO check tt and nt compat.
Copy link
Contributor

Choose a reason for hiding this comment

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

Please, perform the required type check, as it is important to catch types mismatch as early as possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added the compat check :)


// This func aims at syncing logic between op define (:=) and declare(var/const)
// for general cases (not handled by specialParseTypeVals)
func generalParseTypeVals(
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
func generalParseTypeVals(
func parseAssignFromExprList(

generalParseTypeVals is unclear. Please name function with more descriptive names. Also please fix function comment to better follow Go conventions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've updated the name + comment :)

) {
numNames := len(nameExprs)

// ensure that function only return 1 value
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// ensure that function only return 1 value
// Ensure that function only return 1 value.

Comment lines should follow normal sentence rules (1st letter capital, punctuation, ...).

}
}

// evaluate types and convert consts.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// evaluate types and convert consts.
// Evaluate types and convert consts.

for i := 0; i < numNames; i++ {
sts[i] = nt
}
// convert if const to nt.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// convert if const to nt.
// Convert if const to nt.

checkOrConvertType(store, bn, &valueExprs[i], nt, false)
}
} else if isConst {
// derive static type from values.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// derive static type from values.
// Derive static type from values.

@hthieu1110
Copy link
Contributor Author

thanks @mvertes for your time and your reviews , I've addressed all your feedbacks. Please re-check the PR, please. Thanksssss.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
📦 🤖 gnovm Issues or PRs gnovm related review/triage-pending PRs opened by external contributors that are waiting for the 1st review
Projects
Status: In Progress
Status: In Review
Development

Successfully merging this pull request may close these issues.

5 participants