Skip to content

Commit 492f46f

Browse files
authored
Merge pull request #34 from vknabel/feature/packages
Packages and improved LSP
2 parents 2e743ca + e7d71a1 commit 492f46f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+1092
-229
lines changed

.devcontainer/Dockerfile

+4-1
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,7 @@ RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/
1616
# RUN go get -x <your-dependency-or-tool>
1717

1818
# [Optional] Uncomment this line to install global node packages.
19-
# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g <your-package-here>" 2>&1
19+
# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g <your-package-here>" 2>&1
20+
21+
COPY ./lithia /usr/local/bin/lithia
22+
ENV LITHIA_STDLIB /workspaces/lithia/stdlib

.devcontainer/lithia

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/usr/bin/env sh
2+
3+
go run ./app/lithia

.vscode/launch.json

+13-8
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,6 @@
44
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
55
"version": "0.2.0",
66
"configurations": [
7-
{
8-
"name": "Attach to Process",
9-
"type": "go",
10-
"request": "attach",
11-
"mode": "local",
12-
"processId": 0
13-
},
147
{
158
"name": "Write docs",
169
"type": "go",
@@ -37,7 +30,19 @@
3730
}
3831
},
3932
{
40-
"name": "Launch lithia",
33+
"name": "Launch example greeter",
34+
"type": "go",
35+
"request": "launch",
36+
"mode": "auto",
37+
"program": "${workspaceFolder}/app/lithia/main.go",
38+
"args": ["${workspaceFolder}/examples/greeter/cmd/main.lithia"],
39+
"cwd": "${workspaceFolder}",
40+
"env": {
41+
"LITHIA_STDLIB": "${workspaceFolder}/stdlib"
42+
}
43+
},
44+
{
45+
"name": "Launch fib-type",
4146
"type": "go",
4247
"request": "launch",
4348
"mode": "auto",

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
## v0.0.16-next
44

55
- fix: undeclared enum case error due to file order within a module
6+
- compiler: new concept of packages containing modules, optionally marked by a `Potfile`
7+
- compiler: implicit `src` module for package imports if folder exists
8+
- compiler: `import root` imports the current package (imports `src` if folder exists)
9+
- lsp: improved autocompletion and hover information
10+
- lsp: autocompletion and hover information across module and file boundaries
11+
- lsp: local autocompletion #30
612

713
## v0.0.15
814

README.md

+20-3
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Currently Lithia is an early proof of concept. Basic language features exist, bu
2626
- [x] Creating a custom language server
2727
- [x] ... with diagnostics
2828
- [x] ... with syntax highlighting
29-
- [ ] ... with auto completion _proof of concept_
29+
- [x] ... with auto completion _basic_
3030
- [ ] ... with highlights
3131
- [ ] ... with refactorings
3232
- [ ] ... with formatter
@@ -264,9 +264,26 @@ As shown, a common use case is to pass the module itself instead of multiple wit
264264

265265
### Module resolution
266266

267-
Lithia will search for a folder containing source files at the following locations:
267+
To create your own package of modules, you can create a `Potfile`. Every module defined by the package is a directory next to the Potfile, with `.lithia` files in it.
268+
269+
Though there are a few special cases:
270+
271+
- the `cmd`-folder is typically used for individual files rather than a module. You execute them with `$ lithia cmd/<file>`.
272+
- the `src`-folder represents the `root` of the package.
273+
- if the `src`-folder is missing, the package `root` is next to the Potfile.
274+
275+
```
276+
.
277+
├── Potfile
278+
├── cmd
279+
│ ├── main.lithia
280+
│ └── test.lithia
281+
└── src
282+
└── greet.lithia
283+
```
284+
285+
If there aren't any matching local modules, Lithia will search for a package containing source files at the following locations:
268286

269-
- when executing a file, relative to it
270287
- when in REPL, inside the current working directory
271288
- at `$LITHIA_LOCALS` if set
272289
- at `$LITHIA_PACKAGES` if set

ast/context-file.go

+19
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,22 @@ func (sf *SourceFile) AddExpr(expr Expr) {
3838
}
3939
sf.Statements = append(sf.Statements, expr)
4040
}
41+
42+
func (sf *SourceFile) ExportedDeclarations() []Decl {
43+
decls := make([]Decl, 0)
44+
for _, decl := range sf.Declarations {
45+
if decl.IsExportedDecl() {
46+
decls = append(decls, decl)
47+
}
48+
}
49+
return decls
50+
}
51+
52+
func (sf SourceFile) EnumerateNestedDecls(enumerate func(interface{}, []Decl)) {
53+
for _, decl := range sf.Declarations {
54+
decl.EnumerateNestedDecls(enumerate)
55+
}
56+
for _, stmt := range sf.Statements {
57+
stmt.EnumerateNestedDecls(enumerate)
58+
}
59+
}

ast/decl-constant.go

+11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package ast
22

