Skip to content

Add scala.Dynamic support. #1291

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 3 commits into from
Jul 15, 2016

Conversation

nicolasstucki
Copy link
Contributor

@nicolasstucki nicolasstucki commented Jun 1, 2016

No description provided.

@nicolasstucki
Copy link
Contributor Author

Still need to add some tests and write some comments.

case Apply(Select(qual, name), args) if !isDynamicMethod(name) =>
if (untpd.isWildcardStarArgList(args)) {
ctx.error(name.toString + " does not support passing a vararg parameter", tree.pos)
tree.withType(ErrorType)
Copy link
Member

Choose a reason for hiding this comment

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

Is there any reason to "preserve" that limitation?

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 current implementation does what the scalac implementation does. Im not sure why the restriction was there in the first place. It could be just because it is harder to handle with applyDynamicNamed.

@nicolasstucki
Copy link
Contributor Author

All dynamic method (like selectDynamic(name: String)) receive as first parameter the name of the method. Currently it would be possible to define it as selectDynamic(name: Int) which will always generate an error at call site. I'm considering adding a new check that forces that first type to be a String at the declaration site and generates an error there (could also be a warning). Is anyone against adding that new restriction for some reason?

@sjrd
Copy link
Member

sjrd commented Jun 2, 2016

Yes, I'm against forcing String. You could have an implicit conversion from String to T that should kick in at that point. Scalac sort of supports that, although it's buggy for updateDynamic.

Speaking of which, it would be good to test that implicit conversions can be applied to the arguments at least. js.Dynamic is full of that requirement.

@felixmulder
Copy link
Contributor

felixmulder commented Jun 2, 2016

This PR should solve #657 when merged

@@ -1,3 +1,4 @@
import dotty.language.dynamics
Copy link
Member

Choose a reason for hiding this comment

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

Unless this works very differently from dynamic in scalac, I think we should use import scala.language.dynamics for compatibility

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 agree.

@nicolasstucki nicolasstucki force-pushed the implement-scala-dynamic branch 2 times, most recently from b4b9b4d to 3d458cf Compare June 3, 2016 15:23
@nicolasstucki nicolasstucki changed the title [WIP] Add scala.Dynamic support. Add scala.Dynamic support. Jun 3, 2016
@nicolasstucki nicolasstucki force-pushed the implement-scala-dynamic branch from 3d458cf to c946f73 Compare June 3, 2016 16:06
}

object DynamicTest {
def test: String = new Foo().bazApply("1" -> 2) // error // error
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note to self: remove one of the // errors

@nicolasstucki nicolasstucki force-pushed the implement-scala-dynamic branch from c946f73 to 7c39491 Compare June 6, 2016 07:34
@nicolasstucki nicolasstucki force-pushed the implement-scala-dynamic branch 9 times, most recently from ec7eeca to bf761be Compare June 6, 2016 14:52
@nicolasstucki nicolasstucki removed their assignment Jun 8, 2016
abstract class TryDynamicCallType extends UncachedGroundType with ValueType

object TryDynamicCallType extends TryDynamicCallType

Copy link
Contributor

Choose a reason for hiding this comment

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

What happens if we try to map or fold over such a type? Did we think of that?

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 idea is that it behaves like ErrorType on any operation until it is caught and handled. I considered making it a subtype of ErrorType but this seamed a bit dangerous and with this alternative there was only one place where I had to add it to a case to do the same as ErrorType.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually, now that I think about it, it should be object TryDynamicCallType extends ErrorType.

@nicolasstucki nicolasstucki force-pushed the implement-scala-dynamic branch 2 times, most recently from 69c996e to 5efd398 Compare June 9, 2016 12:33
@@ -206,6 +230,10 @@ abstract class Reporter extends interfaces.ReporterResult {
*/
def errorsReported = hasErrors

private[this] var reportedFeaturesUseSites = Set[Symbol]()
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be good to have a motivation why this is needed. In fact I am not yet sure we want to suppress feature warnings per use site.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Currently it does not suppress the warning. It is only there to make sure the explanation of how to avoid it is only printed once per site.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, OK, I had missed that.

@nicolasstucki nicolasstucki force-pushed the implement-scala-dynamic branch from 5efd398 to aebb5dc Compare July 1, 2016 12:18
extends UncachedGroundType with AssigningProto {
override def resultType(implicit ctx: Context) = rhsType

def isMatchedBy(tp: Type)(implicit ctx: Context) = ???
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@odersky, i'm not sure what to return AssignProto. isMatchedBy.

@nicolasstucki nicolasstucki force-pushed the implement-scala-dynamic branch from aebb5dc to cab2598 Compare July 5, 2016 11:40
@@ -196,11 +196,16 @@ trait TypeAssigner {
def selectionType(site: Type, name: Name, pos: Position)(implicit ctx: Context): Type = {
val mbr = site.member(name)
if (reallyExists(mbr)) site.select(name, mbr)
else {
else if (site <:< defn.DynamicType && !Dynamic.isDynamicMethod(name)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Cheaper test is: site.derivesFrom(defn.DynamicClass)

@nicolasstucki nicolasstucki force-pushed the implement-scala-dynamic branch from cab2598 to 7e00c72 Compare July 7, 2016 09:17
@nicolasstucki
Copy link
Contributor Author

Updated

@odersky
Copy link
Contributor

odersky commented Jul 7, 2016

LGTM, thanks!

@DarkDimius DarkDimius merged commit f37e45a into scala:master Jul 15, 2016
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.

7 participants