-
Notifications
You must be signed in to change notification settings - Fork 323
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
[Poc] Generate IR definitions - superclass approach #11770
base: develop
Are you sure you want to change the base?
Changes from all commits
6e33120
69f9247
0e4ceb0
9891eb7
a3bf203
08b0571
51796ba
3ea7a90
f6bf733
1870ef2
826245d
fc89b3d
1fc0497
d2bb8c3
68a070b
cf08781
f930e53
298c883
bc1e9c9
ef05c64
aa0a5b6
c6def78
8cea491
f5cb331
2393e18
cf1d079
f63bda1
158a4f1
1289374
73a9d31
be4396c
3665232
260d11d
df95a4e
7918fd2
9ae8e3f
cf264cf
0f21885
18b2d10
26239a3
9c3a580
c6b1987
399ca43
7a97c61
8acfa30
7988276
c84ebb7
8a778f0
86d1b0e
8aa64bd
e91f09e
dd34e5d
2a2b6d3
7def7b1
66aba89
f6b75ed
9bccf1c
f027307
687d0e1
bd9b7e4
98f4743
92d9004
69728be
7709597
7d012fe
cb06f03
c08c035
43ed045
69258cf
f888cee
57c5bff
be2d374
b828603
814d031
419dca0
c8cbc98
fd6ad5b
e066374
68389f4
1b7a120
aa345ed
fa26144
c4a669e
e4222f0
4d5b214
5ef1bde
9b48ed4
5ac716a
4a0ea14
9b5f1b2
e294877
00ad5f6
e6c7609
c8b7e34
fadf973
b549bf7
f6f0e4d
70deaca
f02b645
088b614
3a3cc14
11d2a25
e6205f1
ea17b2f
d978592
54d9c25
7507065
e026c77
f66ded2
363a838
b8f6b8f
a42d236
6587692
3ea1bb3
d61eca7
0ea630d
006406f
4973bb8
00cae90
3cb8424
371071b
a94a954
4368bd1
6222615
8f699f9
51420df
db713a7
f33af6e
30f14d9
ba602c4
9bae261
1b069ed
b3e262b
1a87899
e7dc725
0a1f5a8
83fe023
c6d66c3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module org.enso.runtime.parser.dsl { | ||
exports org.enso.runtime.parser.dsl; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package org.enso.runtime.parser.dsl; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
/** | ||
* Parameters of the constructor annotated with this annotation will be scanned by the IR processor | ||
* and <b>fields</b>will be generated for them. There can be only a single constructor with this | ||
* annotation in a class. The enclosing class must be annotated with {@link GenerateIR}. | ||
* | ||
* <h2>Fields</h2> | ||
* | ||
* The generated class will contain 4 <b>meta</b> fields that are required to be present inside | ||
* every IR element: | ||
* | ||
* <ul> | ||
* <li>{@code private DiagnosticStorage diagnostics} | ||
* <li>{@code private MetadataStorage passData} | ||
* <li>{@code private IdentifiedLocation location} | ||
* <li>{@code private UUID id} | ||
* </ul> | ||
* | ||
* Apart from these <b>meta</b> fields, the generated class will also contain <b>user-defined</b> | ||
* fields. User-defined fields are inferred from all the parameters of the constructor annotated | ||
* with {@link GenerateFields}. The parameter of the constructor can be one of the following: | ||
* | ||
* <ul> | ||
* <li>Any reference, or primitive type annotated with {@link IRField} | ||
* <li>A subtype of {@code org.enso.compiler.ir.IR} annotated with {@link IRChild} | ||
* <li>One of the <emph>meta</emph> types mentioned above | ||
* </ul> | ||
* | ||
* <p>A user-defined field generated out of constructor parameter annotated with {@link IRChild} is | ||
* a child element of this IR element. That means that it will be included in generated | ||
* implementation of IR methods that iterate over the IR tree. For example {@code mapExpressions} or | ||
* {@code children}. | ||
* | ||
* <p>A user-defined field generated out of constructor parameter annotated with {@link IRField} | ||
* will be a field with generated getters. Such field however, will not be part of the IR tree | ||
* traversal methods. | ||
* | ||
* <p>For a constructor parameter of a meta type, there will be no user-defined field generated, as | ||
* the meta fields are always generated. | ||
* | ||
* <p>Other types of constructor parameters are forbidden. | ||
*/ | ||
@Retention(RetentionPolicy.SOURCE) | ||
@Target(ElementType.CONSTRUCTOR) | ||
public @interface GenerateFields {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package org.enso.runtime.parser.dsl; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
/** | ||
* A class annotated with this annotation will be processed by the IR processor. The processor will | ||
* generate a super class that is meant to be extended by this class. The generated class will have | ||
* the same package as this class, and its name will have the "Gen" suffix. Majority of the methods | ||
* in the generated class will be either private or package-private, so that they are not accessible | ||
* from the outside. | ||
* | ||
* <p>The class can be enclosed (nested inside) an interface. | ||
* | ||
* <p>The class must contain a single constructor annotated with {@link GenerateFields}. | ||
*/ | ||
@Retention(RetentionPolicy.SOURCE) | ||
@Target(ElementType.TYPE) | ||
public @interface GenerateIR { | ||
|
||
/** | ||
* Name of the interfaces that the generated superclass must implement. All the interfaces must be | ||
* subtypes of the {@code org.enso.compiler.ir.IR} interface. All the abstract parameterless | ||
* methods from all the interfaces will be implemented by the generated class. Must not be empty. | ||
* | ||
* @return | ||
*/ | ||
String interfaces() default "org.enso.compiler.core.IR"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess this is not used yet. I see plural being used here. In such case the value should be |
||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,19 @@ | ||||||
package org.enso.runtime.parser.dsl; | ||||||
|
||||||
import java.lang.annotation.ElementType; | ||||||
import java.lang.annotation.Retention; | ||||||
import java.lang.annotation.RetentionPolicy; | ||||||
import java.lang.annotation.Target; | ||||||
|
||||||
/** | ||||||
* Constructor parameter annotated with this annotation will be represented as a child field in the | ||||||
* generated super class. Children of IR elements for a tree. A child will be part of the methods | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
* traversing the tree, like {@code mapExpression} and {@code children}. The parameter type must be | ||||||
* a subtype of {@code org.enso.compiler.ir.IR}. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
*/ | ||||||
@Retention(RetentionPolicy.SOURCE) | ||||||
@Target(ElementType.PARAMETER) | ||||||
public @interface IRChild { | ||||||
/** If true, the child will always be non-null. Otherwise, it can be null. */ | ||||||
boolean required() default true; | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package org.enso.runtime.parser.dsl; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
/** | ||
* A constructor parameter annotated with this annotation will have a corresponding user-defined | ||
* field generated in the super class (See {@link GenerateFields} for docs about fields). | ||
* | ||
* <p>There is no restriction on the type of the parameter. | ||
*/ | ||
@Retention(RetentionPolicy.SOURCE) | ||
@Target(ElementType.PARAMETER) | ||
public @interface IRField { | ||
/** If true, the field will always be non-null. Otherwise, it can be null. */ | ||
boolean required() default true; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package org.enso.runtime.parser.processor.test.gen.ir.core; | ||
|
||
import java.util.function.Function; | ||
import org.enso.compiler.core.IR; | ||
import org.enso.compiler.core.ir.Expression; | ||
import org.enso.compiler.core.ir.Name; | ||
import org.enso.runtime.parser.dsl.GenerateFields; | ||
import org.enso.runtime.parser.dsl.GenerateIR; | ||
import org.enso.runtime.parser.dsl.IRChild; | ||
import org.enso.runtime.parser.dsl.IRField; | ||
import scala.Option; | ||
|
||
/** Call-site arguments in Enso. */ | ||
public interface JCallArgument extends IR { | ||
/** The name of the argument, if present. */ | ||
Option<Name> name(); | ||
|
||
/** The expression of the argument, if present. */ | ||
Expression value(); | ||
|
||
/** Flag indicating that the argument was generated by compiler. */ | ||
boolean isSynthetic(); | ||
|
||
@Override | ||
JCallArgument mapExpressions(Function<Expression, Expression> fn); | ||
|
||
@Override | ||
JCallArgument duplicate( | ||
boolean keepLocations, | ||
boolean keepMetadata, | ||
boolean keepDiagnostics, | ||
boolean keepIdentifiers); | ||
|
||
@GenerateIR(interfaces = "JCallArgument") | ||
final class JSpecified extends JSpecifiedGen { | ||
@GenerateFields | ||
public JSpecified( | ||
@IRField boolean isSynthetic, @IRChild Option<Name> name, @IRChild Expression value) { | ||
super(isSynthetic, name, value); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package org.enso.runtime.parser.processor.test.gen.ir.core; | ||
|
||
import java.util.function.Function; | ||
import org.enso.compiler.core.IR; | ||
import org.enso.compiler.core.ir.Expression; | ||
import org.enso.compiler.core.ir.Name; | ||
import org.enso.runtime.parser.dsl.GenerateFields; | ||
import org.enso.runtime.parser.dsl.GenerateIR; | ||
import org.enso.runtime.parser.dsl.IRChild; | ||
import org.enso.runtime.parser.dsl.IRField; | ||
import scala.collection.immutable.List; | ||
|
||
public interface JExpression extends IR { | ||
@Override | ||
JExpression mapExpressions(Function<Expression, Expression> fn); | ||
|
||
@Override | ||
JExpression duplicate( | ||
boolean keepLocations, | ||
boolean keepMetadata, | ||
boolean keepDiagnostics, | ||
boolean keepIdentifiers); | ||
|
||
@GenerateIR(interfaces = "JExpression") | ||
final class JBlock extends JBlockGen { | ||
@GenerateFields | ||
public JBlock( | ||
@IRChild List<JExpression> expressions, | ||
@IRChild JExpression returnValue, | ||
@IRField boolean suspended) { | ||
super(expressions, returnValue, suspended); | ||
} | ||
} | ||
|
||
@GenerateIR(interfaces = "JExpression") | ||
final class JBinding extends JBindingGen { | ||
@GenerateFields | ||
public JBinding(@IRChild Name name, @IRChild JExpression expression) { | ||
super(name, expression); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/** | ||
* Contains hierarchy of interfaces that should correspond to the previous {@link | ||
* org.enso.compiler.core.IR} element hierarchy. All the classes inside this package have {@code J} | ||
* prefix. So for example {@code JCallArgument} correspond to {@code CallArgument}. | ||
* | ||
* <p>The motivation to put these classes here is to test the generation of {@link | ||
* org.enso.runtime.parser.processor.IRProcessor}. | ||
*/ | ||
package org.enso.runtime.parser.processor.test.gen.ir.core; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/** | ||
* Contains interfaces with parser-dsl annotations. There will be generated classes for these | ||
* interfaces and they are tested. All these interfaces are only for testing. | ||
*/ | ||
package org.enso.runtime.parser.processor.test.gen.ir; |
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 is possible to extract the name of the super class from
class X extends MyParent
definition. E.g. then the name of the super class could be arbitrary. It would have to be in the same package, but there would be no restriction on theGen
suffix.