3+
import "fmt"
4+
35
var _ Decl = DeclConstant{}
6+
var _ Overviewable = DeclConstant{}
47

58
type DeclConstant struct {
69
Name Identifier
@@ -14,6 +17,10 @@ func (e DeclConstant) DeclName() Identifier {
1417
return e.Name
1518
}
1619

20+
func (e DeclConstant) DeclOverview() string {
21+
return fmt.Sprintf("let %s", e.Name)
22+
}
23+
1724
func (e DeclConstant) Meta() *MetaDecl {
1825
return e.MetaInfo
1926
}
@@ -33,3 +40,7 @@ func MakeDeclConstant(name Identifier, value Expr, source *Source) *DeclConstant
3340
func (e DeclConstant) ProvidedDocs() *Docs {
3441
return e.Docs
3542
}
43+
44+
func (e DeclConstant) EnumerateNestedDecls(enumerate func(interface{}, []Decl)) {
45+
e.Value.EnumerateNestedDecls(enumerate)
46+
}

ast/decl-data.go

+21
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package ast
22

3+
import (
4+
"fmt"
5+
"strings"
6+
)
7+
38
var _ Decl = DeclData{}
9+
var _ Overviewable = DeclData{}
410

511
type DeclData struct {
612
Name Identifier
@@ -14,6 +20,17 @@ func (e DeclData) DeclName() Identifier {
1420
return e.Name
1521
}
1622

23+
func (e DeclData) DeclOverview() string {
24+
if len(e.Fields) == 0 {
25+
return fmt.Sprintf("data %s", e.Name)
26+
}
27+
fieldLines := make([]string, 0)
28+
for _, field := range e.Fields {
29+
fieldLines = append(fieldLines, " "+field.DeclOverview())
30+
}
31+
return fmt.Sprintf("data %s {\n%s\n}", e.Name, strings.Join(fieldLines, "\n"))
32+
}
33+
1734
func (e DeclData) Meta() *MetaDecl {
1835
return e.MetaInfo
1936
}
@@ -40,3 +57,7 @@ func (e *DeclData) AddField(field DeclField) {
4057
func (decl DeclData) ProvidedDocs() *Docs {
4158
return decl.Docs
4259
}
60+
61+
func (DeclData) EnumerateNestedDecls(enumerate func(interface{}, []Decl)) {
62+
// no nested decls
63+
}

ast/decl-enum-case.go

+4
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,7 @@ func MakeDeclEnumCase(name Identifier) *DeclEnumCase {
3131
func (decl DeclEnumCase) ProvidedDocs() *Docs {
3232
return decl.Docs
3333
}
34+
35+
func (DeclEnumCase) EnumerateNestedDecls(enumerate func(interface{}, []Decl)) {
36+
// no nested decls
37+
}

ast/decl-enum.go

+20-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
package ast
22

3-
import "fmt"
3+
import (
4+
"fmt"
5+
"strings"
6+
)
47

58
var _ Decl = DeclEnum{}
9+
var _ Overviewable = DeclEnum{}
610

711
type DeclEnum struct {
812
Name Identifier
@@ -16,6 +20,17 @@ func (e DeclEnum) DeclName() Identifier {
1620
return e.Name
1721
}
1822

23+
func (e DeclEnum) DeclOverview() string {
24+
if len(e.Cases) == 0 {
25+
return fmt.Sprintf("enum %s", e.Name)
26+
}
27+
caseLines := make([]string, 0)
28+
for _, cs := range e.Cases {
29+
caseLines = append(caseLines, " "+string(cs.Name))
30+
}
31+
return fmt.Sprintf("enum %s {\n%s\n}", e.Name, strings.Join(caseLines, "\n"))
32+
}
33+
1934
func (e DeclEnum) Meta() *MetaDecl {
2035
return e.MetaInfo
2136
}
@@ -54,3 +69,7 @@ func (e DeclEnum) String() string {
5469
func (decl DeclEnum) ProvidedDocs() *Docs {
5570
return decl.Docs
5671
}
72+
73+
func (decl DeclEnum) EnumerateNestedDecls(enumerate func(interface{}, []Decl)) {
74+
// no nested decls - will be handled by the parser
75+
}

ast/decl-extern-func.go

+21
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package ast
22

3+
import (
4+
"fmt"
5+
"strings"
6+
)
7+
38
var _ Decl = DeclExternFunc{}
9+
var _ Overviewable = DeclExternFunc{}
410

511
type DeclExternFunc struct {
612
Name Identifier
@@ -22,6 +28,17 @@ func (e DeclExternFunc) IsExportedDecl() bool {
2228
return true
2329
}
2430

31+
func (e DeclExternFunc) DeclOverview() string {
32+
if len(e.Parameters) == 0 {
33+
return fmt.Sprintf("extern %s { => }", e.Name)
34+
}
35+
paramNames := make([]string, len(e.Parameters))
36+
for i, param := range e.Parameters {
37+
paramNames[i] = string(param.Name)
38+
}
39+
return fmt.Sprintf("extern %s { %s => }", e.Name, strings.Join(paramNames, ", "))
40+
}
41+
2542
func MakeDeclExternFunc(name Identifier, params []DeclParameter, source *Source) *DeclExternFunc {
2643
return &DeclExternFunc{
2744
Name: name,
@@ -33,3 +50,7 @@ func MakeDeclExternFunc(name Identifier, params []DeclParameter, source *Source)
3350
func (decl DeclExternFunc) ProvidedDocs() *Docs {
3451
return decl.Docs
3552
}
53+
54+
func (DeclExternFunc) EnumerateNestedDecls(enumerate func(interface{}, []Decl)) {
55+
// no nested decls
56+
}

ast/decl-extern-type.go

+21
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package ast
22

3+
import (
4+
"fmt"
5+
"strings"
6+
)
7+
38
var _ Decl = DeclExternType{}
9+
var _ Overviewable = DeclExternType{}
410

511
type DeclExternType struct {
612
Name Identifier
@@ -14,6 +20,17 @@ func (e DeclExternType) DeclName() Identifier {
1420
return e.Name
1521
}
1622

23+
func (e DeclExternType) DeclOverview() string {
24+
if len(e.Fields) == 0 {
25+
return fmt.Sprintf("extern %s", e.Name)
26+
}
27+
fieldLines := make([]string, 0)
28+
for _, field := range e.Fields {
29+
fieldLines = append(fieldLines, " "+field.DeclOverview())
30+
}
31+
return fmt.Sprintf("extern %s {\n%s\n}", e.Name, strings.Join(fieldLines, "\n"))
32+
}
33+
1734
func (e DeclExternType) Meta() *MetaDecl {
1835
return e.MetaInfo
1936
}
@@ -38,3 +55,7 @@ func (e *DeclExternType) AddField(decl DeclField) {
3855
func (decl DeclExternType) ProvidedDocs() *Docs {
3956
return decl.Docs
4057
}
58+
59+
func (DeclExternType) EnumerateNestedDecls(enumerate func(interface{}, []Decl)) {
60+
// no nested decls
61+
}

ast/decl-field.go

+21
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package ast
22

3+
import (
4+
"fmt"
5+
"strings"
6+
)
7+
38
var _ Decl = DeclField{}
9+
var _ Overviewable = DeclField{}
410

511
type DeclField struct {
612
Name Identifier
@@ -14,6 +20,17 @@ func (e DeclField) DeclName() Identifier {
1420
return e.Name
1521
}
1622

23+
func (e DeclField) DeclOverview() string {
24+
if len(e.Parameters) == 0 {
25+
return string(e.Name)
26+
}
27+
paramNames := make([]string, len(e.Parameters))
28+
for i, param := range e.Parameters {
29+
paramNames[i] = string(param.Name)
30+
}
31+
return fmt.Sprintf("%s %s", e.Name, strings.Join(paramNames, ", "))
32+
}
33+
1734
func (e DeclField) Meta() *MetaDecl {
1835
return e.MetaInfo
1936
}
@@ -36,3 +53,7 @@ func MakeDeclField(name Identifier, params []DeclParameter, source *Source) *Dec
3653
func (decl DeclField) ProvidedDocs() *Docs {
3754
return decl.Docs
3855
}
56+
57+
func (DeclField) EnumerateNestedDecls(enumerate func(interface{}, []Decl)) {
58+
// no nested decls
59+
}

ast/decl-func.go

+21
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package ast
22

3+
import (
4+
"fmt"
5+
"strings"
6+
)
7+
38
var _ Decl = DeclFunc{}
9+
var _ Overviewable = DeclFunc{}
410

511
type DeclFunc struct {
612
Name Identifier
@@ -14,6 +20,17 @@ func (e DeclFunc) DeclName() Identifier {
1420
return e.Name
1521
}
1622

23+
func (e DeclFunc) DeclOverview() string {
24+
if len(e.Impl.Parameters) == 0 {
25+
return fmt.Sprintf("func %s { => }", e.Name)
26+
}
27+
paramNames := make([]string, len(e.Impl.Parameters))
28+
for i, param := range e.Impl.Parameters {
29+
paramNames[i] = string(param.Name)
30+
}
31+
return fmt.Sprintf("func %s { %s => }", e.Name, strings.Join(paramNames, ", "))
32+
}
33+
1734
func (e DeclFunc) Meta() *MetaDecl {
1835
return e.MetaInfo
1936
}
@@ -35,3 +52,7 @@ func MakeDeclFunc(name Identifier, impl *ExprFunc, source *Source) *DeclFunc {
3552
func (decl DeclFunc) ProvidedDocs() *Docs {
3653
return decl.Docs
3754
}
55+
56+
func (decl DeclFunc) EnumerateNestedDecls(enumerate func(interface{}, []Decl)) {
57+
decl.Impl.EnumerateNestedDecls(enumerate)
58+
}

0 commit comments

Comments
 (0)