Skip to content

Commit 53fd83d

Browse files
committed
Incorporate feedback from @lrytz, @janekdb and @dwijnand.
1 parent b13183d commit 53fd83d

File tree

1 file changed

+37
-10
lines changed

1 file changed

+37
-10
lines changed

Diff for: sips/pending/_posts/2016-01-01-static-members.md renamed to sips/pending/_posts/2016-01-11-static-members.md

+37-10
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ title: SIP 25 - @static fields and methods in Scala objects(SI-4581)
44
disqus: true
55
---
66

7-
__Dmitry Petrashko and Sébastien Doeraene__
7+
__Dmitry Petrashko, Sébastien Doeraene and Martin Odersky__
88

9-
__first submitted TODO 2016__
9+
__first submitted 11 January 2016__
1010

1111
## Motivation ##
1212

@@ -18,18 +18,19 @@ Some JVM and JavaScript frameworks require classes to have specific static field
1818

1919
For example, classes extending `android.os.Parcelable` are required to have a static field named `CREATOR` of type `android.os.Parcelable$Creator`.
2020

21-
Another example is using an [`AtomicReferenceFieldUpdater`](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.html).
21+
Another example is using an [`AtomicReferenceFieldUpdater`](http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.html).
2222

2323
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`.
2424
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.
2525

2626
## Overview ##
2727

28-
In order for method or field to be considered static it needs to be defined in an `object` and annotated `@static`.
28+
In order for a method or field to be considered static it needs to be defined in an `object` and annotated `@static`.
2929
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.
3030

3131
For example:
3232

33+
```scala
3334
{% highlight scala %}
3435
class Foo
3536

@@ -41,10 +42,12 @@ object Foo {
4142
println(Foo.x)
4243
println(Foo.bar(12))
4344
{% endhighlight %}
45+
```
4446

45-
Intuively, the presence of the `@static` annotation ensures that a field/method is declared as a static member of the companion class.
47+
Intuitively, the presence of the `@static` annotation ensures that a field/method is declared as a static member of the companion class.
4648
For the JVM, the above would therefore look to other Java code as if it had been declared with the following Java code:
4749

50+
```java
4851
{% highlight java %}
4952
class Foo {
5053
public static int x = 5;
@@ -53,10 +56,12 @@ class Foo {
5356
}
5457
}
5558
{% endhighlight %}
59+
```
5660

5761
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).
5862
It has a semantic effect on Scala.js-defined JS classes, for example:
5963

64+
```scala
6065
{% highlight scala %}
6166
@ScalaJSDefined
6267
class Foo extends js.Object
@@ -67,9 +72,11 @@ object Foo extends js.Object {
6772
@static def bar(y: Int): Int = x + y
6873
}
6974
{% endhighlight %}
75+
```
7076

7177
would look to JavaScript code as if it had been declared with the following JavaScript code:
7278

79+
```javascript
7380
{% highlight javascript %}
7481
class Foo extends Object {
7582
static bar(y) {
@@ -78,22 +85,42 @@ class Foo extends Object {
7885
}
7986
Foo.x = 5; // in ES6, there is no declarative syntax for static fields yet
8087
{% endhighlight %}
88+
```
89+
90+
## Comparison with mirror classes ##
91+
92+
Scalac currently generates static forwarders for fields and methods in top-level objects:
93+
94+
```scala
95+
{% highlight scala %}
96+
object O {
97+
val d = 1
98+
object I {
99+
val f = 1
100+
}
101+
}
102+
{% endhighlight %}
103+
```
104+
105+
Under the proposed scheme users will be able to opt-in to have the field `f` defined in the inner object `I` emited as a static field.
106+
In case `O.d` is annotated with `@static` the field will be crated as a static field `d` in `class O`.
107+
If not annotated, it will be created in the companion module with a static forwarder `d` in `class O`.
81108

82109
## Restrictions ##
83110

84-
The following rules ensure that method can be correctly compiled into static member on both JVM and JavaScript:
111+
The following rules ensure that methods can be correctly compiled into static members on both JVM and JavaScript:
85112

86113
1. Only objects can have members annotated with `@static`
87114

88115
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.
89116

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.
117+
3. The right hand side of a method or field annotated with `@static` can only refer to top-level classes, members of globally accessible objects and `@static` members. In particular, for non-static objects `this` is not accesible. `super` is never accessible.
91118

92119
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`.
93120

94121
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`.
95122

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.
123+
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.
97124

98125
## Compilation scheme ##
99126
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`.
@@ -103,14 +130,14 @@ If implemented in the dotty code base, the following modifications would be need
103130
- extend `LambdaLift` to trigger an error if a method annotated with `@static` method cannot be lifted to the top level scope;
104131
- extend `GenBCode` to emit static fields and methods in companion classes and forwarders to them in companion modules.
105132

106-
## Overriding&Hiding ##
133+
## Overriding & Hiding ##
107134
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).
108135

109136
This is required because in Java calling a `static` method on a class instance is supported.
110137
This proposal does not need to introduce this notion as we do not support such calls.
111138

112139
## 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.
140+
Lukas 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.
114141
It also does not address the question of `@static` members in inner objects and inheritance/hiding of those methods in subclasses.
115142

116143
## Open questions ##

0 commit comments

Comments
 (0)