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

Support multiple return values #1089

Open
4 of 5 tasks
maximiliankaul opened this issue Feb 8, 2023 · 6 comments
Open
4 of 5 tasks

Support multiple return values #1089

maximiliankaul opened this issue Feb 8, 2023 · 6 comments
Assignees
Labels
core enhancement New feature or request epic graph-changing This change breaks the current graph structure, i.e. it changes semantic of properties and edges

Comments

@maximiliankaul
Copy link
Contributor

maximiliankaul commented Feb 8, 2023

The CPG should support multiple return values per statement. This is useful for language constructs like a, b = (1, 2) or value, error := someFunction().
Note, that such constructs can also happen in unexpected places like loops for a, b, c in ... where we would have three loop variables in this example.

Tasks

Preview Give feedback
  1. 7 of 7
    epic
  2. python
    maximiliankaul
@maximiliankaul maximiliankaul added enhancement New feature or request graph-changing This change breaks the current graph structure, i.e. it changes semantic of properties and edges core labels Feb 8, 2023
@KuechA
Copy link
Contributor

KuechA commented Feb 23, 2023

The expressions supporting multiple values will model the targets with lists.

Tasks:

  • Replace the = Binary Operator with a dedicated AssignmentExpression class.
  • Adapt the variable in the ForEachStatement.
  • The support for multiple return types/values of functions has to be expanded (see TODOs in code)

Tricky problems:

  • (1) a, b = foo(): The function call should be modeled only once and magically be "expanded"
  • (2) int i, a, b = 1;: Not all declared variables are initialized
  • (3) Various ways to initialize a variable in C++ should be represented in the same way. The different options should probably be kept in some properties.
  • (4) Mixture of DeclaredReferenceExpressions and VariableDeclarations (e.g. a is an already defined variable and used in a, b = 1,2): This probably needs handling refs and decls at the same time
  • (5) It should be easy to identify uninitialized variables (= write a query)

Discussed solutions:

  1. Split multiple assignments into multiple nodes. Problems: 1
  2. Assignment statement with lists for lhs, rhs, declarations. Problems: 1, 2 (keeping the lists synchronized). Needs to change the VariableDeclaration to get rid of the initializer

@peckto
Copy link
Collaborator

peckto commented Feb 23, 2023

If we treat multiple return values as a container, we could add an implicit "unpack" node in situations where the return values are unpacked to separate values.
The "unpack" functionality is probably language specific and could be implemented in separate pass.

@oxisto
Copy link
Member

oxisto commented Feb 24, 2023

After some more internal discussion, we arrived at the following proposal:

We introduce a new AssignStatement (or does it have to be an expression?), which has a list of rhs and lhs. This should allow the assignment of multiple return values of a function into multiple references, such as:

i, err = func()

.We remove the initializer from the VariableDeclaration and model a possible assignment as an implicit AssignStatement. Language frontends need to take care of this.

var i = 1

effectively will be modelled as

var i int
i = 1

If a language supports mixed assignment and declarations (e.g. Go in the following snippet), we extract all possible declarations out of the assignment and model them as implicit VariableDeclaration/ DeclarationStatement nodes.

// This declares i, but assigns err
var err error
i, err := ret()

which is then equivalent to

var err error
var i any
i, err = ret()

@oxisto
Copy link
Member

oxisto commented Sep 25, 2024

@maximiliankaul Is this issue still relevant? I think we implemented this in python using our assign expression? Or at least it should be done once #1729 is merged.

@maximiliankaul
Copy link
Contributor Author

@maximiliankaul Is this issue still relevant? I think we implemented this in python using our assign expression? Or at least it should be done once #1729 is merged.

I think it's no longer relevant. I'll double check that we have tests for all the corner cases discussed above and then close this issue asap.

@maximiliankaul maximiliankaul self-assigned this Sep 25, 2024
@maximiliankaul
Copy link
Contributor Author

There are still some bugs. See #1807 for fixes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core enhancement New feature or request epic graph-changing This change breaks the current graph structure, i.e. it changes semantic of properties and edges
Projects
None yet
Development

No branches or pull requests

4 participants