You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: sips/pending/_posts/2016-01-01-static-members.md
+75-22Lines changed: 75 additions & 22 deletions
Original file line number
Diff line number
Diff line change
@@ -4,68 +4,121 @@ title: SIP 25 - @static fields and methods in Scala objects(SI-4581)
4
4
disqus: true
5
5
---
6
6
7
-
__Dmitry Petrashko__
7
+
__Dmitry Petrashko and Sébastien Doeraene__
8
8
9
9
__first submitted TODO 2016__
10
10
11
11
## Motivation ##
12
12
13
-
We would like to allow methods and fields to be compiled as static. This is usable for interop with Java and other JVM languages and is convenient for optimizations.
13
+
We would like to allow methods and fields to be compiled as static. This is usable for interop with Java and other JVM languages, as well as with JavaScript, and is convenient for optimizations.
14
14
15
15
## Use Cases
16
16
17
-
Some JVM and JavaScript frameworks require classes to have specific static fields.
17
+
Some JVM and JavaScript frameworks require classes to have specific static fields and/or methods.
18
18
19
19
For example, classes extending `android.os.Parcelable` are required to have a static field named `CREATOR` of type `android.os.Parcelable$Creator`.
20
20
21
21
Another example is using an [`AtomicReferenceFieldUpdater`](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.html).
22
22
23
-
@sjrd could you please illustrate JS exaples?
23
+
On the JavaScript side, one example is [Relay Route Definitions](https://facebook.github.io/relay/docs/guides-routes.html), whose subclasses must define static fields such as `queries`.
24
+
Static methods and fields for JavaScript classes are one of the very few things (if not the only thing) that Scala.js "cannot do" at the moment, at least not declaratively.
25
+
26
+
## Overview ##
24
27
25
-
## Syntax ##
26
28
In order for method or field to be considered static it needs to be defined in an `object` and annotated `@static`.
27
29
There is no special syntax proposed to access these members, they are accessed as if they were a member of defining objects with all appropriate access requirements for accessing them.
28
30
31
+
For example:
32
+
33
+
{% highlight scala %}
34
+
class Foo
35
+
36
+
object Foo {
37
+
@static val x = 5
38
+
@static def bar(y: Int): Int = x + y
39
+
}
40
+
41
+
println(Foo.x)
42
+
println(Foo.bar(12))
43
+
{% endhighlight %}
44
+
45
+
Intuively, the presence of the `@static` annotation ensures that a field/method is declared as a static member of the companion class.
46
+
For the JVM, the above would therefore look to other Java code as if it had been declared with the following Java code:
47
+
48
+
{% highlight java %}
49
+
class Foo {
50
+
public static int x = 5;
51
+
public static int bar(int y) {
52
+
return x + y;
53
+
}
54
+
}
55
+
{% endhighlight %}
56
+
57
+
In Scala.js, the `@static` annotation has no semantic effect in Scala objects, as they are not visible from JavaScript anyway (it could be used for optimizations).
58
+
It has a semantic effect on Scala.js-defined JS classes, for example:
59
+
60
+
{% highlight scala %}
61
+
@ScalaJSDefined
62
+
class Foo extends js.Object
63
+
64
+
@ScalaJSDefined
65
+
object Foo extends js.Object {
66
+
@static val x = 5
67
+
@static def bar(y: Int): Int = x + y
68
+
}
69
+
{% endhighlight %}
70
+
71
+
would look to JavaScript code as if it had been declared with the following JavaScript code:
72
+
73
+
{% highlight javascript %}
74
+
class Foo extends Object {
75
+
static bar(y) {
76
+
return x + y;
77
+
}
78
+
}
79
+
Foo.x = 5; // in ES6, there is no declarative syntax for static fields yet
80
+
{% endhighlight %}
81
+
29
82
## Restrictions ##
30
83
31
84
The following rules ensure that method can be correctly compiled into static member on both JVM and JavaScript:
32
85
33
-
1. Only objects can have members annotated as`@static`
86
+
1. Only objects can have members annotated with`@static`
34
87
35
88
2. The fields annotated with `@static` should preceed any non-`@static` fields. This ensures that we do not introduce surprises for users in initialization order.
36
89
37
-
3. The right hand side of method or field annotated as`@static` can only refer to members of globally accessible objects and `@static` members. In particular, for non-static objects `this` is not accesable. `super` is never accessable.
90
+
3. The right hand side of a method or field annotated with`@static` can only refer to members of globally accessible objects and `@static` members. In particular, for non-static objects `this` is not accesible. `super` is never accessible.
38
91
39
-
4. If member `foo` of `object C` is annotated `@static`, companion class `C` is not allowed to define term members with name `foo`.
92
+
4. If a member `foo` of an `object C` is annotated with `@static`, the companion class `C` is not allowed to define term members with name `foo`.
40
93
41
-
5. If member `foo` of `object C` is annotated `@static`, companion class `C` is not allowed to inherit classes that define a term member with name `foo`..
94
+
5. If a member `foo` of an `object C` is annotated with `@static`, the companion class `C` is not allowed to inherit classes that define a term member with name `foo`.
42
95
43
-
6. Only @static methods and vals are suppoerted in companions of traits. Java8 supports those, but not vars.
96
+
6. Only @static methods and vals are supported in companions of traits. Java8 supports those, but not vars, and JavaScript does not have interfaces at all.
44
97
45
98
## Compilation scheme ##
46
-
No modificaiton of typer is planned. The current proposed scheme piggybacks on already existing scoping restrictions in typer, thus requiring `@static` methods to be defined in `objects`.
47
-
If implemented in dotty code base, such modifications would be needed:
48
-
- extend RefChecks to check restrictions 1, 2, 4, 5 and 6. This can be done in a separate mini-phase;
49
-
- extend LamdaLift.CollectDependencies to be aware that accessing member annotated `@static` should not trigger capturing object that contains this member;
50
-
- extend LambdaLift to trigger error if `@static`annotated method cannot be lifted to top level scope;
51
-
- extend GenBCode to emmit static fields and methods in companion classes and forwarders to them in companion modules.
99
+
No modificaiton of the typer is planned. The current proposed scheme piggybacks on already existing scoping restrictions in the typer, thus requiring `@static` methods to be defined in `objects`.
100
+
If implemented in the dotty code base, the following modifications would be needed:
101
+
- extend `RefChecks` to check restrictions 1, 2, 4, 5 and 6. This can be done in a separate mini-phase;
102
+
- extend `LamdaLift.CollectDependencies` to be aware that accessing a member annotated `@static` should not trigger capturing the object that contains this member;
103
+
- extend `LambdaLift` to trigger an error if a method annotated with `@static` method cannot be lifted to the top level scope;
104
+
- extend `GenBCode` to emit static fields and methods in companion classes and forwarders to them in companion modules.
52
105
53
106
## Overriding&Hiding ##
54
-
Java allows classes to define static methods with same name and signature as a static method of superclass. In order to define semantics of what does it mean,
55
-
Java Specification introduces a notion of [hiding](http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.8.2).
107
+
Java allows classes to define static methods with the same name and signature as a static method of a superclass. In order to define the semantics of such cases, the Java Specification introduces the notion of [hiding](http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.8.2).
56
108
57
-
This is required because in Java calling `@static` method on class instance is supported.
109
+
This is required because in Java calling a `static` method on a class instance is supported.
58
110
This proposal does not need to introduce this notion as we do not support such calls.
59
111
60
-
## Comparison with @lrytz[proposal](https://gist.github.com/lrytz/80f3141de8240f9629da) ##
61
-
Lucas Rytz has proposed a similar SIP, but his SIP requires changes to typer to ensure that `@static` fields do not capture `this`, as in his proposal `@static` fields are defined in class body.
62
-
It also does not address the question of `@static` members in inner objects and inheritance\hiding of those methods in subclasses.
112
+
## Comparison with [@lrytz's proposal](https://gist.github.com/lrytz/80f3141de8240f9629da) ##
113
+
Lucas Rytz has proposed a similar SIP, but his SIP requires changes to the typer to ensure that `@static` fields do not capture `this`, as in his proposal `@static` fields are defined in the class, rather than its companion object.
114
+
It also does not address the question of `@static` members in inner objects and inheritance/hiding of those methods in subclasses.
63
115
64
116
## Open questions ##
65
117
-@static lazy val
66
118
67
119
## See Also ##
68
120
*[SI-4581](https://issues.scala-lang.org/browse/SI-4581) is a request for a `@static` annotation
121
+
*[Scala.js issue #1902](https://github.com/scala-js/scala-js/issues/1902) is a request for defining static fields in Scala.js-defined JS classes
69
122
*[Another proposal by @lrytz](https://gist.github.com/lrytz/80f3141de8240f9629da)
70
123
*[Old discussion on scala-internals mailing list](https://groups.google.com/forum/#!searchin/scala-internals/static/scala-internals/vOps4k8CADY/Dq1I3Ysvao0J)
71
124
*[Another discussion of scala-internals mailing list](https://groups.google.com/forum/#!searchin/scala-internals/static/scala-internals/Y3OlFWPvnyM/tGE5BQw4Pe0J)
0 commit comments