mirror of
https://github.com/apple/pkl.git
synced 2026-06-29 08:46:22 +02:00
Resolve variables at parse time (#1429)
This replaces `ResolveVariableNode` and `ResolveMethodNode` with their resolution. When we build the truffle node tree, we determine whether names resolve to: * lexical scope * base module * implicit this Then, we use this information to directly construct the underlying nodes (`ReadPropertyNode`, `ReadLocalPropertyNode`, etc). Additionally, `AstBuilder` determines whether the property access must be const or not. This introduces a `BaseModuleMembers` registry, which gets generated as part of Java compilation.
This commit is contained in:
+34
@@ -0,0 +1,34 @@
|
||||
import "pkl:reflect"
|
||||
|
||||
const function plusThree(it) = it + 3
|
||||
const function plusFour(it) = it + 4
|
||||
|
||||
local const myProp = "myProp"
|
||||
|
||||
class MyClass {
|
||||
@MyAnnotation {
|
||||
func = (it) -> plusThree(it)
|
||||
prop = myProp
|
||||
}
|
||||
foo: Int
|
||||
}
|
||||
|
||||
@MyAnnotation {
|
||||
func = (it) -> plusFour(it)
|
||||
prop = myProp
|
||||
}
|
||||
hidden qux: Int
|
||||
|
||||
class MyAnnotation extends Annotation {
|
||||
func: ((Any) -> Any)
|
||||
|
||||
prop: Any
|
||||
}
|
||||
|
||||
local nestedAnnotation = reflect.Class(MyClass).properties["foo"].annotations.first as MyAnnotation
|
||||
local moduleAnnotation = reflect.Module(module).moduleClass.properties["qux"].annotations.first as MyAnnotation
|
||||
|
||||
res1 = nestedAnnotation.func.apply(15)
|
||||
res2 = nestedAnnotation.prop
|
||||
res3 = moduleAnnotation.func.apply(15)
|
||||
res4 = moduleAnnotation.prop
|
||||
@@ -0,0 +1,7 @@
|
||||
local foo = "hello"
|
||||
|
||||
bar {
|
||||
new Mixin {
|
||||
[foo] = "world"
|
||||
}.apply(new Dynamic {})
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
qux = "outer"
|
||||
|
||||
foo {
|
||||
when (true) {
|
||||
local qux = "then branch"
|
||||
prop = qux
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// `qux` has ambiguous locality; don't know if it should be local read or not
|
||||
|
||||
hidden res1 {
|
||||
cond = true
|
||||
prop {
|
||||
when (cond) {
|
||||
local qux = "then branch"
|
||||
} else {
|
||||
qux = "else branch"
|
||||
}
|
||||
theBranch = qux
|
||||
}
|
||||
}
|
||||
|
||||
res2 = (res1) {
|
||||
cond = false
|
||||
}
|
||||
|
||||
res3 {
|
||||
cond = true
|
||||
prop {
|
||||
when (cond) {
|
||||
local qux = "then branch"
|
||||
} else {
|
||||
qux = cond
|
||||
}
|
||||
theBranch = qux
|
||||
}
|
||||
}
|
||||
pkl-core/src/test/files/LanguageSnippetTests/input/generators/forGeneratorInMixinWithObjectParam.pkl
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
foo {
|
||||
bar = new Listing { "elem" } |> mapEnvWithObjectParam(new Dynamic {
|
||||
res1Name = "res1Value"
|
||||
res2Name = "res2Value"
|
||||
})
|
||||
}
|
||||
|
||||
function mapEnvWithObjectParam(_env: Dynamic) = new Mixin { it ->
|
||||
new {
|
||||
res = it
|
||||
}
|
||||
for (k, v in _env) {
|
||||
new {
|
||||
name = k
|
||||
value = v
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
local function myFunc(foo: String, bar: String, baz: String): Any = new Listing {
|
||||
for (
|
||||
qux in new Listing {
|
||||
for (param1 in List(1)) {
|
||||
List("\(param1) \(foo) \(bar) \(baz)")
|
||||
}
|
||||
}
|
||||
) {
|
||||
for (param2 in qux) {
|
||||
"Hello \(foo) \(bar) \(baz) \(param2)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res = myFunc("arg1", "arg2", "arg3")
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
res1 = 18
|
||||
res2 = "myProp"
|
||||
res3 = 19
|
||||
res4 = "myProp"
|
||||
@@ -0,0 +1,5 @@
|
||||
bar {
|
||||
new {
|
||||
["hello"] = "world"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
qux = "outer"
|
||||
foo {
|
||||
prop = "then branch"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
res2 {
|
||||
cond = false
|
||||
prop {
|
||||
qux = "else branch"
|
||||
theBranch = "else branch"
|
||||
}
|
||||
}
|
||||
res3 {
|
||||
cond = true
|
||||
prop {
|
||||
theBranch = "then branch"
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
foo {
|
||||
bar {
|
||||
"elem"
|
||||
new {
|
||||
res {
|
||||
"elem"
|
||||
}
|
||||
}
|
||||
new {
|
||||
name = "res1Name"
|
||||
value = "res1Value"
|
||||
}
|
||||
new {
|
||||
name = "res2Name"
|
||||
value = "res2Value"
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
res {
|
||||
"Hello arg1 arg2 arg3 1 arg1 arg2 arg3"
|
||||
}
|
||||
@@ -223,6 +223,24 @@ class ReplServerTest {
|
||||
assertThat((response as ReplResponse.EvalSuccess).result).isEqualTo("\u001B[32m5\u001B[0m.ms")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `strip expression preamble in error message`() {
|
||||
val result = makeFailingEvalRequest("foo")
|
||||
assertThat(result)
|
||||
.isEqualTo(
|
||||
"""
|
||||
–– Pkl Error ––
|
||||
Cannot find property `foo`.
|
||||
|
||||
1 | foo
|
||||
^^^
|
||||
at (repl:id)
|
||||
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
}
|
||||
|
||||
private fun makeEvalRequest(text: String): String {
|
||||
val responses = server.handleRequest(ReplRequest.Eval("id", text, false, false))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user