Introduce typed semantic analysis pipeline
This commit is contained in:
parent
117d188194
commit
f4cd4f4458
30 changed files with 2079 additions and 2381 deletions
|
|
@ -707,7 +707,7 @@ fun main() {
|
|||
}
|
||||
}
|
||||
|
||||
func TestBuildDocumentStateChannelsAndSelectSemantics(t *testing.T) {
|
||||
func TestBuildDocumentStateChannelSemantics(t *testing.T) {
|
||||
text := strings.TrimSpace(`
|
||||
package demo
|
||||
|
||||
|
|
@ -716,13 +716,8 @@ fun writer(ch: Channel<Int>) {
|
|||
}
|
||||
|
||||
fun main() {
|
||||
val ch = Channel<Int>()
|
||||
runBlocking {
|
||||
launch { writer(ch) }
|
||||
select {
|
||||
ch -> println(it)
|
||||
}
|
||||
}
|
||||
val ch = Channel<Int>(1)
|
||||
writer(ch)
|
||||
val v = ch.read()
|
||||
println(v)
|
||||
}
|
||||
|
|
@ -787,138 +782,3 @@ fun main() {
|
|||
t.Fatal("expected removed worker syntax diagnostic")
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildDocumentStateTimerBuiltinsSemantics(t *testing.T) {
|
||||
text := strings.TrimSpace(`
|
||||
package demo
|
||||
|
||||
fun main() {
|
||||
val once = after(1000)
|
||||
val repeat = every(250)
|
||||
select {
|
||||
after(1000) -> println(it)
|
||||
every(250) -> println("tick")
|
||||
}
|
||||
println(once)
|
||||
println(repeat)
|
||||
}
|
||||
`)
|
||||
|
||||
state := buildDocumentState(text)
|
||||
if state.program == nil {
|
||||
t.Fatal("expected parsed program")
|
||||
}
|
||||
if len(state.diagnostics) != 0 {
|
||||
t.Fatalf("expected no diagnostics, got %+v", state.diagnostics)
|
||||
}
|
||||
|
||||
var onceDetail string
|
||||
var repeatDetail string
|
||||
for _, sym := range state.symbols {
|
||||
if sym.Kind != symbolKindVariable {
|
||||
continue
|
||||
}
|
||||
if sym.Name == "once" {
|
||||
onceDetail = sym.Detail
|
||||
}
|
||||
if sym.Name == "repeat" {
|
||||
repeatDetail = sym.Detail
|
||||
}
|
||||
}
|
||||
if onceDetail != "val once: Channel<time.Time>" {
|
||||
t.Fatalf("unexpected once detail: %q", onceDetail)
|
||||
}
|
||||
if repeatDetail != "val repeat: Channel<time.Time>" {
|
||||
t.Fatalf("unexpected repeat detail: %q", repeatDetail)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildDocumentStateEveryNonPositiveDiagnostics(t *testing.T) {
|
||||
text := strings.TrimSpace(`
|
||||
package demo
|
||||
|
||||
fun main() {
|
||||
select {
|
||||
every(0) -> println("x")
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
state := buildDocumentState(text)
|
||||
if state.program == nil {
|
||||
t.Fatal("expected parsed program")
|
||||
}
|
||||
if len(state.diagnostics) == 0 {
|
||||
t.Fatal("expected diagnostics")
|
||||
}
|
||||
found := false
|
||||
for _, d := range state.diagnostics {
|
||||
if strings.Contains(d.Message, "every(ms) requires ms > 0") {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Fatalf("expected every(ms) diagnostic, got %+v", state.diagnostics)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildDocumentStateAfterIntArgumentDiagnostics(t *testing.T) {
|
||||
text := strings.TrimSpace(`
|
||||
package demo
|
||||
|
||||
fun main() {
|
||||
select {
|
||||
after("1s") -> println("x")
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
state := buildDocumentState(text)
|
||||
if state.program == nil {
|
||||
t.Fatal("expected parsed program")
|
||||
}
|
||||
found := false
|
||||
for _, d := range state.diagnostics {
|
||||
if strings.Contains(d.Message, "after(ms) expects an Int argument") {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Fatalf("expected after int argument diagnostic, got %+v", state.diagnostics)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHoverBuiltinEverySignature(t *testing.T) {
|
||||
text := strings.TrimSpace(`
|
||||
package demo
|
||||
|
||||
fun main() {
|
||||
every(100)
|
||||
}
|
||||
`)
|
||||
uri := "file:///tmp/demo.gt"
|
||||
s := &server{
|
||||
docs: map[string]documentState{
|
||||
uri: buildDocumentState(text),
|
||||
},
|
||||
}
|
||||
|
||||
result := s.hover(uri, position{Line: 3, Character: 5})
|
||||
if result == nil {
|
||||
t.Fatal("expected hover result")
|
||||
}
|
||||
m, ok := result.(map[string]any)
|
||||
if !ok {
|
||||
t.Fatalf("unexpected hover type: %T", result)
|
||||
}
|
||||
contents, ok := m["contents"].(map[string]any)
|
||||
if !ok {
|
||||
t.Fatalf("unexpected hover contents: %+v", m)
|
||||
}
|
||||
value, _ := contents["value"].(string)
|
||||
if !strings.Contains(value, "fun every(ms: Int): Channel<time.Time>") {
|
||||
t.Fatalf("unexpected hover value: %q", value)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue