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

Optimise materialised code + allow = ??? and accessor methods #87

Merged
merged 9 commits into from
May 22, 2020

Conversation

marcgrue
Copy link
Contributor

@marcgrue marcgrue commented May 19, 2020

Sorry for the large code base to review! I saw that @mathieuleclaire also just made the tests pass.

This pull request consists of basically 5 parts:

  • Allowing undefined implementations = ??? (commit)
  • Allowing accessor methods (commit)
  • Cutting materialised code in half by only materialising one distinct method name from interface/implementation (commit)
  • Eliminating deprecated code
  • Cosmetic: adding return types + various cleanups (non-essential and subject to style preferences)

Allowing a shared interface to define methods with an undefined implementation (def someMethod() = ???) allows client code to extend such interfaces without having to implement the methods or being abstract itself.

Allowing accessor methods solves #36

(embarrassing fact: this is my first pull request - have been working solo on my own projects for years. So please let me know if I'm doing something wrong here)

member <- membersOfBaseAndParents
if !isAMemberOfAnyRef(member)
if !member.isSynthetic
if member.isPublic
if member.isTerm
if member.isAbstract
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Allows a method in the shared API to define a dummy implementation like

def someMethod() = ???

This allow client classes to extend the shared api without themselves having to implement the interface methods or being abstract classes themselves.

Removing the isAbstract check reverses pull request #58. Would omitting the isAbstract check do any harm when using scalapb generated rpc's @nathanleyton?

}


class MacroHelp[C <: Context](val c: C) {
class MacroHelp[C <: blackbox.Context](val c: C) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Replacing deprecated Context with more specific blackbox.Context

if (member.returnType <:< c.typeOf[Future[_]]) t
else q"scala.concurrent.Future($t)"
}

def getValsOrMeths(curCls: Type): Iterable[Either[(c.Symbol, MethodSymbol), (c.Symbol, MethodSymbol)]] = {
def getValsOrMeths(curCls: Type): Iterable[Either[(Symbol, MethodSymbol), (Symbol, MethodSymbol)]] = {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

No need to prefix types with Context

memTerm = member.asTerm
if memTerm.isMethod
} yield {
member -> memTerm.asMethod
}

extractableMembers flatMap { case (member, memTerm) =>
extractableMembers.toList.distinct flatMap { case (member, memTerm) =>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

No need to materialise code from duplicate method names (one from api, one from implementation). This will cut materialised code almost in half.

"""
val futurized: Tree = if (params.isEmpty) {
// Accessor method
futurize(q"$memSel", meth)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Method invocation without parameter list allows for accessor methods.

If a method is defined with empty parenthesis def someMethod() it will be materialised as an accessor method def someMethod which seems to be fine (all tests pass with/without parenthesis).

(unwrapTree, methodName, args, Nil, Nil)
case t@q"..${statements: List[ValDef]@unchecked}; $thing.$call(..$args)"
case q"$unwrapTree.$methodName" =>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This allows calling the accessor method (without parenthesis).

case Error.InvalidInput(
Error.Param.Invalid("x", InvalidData(Arr(Seq()), _)),
Error.Param.Invalid("ys", InvalidData(Num(234), _))
Error.Param.Invalid("x", AbortException("expected number got sequence", _, _, _, _)),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Adding the error messages helps understand the problems.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I hadn't add Exception strings in tests, this is better this way

@mathieuleclaire
Copy link
Collaborator

mathieuleclaire commented May 19, 2020

Thanks Marc for this (huge first) PR. Indeed we solved test in the same time :). I tried tests with your PR, they all pass.

Do you have any idea on how fix the Case Class test (https://github.com/marcgrue/autowire/blob/master/autowire/shared/src/test/scala/autowire/UpickleTests.scala#L125) ?

@lihaoyi, do you have any comment on other items ?

@marcgrue
Copy link
Contributor Author

Thanks yourself, Mathieu, for putting time into Lihaoyi's excellent library!

I had a look at the Point case class test, yes, but I didn't manage to solve it, unfortunately. I suspect that the error:

Error:(19, 57) could not find implicit value for evidence parameter of type 
upickle.default.Reader[autowire.Point]
def routes: Bundle.Server.Router = Server.route[Api](Controller)

has something to do with upickle but I'm not sure :-(

@mathieuleclaire
Copy link
Collaborator

Yes definitely. I tried to implement something like this https://www.lihaoyi.com/upickle/#ManualSealedTraitPicklers, but It didn't work. I am now use Boopickle, so I do not really understand upickle nuances :) !

@mathieuleclaire mathieuleclaire merged commit fa1c5e2 into lihaoyi:master May 22, 2020
@marcgrue
Copy link
Contributor Author

I'm happy it worked. Thanks, Mathieu!

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