Skip to content

Allow macros to generate method symbols, add missing method type constructors #8090

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

Merged
merged 1 commit into from
Jan 28, 2020

Conversation

fhackett
Copy link
Contributor

Partially addressing #6280, and the issue underlying #7626. Review by @nicolasstucki.

Since there already exists the machinery to generate a new tree for an existing method symbol, this change simply adds the ability to generate a fresh method symbol with the given name, type and flags. Then, DefDef.apply can be used to generate the full tree.

Missing type constructors for PolyType and ByNameType are added, as well as corresponding .param(Int) accessors in order to make references to a MethodType or a PolyType's parameter types.

Testing is achieved by synthesizing a series of method definitions, along with references to these methods and some basic correctness assertions. The purpose of each test is described in a comment above the corresponding block of code.

Note 1: there are optional parameters for flags and private in the Symbol.newMethod function. These seem unnecessary for just defining local functions, but may be useful in synthesizing more complex declarations that may be supported later, such as local classes.

Note 2: implicit/given method types are not exposed by this change. Since these types are structurally identical to normal method types, perhaps some optional flags could be added to the MethodType constructor for this purpose?

Copy link
Member

@dottybot dottybot left a comment

Choose a reason for hiding this comment

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

Hello, and thank you for opening this PR! 🎉

All contributors have signed the CLA, thank you! ❤️

Have an awesome day! ☀️

@fhackett fhackett closed this Jan 25, 2020
@fhackett fhackett deleted the fhackett-synth-defdef branch January 25, 2020 01:41
@fhackett fhackett restored the fhackett-synth-defdef branch January 25, 2020 01:41
@fhackett
Copy link
Contributor Author

sorry, git accident

@fhackett fhackett reopened this Jan 25, 2020
@nicolasstucki nicolasstucki self-requested a review January 25, 2020 08:21
@nicolasstucki nicolasstucki self-assigned this Jan 25, 2020
Copy link
Contributor

@nicolasstucki nicolasstucki left a comment

Choose a reason for hiding this comment

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

Otherwise LGTM

*
* @note As a macro can only splice code into the point at which it is expanded, all generated symbols must be
* direct or indirect children of the reflection context's owner. */
def newMethod(parent: Symbol, name: String, tpe: Type, flags: Flags = Flags.EmptyFlags, privateWithin: Option[Symbol] = None)(given ctx: Context): Symbol =
Copy link
Contributor

Choose a reason for hiding this comment

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

We are trying to avoid default parameters for compatibility reasons. Remove them and maybe add an overloaded version without the last two.

    /** ... */
    def newMethod(parent: Symbol, name: String, tpe: Type)(given ctx: Context): Symbol =
      newMethod(parent, name, tpe, Flags.EmptyFlags, None)

    /** ... */
    def newMethod(parent: Symbol, name: String, tpe: Type, flags: Flags, privateWithin: Option[Symbol])(given ctx: Context): Symbol =

…tructors

Since there already exists the machinery to generate a new tree for an existing method symbol, this change simply adds the
ability to generate a fresh method symbol with the given name, type and flags. Then, `DefDef.apply` can be used to generate
the full tree.

Missing type constructors for `PolyType` and `ByNameType` are added, as well as corresponding `.param(Int)` accessors in
order to make references to a `MethodType` or a `PolyType`'s parameter types.

Testing is achieved by synthesizing a series of method definitions, along with references to these methods and some basic
correctness assertions. The purpose of each test is described in a comment above the corresponding block of code.

Note 1: it is possible to additionaly specify flags and private in the `Symbol.newMethod` function. These seem unnecessary
for just defining local functions, but may be useful in synthesizing more complex declarations that may be supported later,
such as local classes.

Note 2: implicit/given method types are not exposed by this change. Since these types are structurally identical to normal
method types, perhaps some optional flags could be added to the MethodType constructor for this purpose?
@fhackett fhackett force-pushed the fhackett-synth-defdef branch from 97945bc to 5ff0325 Compare January 27, 2020 23:32
@nicolasstucki nicolasstucki merged commit 654f303 into scala:master Jan 28, 2020
@nicolasstucki
Copy link
Contributor

Thank you @fhackett

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.

3 participants