Add this as a self type#1708
Conversation
6fb74b2 to
fa93f3d
Compare
a1d16f8 to
55f923c
Compare
71958eb to
a8c3282
Compare
| /** | ||
| * If {@code frame} is provided then self types should be resolved to real types, otherwise return | ||
| * the self PType | ||
| */ | ||
| protected PType doExport(@Nullable VirtualFrame frame) { |
There was a problem hiding this comment.
ReferenceTypeNode needs to export the real class here, so when a frame is passed NonFinalSelfTypeNode uses it to get the target's class instead of exporting PType.MODULE/PType.THIS.
41b3a9f to
9d20551
Compare
b00e394 to
a5729f3
Compare
835f94f to
6c21103
Compare
bioball
left a comment
There was a problem hiding this comment.
Left some comments!
The major ones are:
- Much of the resolution logic should happen inside
AstBuilder; we shouldn't need to traverse the truffle tree - Not sure about the
realTypeAliasFramelogic added to type node execution; this feels like a workaround to a deeper issue - Not sure if
TypeNode.export()should be deferencing self types; this feels like the responsibility of the caller, notTypeNodeitself
| if (typeAliasNode.isBodyChild(prevParent)) { | ||
| throw exceptionBuilder() | ||
| .evalError("invalidSelfTypeUsage", "this", "type alias") | ||
| .build(); |
There was a problem hiding this comment.
I think we should handle this error at parse time in AstBuilder, rather than here. We should walk the parser syntax tree, rather than Truffle
| } | ||
| PType.THIS -> { | ||
| +"this" | ||
| } |
There was a problem hiding this comment.
Need to also handle PType.THIS in SearchIndexGenerator and PackageDataGenerator
|
|
||
| return VmUtils.getClass(getReceiverNode.executeGeneric(frame)); | ||
| } | ||
| } |
There was a problem hiding this comment.
Same comment as above: I think this should be done at parse time (within AstBuilder), not here.
This truffle node can receive the (nullable) enclosing class name, and use a combination of GetModuleNode (in the case of no enclosing module) and ResolveSimpleDeclaredTypeNode (in the case of an enclosing module) to get the correct VmClass
There was a problem hiding this comment.
Within AstBuilder, we can walk up the symbol table scope until we find a Class scope to find the class identifier.
There was a problem hiding this comment.
We can also maybe introduce a ReadClassNode or something like that perhaps that receives the identifier name, whether it's local, and whether it's the module class.
|
|
||
| private VirtualFrame getEffectiveFrame(VirtualFrame frame) { | ||
| var realFrame = VmLanguage.get(this).localContext.get().getRealTypeAliasFrame(); | ||
| return realFrame != null ? realFrame : frame; |
There was a problem hiding this comment.
I'm trying to understand what this code is doing; is this to address the case of typealias Foo = module?'
If so, I think probably a better solution here is: when we execute a TypeAliasNode, we can replace the module type when we execute the type alias itself (e.g. inside TypeAliasNode#executeGeneric)
| // gets replaced upon instantiation, and Function can bubble up to users as a reference error | ||
| // if accessed. | ||
| result.add(type); | ||
| // PType.MODULE and PType.THIS can never be encountered here; caller must deref self types |
There was a problem hiding this comment.
I don't think this is actually happening here? This class is just calling clazz.export() in the constructor, which won't pass in a frame, which won't defer self types.
There was a problem hiding this comment.
Also: I don't know if it's worth investing too much into this code path; I think we should introduce a VmType value. If we had that, the TypeNode.export() call wouldn't be used.
| } | ||
| }; | ||
|
|
||
| /** The type of the enclosing owner. */ |
There was a problem hiding this comment.
| /** The type of the enclosing owner. */ | |
| /** The {@code this} type. */ |
| `Reference` referent type argument may not include type constraints. | ||
|
|
||
| invalidSelfTypeUsage=\ | ||
| `{0}` type annotations are not allowed in {1} bodies. |
There was a problem hiding this comment.
A "type annotation" is the thing on the right-hand side of a typed identifier; foo: Bar has type annotation : Bar
| `{0}` type annotations are not allowed in {1} bodies. | |
| `{0}` types are not allowed in {1} bodies. |
| } | ||
|
|
||
| @Override | ||
| @TruffleBoundary |
There was a problem hiding this comment.
Leftover code? This didn't need a truffle boundary before, so I wouldn't expect this to need one now
| @@ -0,0 +1,14 @@ | |||
| –– Pkl Error –– | |||
| `this` type annotations are not allowed in type alias bodies. | |||
There was a problem hiding this comment.
For consistency with other error messages, I think let's phrase this as:
Cannot declare `this` types inside type alias bodies.
This PR:
this, a fully featured self type for use in modules or classes.thisin typealias bodies.moduletype in class and typealias bodies with a warning, to be an error in a future release.moduletypes as typelias type args are evaluated in the context of the alias's module, not wheremoduleis used #1712).thisor a self-import and use of the current module.thisin the standard library:pkl.base#Any.getClass()now returnsClass<this>.pkl.base#Any.ifNonNull()now accepts an argument of type(this) -> Result.pkl.ref#Domain.renderReference()now accepts aReference<this, Any>.ReferenceTypeNode,moduletypes, and type aliases that causedmoduletypes in the referent position to always be resolved to the module where theReferencetype annotation is instead of wheremoduleis used.For ease of review, this PR consists of two commits; the first is all implementation changes, the second includes regenerated pkl-doc test output.
Resolves #1612
Resolves #1712