-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Add scala.Dynamic support. #1291
Conversation
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) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
.
All dynamic method (like |
Yes, I'm against forcing Speaking of which, it would be good to test that implicit conversions can be applied to the arguments at least. |
This PR should solve #657 when merged |
e4f7c47
to
dfe79b6
Compare
dfe79b6
to
0920fed
Compare
@@ -1,3 +1,4 @@ | |||
import dotty.language.dynamics |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree.
b4b9b4d
to
3d458cf
Compare
3d458cf
to
c946f73
Compare
} | ||
|
||
object DynamicTest { | ||
def test: String = new Foo().bazApply("1" -> 2) // error // error |
There was a problem hiding this comment.
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 // error
s
c946f73
to
7c39491
Compare
ec7eeca
to
bf761be
Compare
abstract class TryDynamicCallType extends UncachedGroundType with ValueType | ||
|
||
object TryDynamicCallType extends TryDynamicCallType | ||
|
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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
.
69c996e
to
5efd398
Compare
@@ -206,6 +230,10 @@ abstract class Reporter extends interfaces.ReporterResult { | |||
*/ | |||
def errorsReported = hasErrors | |||
|
|||
private[this] var reportedFeaturesUseSites = Set[Symbol]() |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
5efd398
to
aebb5dc
Compare
extends UncachedGroundType with AssigningProto { | ||
override def resultType(implicit ctx: Context) = rhsType | ||
|
||
def isMatchedBy(tp: Type)(implicit ctx: Context) = ??? |
There was a problem hiding this comment.
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
.
aebb5dc
to
cab2598
Compare
@@ -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)) { |
There was a problem hiding this comment.
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)
cab2598
to
7e00c72
Compare
Updated |
LGTM, thanks! |
No description provided.