| Summary: | [Xtend] Add sugar for immutable objects | ||
|---|---|---|---|
| Product: | [Tools] Xtend | Reporter: | Steve Ash <stevemash> |
| Component: | Core | Assignee: | Project Inbox <xtend-inbox> |
| Status: | CLOSED FIXED | QA Contact: | |
| Severity: | enhancement | ||
| Priority: | P3 | CC: | bugs-eclipse.org, sven.efftinge |
| Version: | 2.2.0 | Flags: | sven.efftinge:
juno+
|
| Target Milestone: | M7 | ||
| Hardware: | PC | ||
| OS: | Windows 7 | ||
| Whiteboard: | |||
| Bug Depends on: | 373184 | ||
| Bug Blocks: | |||
An addition that could be done to this to make it even more useful would be to generate
withX(String x)
and withY(String y)
methods which return a "clone" of the instance with the X (resp. Y) property updated according to the argument given to the withX() method.
For example
val a = new MyDataValue("0", "1")
val ax = a.withX("00")
val ay = a.withY("11")
println(a)
println(ax)
println(ay)
would result in
MyDataValue{"0","1"}
MyDataValue{"00","1"}
MyDataValue{"0","11"}
(Obviously with a suitable toString() method... which could also be generated quite easily for these types of classes :)).
This would be an excellent use case for bug #373184 just like @Property we decided to do this now based on an annotation and back-port it to a more generic annotation processing hook, when it's available.
Here's the proposal:
@Data class Person {
String name
String firstName
val gender = Gender::MALE
}
1) all field are treated and marked as final. The internal field's name is renamed to _fieldName.
2) a constructor for the non-initialized fields is generated, the ordering of the parameters is the same as
the declaration of the fields. Collections are copied to immutable variants in the constructor.
3) a getter method for each field is generated, if not existing.
4) equals and hash code are generated
5) toString() is generated returning a multiline string in the following form
DataClassName {
field1 = toStringOfField1
field2 = ...
}
Constraints:
1) A data class can only refer to immutable data types. That is other data classes and a predefined list of classes.
2) A data class can only extend other data classes.
3) A data class must have the @Data annotation.
4) A data class must have final fields only.
5) A data class must have one constructor.
Comments? Anything I missed?
pushed to master Requested via bug 522520. -M. Requested via bug 522520. -M. |
Build Identifier: A popular new language feature in a number of languages (Scala, Cylon) is a concise syntax for immutable object construction. The use case is _not_ intended to support injection of collaborators-- that is still best served by DI. This is intended to provide sugar for the common idiom of passing values into a constructor which need to be assigned to a final field (exposed through a property). So all the time we see java like: public class MyDataValue { private final String x; private final String y; public MyDataValue(String x, String y) { this.x = x; this.y = y; } public String getX() { return this.x; } public String getY() { return this.y; } } Here is the Scala equivalent of that class: class MyDataValue(val x:String, val y:String) You can also have mixed mutability and do: class MyDataValue2(var x:String, val y:String) so x will have get/set property access and y will only have get and will be final. This is a common idiom with tremendous amount of noise reduction. So it might fit well into Xtend. If not, then fair enough. Just thought I would log it for consideration since I didn't see it. Reproducible: Always