mirror of
https://github.com/apple/pkl.git
synced 2026-07-12 16:12:42 +02:00
Require references from typealiases to be const (#516)
This adds a language change that requires references from typealiases to the enclosing module to be `const`. This is required because typealiases are not late-bound. Rationale is laid out in SPICE-0007. Also: * Update documentation to reflect new rules. * Fix `Project.pkl`; mark method `const` to not break said rule.
This commit is contained in:
@@ -1147,9 +1147,13 @@ Therefore, the same rules that apply to `fixed` also apply to `const`:
|
|||||||
* The const-ness of a property or method must be preserved when it is overridden by a child class.
|
* The const-ness of a property or method must be preserved when it is overridden by a child class.
|
||||||
|
|
||||||
[[class-and-annotation-const]]
|
[[class-and-annotation-const]]
|
||||||
*Class and Annotation Scoping*
|
*Class, Annotation, and Typealias Scoping*
|
||||||
|
|
||||||
Within a class or annotation body, any reference to a property or method of its enclosing module requires that the referenced member is `const`.
|
In these following scenarios, any reference to a property or method of its enclosing module requires that the referenced member is `const`:
|
||||||
|
|
||||||
|
* Class body
|
||||||
|
* Annotation body
|
||||||
|
* Typealiased constrained type
|
||||||
|
|
||||||
.invalid2.pkl
|
.invalid2.pkl
|
||||||
[source%parsed,{pkl}]
|
[source%parsed,{pkl}]
|
||||||
@@ -1162,15 +1166,18 @@ class Bird {
|
|||||||
|
|
||||||
@Deprecated { message = "Replace with \(pigeonName)" } // <2>
|
@Deprecated { message = "Replace with \(pigeonName)" } // <2>
|
||||||
oldPigeonName: String
|
oldPigeonName: String
|
||||||
|
|
||||||
|
typealias IsPigeonName = String(pigeonName) // <3>
|
||||||
----
|
----
|
||||||
<1> Error: cannot reference non-const property `pigeonName` from a class.
|
<1> Error: cannot reference non-const property `pigeonName` from a class.
|
||||||
<2> Error: cannot reference non-const property `pigeonName` from an annotation.
|
<2> Error: cannot reference non-const property `pigeonName` from an annotation.
|
||||||
|
<3> Error: cannot reference non-const property `pigeonname` from a typealias.
|
||||||
|
|
||||||
This rule exists because classes and annotations are not <<late-binding,late bound>>;
|
This rule exists because classes, annotations, and typealiases are not <<late-binding,late bound>>;
|
||||||
it is not possible to change the definition of a class or annotation by amending the module
|
it is not possible to change the definition of these members by amending the module
|
||||||
where it is defined.
|
where it is defined.
|
||||||
|
|
||||||
Generally, there are two strategies for referencing a property from a class or annotation:
|
Generally, there are two strategies for referencing such properties:
|
||||||
|
|
||||||
*Add the `const` modifier to the referenced property*
|
*Add the `const` modifier to the referenced property*
|
||||||
|
|
||||||
|
|||||||
@@ -439,7 +439,7 @@ public final class SymbolTable {
|
|||||||
String qualifiedName,
|
String qualifiedName,
|
||||||
FrameDescriptor.Builder frameDescriptorBuilder,
|
FrameDescriptor.Builder frameDescriptorBuilder,
|
||||||
List<TypeParameter> typeParameters) {
|
List<TypeParameter> typeParameters) {
|
||||||
super(parent, name, qualifiedName, ConstLevel.NONE, frameDescriptorBuilder, typeParameters);
|
super(parent, name, qualifiedName, ConstLevel.MODULE, frameDescriptorBuilder, typeParameters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+5
@@ -0,0 +1,5 @@
|
|||||||
|
typealias MyValue = Any(isValid)
|
||||||
|
|
||||||
|
isValid = true
|
||||||
|
|
||||||
|
myValue: MyValue = 1
|
||||||
Vendored
+18
@@ -0,0 +1,18 @@
|
|||||||
|
–– Pkl Error ––
|
||||||
|
Cannot reference property `isValid` from here because it is not `const`.
|
||||||
|
|
||||||
|
x | typealias MyValue = Any(isValid)
|
||||||
|
^^^^^^^
|
||||||
|
at constTypeAliasConstraint#myValue (file:///$snippetsDir/input/errors/const/constTypeAliasConstraint.pkl)
|
||||||
|
|
||||||
|
To fix, do either of:
|
||||||
|
1. Add modifier `const` to property `isValid`
|
||||||
|
2. Self-import this module, and reference this property from the import.
|
||||||
|
|
||||||
|
x | myValue: MyValue = 1
|
||||||
|
^
|
||||||
|
at constTypeAliasConstraint#myValue (file:///$snippetsDir/input/errors/const/constTypeAliasConstraint.pkl)
|
||||||
|
|
||||||
|
xxx | text = renderer.renderDocument(value)
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
at pkl.base#Module.output.text (pkl:base)
|
||||||
+1
-1
@@ -221,7 +221,7 @@ function newInstance(enclosingModule: Module): Project = new {
|
|||||||
projectFileUri = reflect.Module(enclosingModule).uri
|
projectFileUri = reflect.Module(enclosingModule).uri
|
||||||
}
|
}
|
||||||
|
|
||||||
local hasVersion = (it: Uri) ->
|
const local hasVersion = (it: Uri) ->
|
||||||
let (versionSep = it.lastIndexOf("@"))
|
let (versionSep = it.lastIndexOf("@"))
|
||||||
if (versionSep == -1) false
|
if (versionSep == -1) false
|
||||||
else let (version = it.drop(versionSep + 1))
|
else let (version = it.drop(versionSep + 1))
|
||||||
|
|||||||
Reference in New Issue
Block a user