using forked RustLSP for rust lsp : )

This commit is contained in:
Noah Santschi-Cooney 2020-02-13 22:31:02 +00:00
parent 41995c3f38
commit b4a19265f8
No known key found for this signature in database
GPG key ID: 3B22282472C8AE48
21 changed files with 462 additions and 1468 deletions

1
server/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
target

303
server/Cargo.lock generated Normal file
View file

@ -0,0 +1,303 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "autocfg"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "futures"
version = "0.1.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "idna"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-normalization 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "itoa"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "languageserver-types"
version = "0.54.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "log"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "log"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "matches"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "num-derive"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-traits"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "percent-encoding"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "proc-macro2"
version = "0.4.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "proc-macro2"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quote"
version = "0.6.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quote"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rust_lsp"
version = "0.6.0"
source = "git+https://github.com/Strum355/RustLSP#30d3247d70b8b8bff1cdeafd61cbfc3126ca432e"
dependencies = [
"languageserver-types 0.54.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rustdt-json_rpc 0.3.0 (git+https://github.com/strager/rustdt-json_rpc?branch=serde-1.0)",
"rustdt_util 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustdt-json_rpc"
version = "0.3.0"
source = "git+https://github.com/strager/rustdt-json_rpc?branch=serde-1.0#5e0768bd7878aeae37569ac8e4cba50392393e13"
dependencies = [
"futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"rustdt_util 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustdt_util"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ryu"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_derive"
version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_json"
version = "1.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "smallvec"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "syn"
version = "0.15.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syn"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-bidi"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-normalization"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-xid"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-xid"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "url"
version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "url_serde"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "vscode-mc-shader"
version = "0.1.0"
dependencies = [
"rust_lsp 0.6.0 (git+https://github.com/Strum355/RustLSP)",
"serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)",
]
[metadata]
"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
"checksum futures 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef"
"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
"checksum itoa 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
"checksum languageserver-types 0.54.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c511f9ff7488a97fe86ca0f3a020e2515ea0e684fc0048ce9821a9e2f851071a"
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
"checksum num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "eafd0b45c5537c3ba526f79d3e75120036502bebacbb3f3220914067ce39dbf2"
"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
"checksum proc-macro2 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548"
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
"checksum rust_lsp 0.6.0 (git+https://github.com/Strum355/RustLSP)" = "<none>"
"checksum rustdt-json_rpc 0.3.0 (git+https://github.com/strager/rustdt-json_rpc?branch=serde-1.0)" = "<none>"
"checksum rustdt_util 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7cfffa8a89d8758be2dd5605c5fc62bce055af2491ebf3ce953d4d31512c59fd"
"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
"checksum serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449"
"checksum serde_derive 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)" = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64"
"checksum serde_json 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "9371ade75d4c2d6cb154141b9752cf3781ec9c05e0e5cf35060e1e70ee7b9c25"
"checksum smallvec 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5c2fb2ec9bcd216a5b0d0ccf31ab17b5ed1d627960edff65bbe95d3ce221cefc"
"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
"checksum syn 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5"
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
"checksum unicode-normalization 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
"checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea"

11
server/Cargo.toml Normal file
View file

@ -0,0 +1,11 @@
[package]
name = "vscode-mc-shader"
version = "0.1.0"
authors = ["Noah Santschi-Cooney <noah@santschi-cooney.ch>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rust_lsp = { git = "https://github.com/Strum355/RustLSP" }
serde_json = "1.0.48"

132
server/package-lock.json generated
View file

@ -1,132 +0,0 @@
{
"name": "vscode-mc-shader-server",
"version": "0.8.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@types/adm-zip": {
"version": "0.4.32",
"resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.4.32.tgz",
"integrity": "sha512-hv1O7ySn+XvP5OeDQcJFWwVb2v+GFGO1A9aMTQ5B/bzxb7WW21O8iRhVdsKKr8QwuiagzGmPP+gsUAYZ6bRddQ==",
"requires": {
"@types/node": "*"
}
},
"@types/node": {
"version": "12.7.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.1.tgz",
"integrity": "sha512-aK9jxMypeSrhiYofWWBf/T7O+KwaiAHzM4sveCdWPn71lzUSMimRnKzhXDKfKwV1kWoBo2P1aGgaIYGLf9/ljw=="
},
"@types/node-fetch": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.0.tgz",
"integrity": "sha512-TLFRywthBgL68auWj+ziWu+vnmmcHCDFC/sqCOQf1xTz4hRq8cu79z8CtHU9lncExGBsB8fXA4TiLDLt6xvMzw==",
"requires": {
"@types/node": "*"
}
},
"adm-zip": {
"version": "0.4.13",
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.13.tgz",
"integrity": "sha512-fERNJX8sOXfel6qCBCMPvZLzENBEhZTzKqg6vrOW5pvoEaQuJhRU4ndTAh6lHOxn1I6jnz2NHra56ZODM751uw=="
},
"error-stack-parser": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-1.3.6.tgz",
"integrity": "sha1-4Oc7k+QXE40c18C3RrGkoUhUwpI=",
"requires": {
"stackframe": "^0.3.1"
}
},
"node-fetch": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
"integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
},
"source-map": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz",
"integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI="
},
"stack-generator": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/stack-generator/-/stack-generator-1.1.0.tgz",
"integrity": "sha1-NvapIHUabBD0maE8Msu19RoLiyU=",
"requires": {
"stackframe": "^1.0.2"
},
"dependencies": {
"stackframe": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.0.4.tgz",
"integrity": "sha512-to7oADIniaYwS3MhtCa/sQhrxidCCQiF/qp4/m5iN3ipf0Y7Xlri0f6eG29r08aL7JYl8n32AF3Q5GYBZ7K8vw=="
}
}
},
"stackframe": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/stackframe/-/stackframe-0.3.1.tgz",
"integrity": "sha1-M6qE8Rd6VUjIk1Uzy/6zQgl19aQ="
},
"stacktrace-gps": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/stacktrace-gps/-/stacktrace-gps-2.4.4.tgz",
"integrity": "sha1-acgn6dbW9Bz0ONfxleLjy/zyjEQ=",
"requires": {
"source-map": "0.5.6",
"stackframe": "~0.3"
}
},
"stacktrace-js": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/stacktrace-js/-/stacktrace-js-1.3.1.tgz",
"integrity": "sha1-Z8qyWJr1xBe5Yvc2mUAne7O2oYs=",
"requires": {
"error-stack-parser": "^1.3.6",
"stack-generator": "^1.0.7",
"stacktrace-gps": "^2.4.3"
}
},
"typescript-logging": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/typescript-logging/-/typescript-logging-0.6.3.tgz",
"integrity": "sha512-0zDqwjZ7KCvRobh3tXRel4IYU95iqThlsKxPeqxUmDBmhXO695LrTHvwgg9CjAPVqftSvL8ZPRcSAPT3i5DkLQ==",
"requires": {
"stacktrace-js": "1.3.1"
}
},
"vscode-jsonrpc": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.6.2.tgz",
"integrity": "sha512-T24Jb5V48e4VgYliUXMnZ379ItbrXgOimweKaJshD84z+8q7ZOZjJan0MeDe+Ugb+uqERDVV8SBmemaGMSMugA=="
},
"vscode-languageserver": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-4.4.2.tgz",
"integrity": "sha512-61y8Raevi9EigDgg9NelvT9cUAohiEbUl1LOwQQgOCAaNX62yKny/ddi0uC+FUTm4CzsjhBu+06R+vYgfCYReA==",
"requires": {
"vscode-languageserver-protocol": "^3.10.3",
"vscode-uri": "^1.0.5"
}
},
"vscode-languageserver-protocol": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.12.0.tgz",
"integrity": "sha512-evY6hmyzLnwQrqlQWPrNBq1z8wrSNjLesmgPzeS6Zv11mVS5UJRel26hbM/DH5tHdn45huNzRW0eFHRmIm8LpA==",
"requires": {
"vscode-jsonrpc": "^3.6.2",
"vscode-languageserver-types": "^3.12.0"
}
},
"vscode-languageserver-types": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.12.0.tgz",
"integrity": "sha512-UxqnpzBToPO7Mi2tr/s5JeyPOSKSJtLB8lIdxCg9ZNdvP2cU8wS7iTDtwQKz91Ne4CUmTdf85ddR5SIZKXmMjQ=="
},
"vscode-uri": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz",
"integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww=="
}
}
}

View file

@ -1,25 +0,0 @@
{
"name": "vscode-mc-shader-server",
"description": "A Language Server for linting/etc Minecraft GLSL Shaders",
"version": "0.8.0",
"author": "Noah Santschi-Cooney (Strum355)",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/Strum355/vscode-mc-shader"
},
"engines": {
"node": "*"
},
"dependencies": {
"@types/adm-zip": "^0.4.32",
"@types/node-fetch": "^2.5.0",
"adm-zip": "^0.4.13",
"node-fetch": "^2.6.0",
"typescript-logging": "^0.6.3",
"vscode-languageserver": "^4.4.2"
},
"scripts": {
"lint": "tslint -c ../tslint.json 'src/**/*.ts'"
}
}

View file

@ -1,39 +0,0 @@
export namespace Comment {
export enum State {
No,
Single,
Multi
}
export function update(line: string, state: State): [State, string] {
for (let i = 0; i < line.length; i++) {
if (state === State.No && line[i] === '/' && line[i + 1] === '*') {
state = State.Multi
line = empty(i, line, true)
i++
} else if (state === State.No && line[i] === '/' && line[i + 1] === '/' && line[i - 1] !== '*') {
// TODO early out here
state = State.Single
line = empty(i, line, true)
i++
} else if (state === State.Multi && line[i] === '*' && line[i + 1] === '/') {
state = State.No
// inefficient, try to aggregate it
line = empty(i, line, true)
i++
}
if (state === State.Multi || state === State.Single) {
line = empty(i, line, false)
}
}
if (state === State.Single) state = State.No
return [state, line]
}
function empty(i: number, line: string, twice: boolean): string {
line = line.substr(0, i) + ' ' + line.substr(i + 1)
if (twice) line = line.substr(0, i + 1) + ' ' + line.substr(i + 3)
return line
}
}

View file

@ -1,363 +0,0 @@
import { CompletionItem, CompletionItemKind } from 'vscode-languageserver'
const value = CompletionItemKind.Value
export const completions: CompletionItem[] = [
{
label: 'heldItemId',
detail: '<int> held item ID (main hand)'
},
{
label: 'heldBlockLightValue',
detail: '<int> held item light value (main hand)'
},
{
label: 'heldItemId2',
detail: '<int> held item ID (off hand)'
},
{
label: 'heldBlockLightValue2',
detail: '<int> held item light value (off hand)'
},
{
label: 'fogMode',
detail: '<int> GL_LINEAR, GL_EXP or GL_EXP2'
},
{
label: 'fogColor',
detail: '<vec3> r, g, b'
},
{
label: 'skyColor',
detail: '<vec3> r, g, b'
},
{
label: 'worldTime',
detail: '<int> <ticks> = worldTicks % 24000'
},
{
label: 'worldDay',
detail: '<int> <days> = worldTicks / 24000'
},
{
label: 'moonPhase',
detail: '<int> 0-7'
},
{
label: 'frameCounter',
detail: '<int> Frame index (0 to 720719, then resets to 0)'
},
{
label: 'frameTime',
detail: '<float> last frame time, seconds'
},
{
label: 'frameTimeCounter',
detail: '<float> run time, seconds (resets to 0 after 3600s)'
},
{
label: 'sunAngle',
detail: '<float> 0.0-1.0'
},
{
label: 'shadowAngle',
detail: '<float> 0.0-1.0'
},
{
label: 'rainStrength',
detail: '<float> 0.0-1.0'
},
{
label: 'aspectRatio',
detail: '<float> viewWidth / viewHeight'
},
{
label: 'viewWidth',
detail: '<float> viewWidth'
},
{
label: 'viewHeight',
detail: '<float> viewHeight'
},
{
label: 'near',
detail: '<float> near viewing plane distance'
},
{
label: 'far',
detail: '<float> far viewing plane distance'
},
{
label: 'sunPosition',
detail: '<vec3> sun position in eye space'
},
{
label: 'moonPosition',
detail: '<vec3> moon position in eye space'
},
{
label: 'shadowLightPosition',
detail: '<vec3> shadow light (sun or moon) position in eye space'
},
{
label: 'upPosition',
detail: '<vec3> direction up'
},
{
label: 'cameraPosition',
detail: '<vec3> camera position in world space'
},
{
label: 'previousCameraPosition',
detail: '<vec3> last frame cameraPosition'
},
{
label: 'gbufferModelView',
detail: '<mat4> modelview matrix after setting up the camera transformations'
},
{
label: 'gbufferModelViewInverse',
detail: '<mat4> inverse gbufferModelView'
},
{
label: 'gbufferPreviousModelView',
detail: '<mat4> last frame gbufferModelView'
},
{
label: 'gbufferProjection',
detail: '<mat4> projection matrix when the gbuffers were generated'
},
{
label: 'gbufferProjectionInverse',
detail: '<mat4> inverse gbufferProjection'
},
{
label: 'gbufferPreviousProjection',
detail: '<mat4> last frame gbufferProjection'
},
{
label: 'shadowProjection',
detail: '<mat4> projection matrix when the shadow map was generated'
},
{
label: 'shadowProjectionInverse',
detail: '<mat4> inverse shadowProjection'
},
{
label: 'shadowModelView',
detail: '<mat4> modelview matrix when the shadow map was generated'
},
{
label: 'shadowModelViewInverse',
detail: '<mat4> inverse shadowModelView'
},
{
label: 'wetness',
detail: '<float> rainStrength smoothed with wetnessHalfLife or drynessHalfLife'
},
{
label: 'eyeAltitude',
detail: '<float> view entity Y position'
},
{
label: 'eyeBrightness',
detail: '<ivec2> x = block brightness, y = sky brightness, light 0-15 = brightness 0-240'
},
{
label: 'eyeBrightnessSmooth',
detail: '<ivec2> eyeBrightness smoothed with eyeBrightnessHalflife'
},
{
label: 'terrainTextureSize',
detail: '<ivec2> not used'
},
{
label: 'terrainIconSize',
detail: '<int> not used'
},
{
label: 'isEyeInWater',
detail: '<int> 1 = camera is in water, 2 = camera is in lava'
},
{
label: 'nightVision',
detail: '<float> night vision (0.0-1.0)'
},
{
label: 'blindness',
detail: '<float> blindness (0.0-1.0)'
},
{
label: 'screenBrightness',
detail: '<float> screen brightness (0.0-1.0)'
},
{
label: 'hideGUI',
detail: '<int> GUI is hidden'
},
{
label: 'centerDepthSmooth',
detail: '<float> centerDepth smoothed with centerDepthSmoothHalflife'
},
{
label: 'atlasSize',
detail: '<ivec2> texture atlas size (only set when the atlas texture is bound)'
},
{
label: 'entityColor',
detail: '<vec4> entity color multiplier (entity hurt, creeper flashing when exploding)'
},
{
label: 'entityId',
detail: '<int> entity ID'
},
{
label: 'blockEntityId',
detail: '<int> block entity ID (block ID for the tile entity)'
},
{
label: 'blendFunc',
detail: '<ivec4> blend function (srcRGB, dstRGB, srcAlpha, dstAlpha)'
},
{
label: 'texture',
detail: '<sampler2D>'
},
{
label: 'lightmap',
detail: '<sampler2D>'
},
{
label: 'normals',
detail: '<sampler2D>'
},
{
label: 'specular',
detail: '<sampler2D>'
},
{
label: 'shadow',
detail: '<sampler2D> waterShadowEnabled ? 5 : 4'
},
{
label: 'watershadow',
detail: '<sampler2D>'
},
{
label: 'shadowtex0',
detail: '<sampler2D>'
},
{
label: 'shadowtex1',
detail: '<sampler2D>'
},
{
label: 'depthtex0',
detail: '<sampler2D>'
},
{
label: 'gaux1',
detail: '<sampler2D> 7 <custom texture or output from deferred programs>'
},
{
label: 'gaux2',
detail: '<sampler2D> 8 <custom texture or output from deferred programs>'
},
{
label: 'gaux3',
detail: '<sampler2D> 9 <custom texture or output from deferred programs>'
},
{
label: 'gaux4',
detail: '<sampler2D> 10 <custom texture or output from deferred programs>'
},
{
label: 'depthtex1',
detail: '<sampler2D>'
},
{
label: 'shadowcolor',
detail: '<sampler2D>'
},
{
label: 'shadowcolor0',
detail: '<sampler2D>'
},
{
label: 'shadowcolor1',
detail: '<sampler2D>'
},
{
label: 'noisetex',
detail: '<sampler2D>'
},
{
label: 'tex',
detail: '<sampler2D>'
},
{
label: 'gcolor',
detail: '<sampler2D>'
},
{
label: 'gdepth',
detail: '<sampler2D>'
},
{
label: 'gnormal',
detail: '<sampler2D>'
},
{
label: 'composite',
detail: '<sampler2D>'
},
{
label: 'colortex0',
detail: '<sampler2D>'
},
{
label: 'colortex1',
detail: '<sampler2D>'
},
{
label: 'colortex2',
detail: '<sampler2D>'
},
{
label: 'colortex3',
detail: '<sampler2D>'
},
{
label: 'colortex4',
detail: '<sampler2D>'
},
{
label: 'colortex5',
detail: '<sampler2D>'
},
{
label: 'colortex6',
detail: '<sampler2D>'
},
{
label: 'colortex7',
detail: '<sampler2D>'
},
{
label: 'gdepthtex',
detail: '<sampler2D>'
},
{
label: 'depthtex2',
detail: '<sampler2D>'
},
{
label: 'depthtex3',
detail: '<type> depthBuffers = 4'
}
]
for (let i = 1; i < completions.length + 1; i++) {
completions[i - 1].data = i
completions[i - 1].kind = value
}

View file

@ -1,99 +0,0 @@
import { connection } from './server'
import { serverLog as log } from './logging'
import { dirname } from 'path'
import { DidChangeConfigurationParams } from 'vscode-languageserver'
import { GLSLangProvider } from './glslangValidator'
const url = {
'win32': 'https://github.com/KhronosGroup/glslang/releases/download/master-tot/glslang-master-windows-x64-Release.zip',
'linux': 'https://github.com/KhronosGroup/glslang/releases/download/master-tot/glslang-master-linux-Release.zip',
'darwin': 'https://github.com/KhronosGroup/glslang/releases/download/master-tot/glslang-master-osx-Release.zip'
}
export let glslangReady = false
export class ConfigProvider {
private _config: Config
private _onChange: (settings: Config) => void
private _glslang: GLSLangProvider
public constructor(func?: (confProv: ConfigProvider, settings: Config) => void) {
this._config = {
shaderpacksPath: '',
glslangValidatorPath: ''
}
if (!func) {
this._onChange = (settings: Config) => {
onConfigChange(this, settings)
}
} else {
this._onChange = (settings: Config) => {
func(this, settings)
}
}
}
public set config(c: Config) {
Object.assign(this._config, c)
}
public get config(): Config {
return this._config
}
public set onChange(func: (confProv: ConfigProvider, settings: Config) => void) {
this._onChange = (settings: Config) => {
func(this, settings)
}
}
public onConfigChange = (change: DidChangeConfigurationParams) => {
this._onChange(change.settings.mcglsl as Config)
}
public set glslang(glslang: GLSLangProvider) {
this._glslang = glslang
}
public get glslang(): GLSLangProvider {
return this._glslang
}
}
interface Config {
shaderpacksPath: string
glslangValidatorPath: string
}
let supress = false
async function onConfigChange(confProv: ConfigProvider, old: Config) {
if (!confProv.config == undefined &&
old.shaderpacksPath === confProv.config.shaderpacksPath &&
old.glslangValidatorPath === confProv.config.glslangValidatorPath) return
confProv.config = {shaderpacksPath: old['shaderpacksPath'], glslangValidatorPath: old['glslangValidatorPath']}
log.debug(() => 'new config: ' + JSON.stringify(old))
log.debug(() => 'old config: ' + JSON.stringify(confProv.config))
if (confProv.config.shaderpacksPath === '' || confProv.config.shaderpacksPath.replace(dirname(confProv.config.shaderpacksPath), '') !== '/shaderpacks') {
if (supress) return
log.error(() => `shaderpack path '${confProv.config.shaderpacksPath.replace(dirname(confProv.config.shaderpacksPath), '')}' not set or doesn't end in 'shaderpacks'`, null)
supress = true
const clicked = await connection.window.showErrorMessage(
'mcglsl.shaderpacksPath is not set or doesn\'t end in \'shaderpacks\'. Please set it in your settings.',
{title: 'Supress'}
)
supress = (clicked && clicked.title === 'Supress') ? true : false
return
}
if (!confProv.glslang.testExecutable()) {
await confProv.glslang.promptDownload()
} else {
glslangReady = true
}
}

View file

@ -1,9 +0,0 @@
export type ShaderFileExtension = '.fsh' | '.gsh' | '.vsh'
export type ShaderFileType = 'frag' | 'geom' | 'vert'
export const extensionMap = new Map<ShaderFileExtension, ShaderFileType>([
['.fsh', 'frag'],
['.gsh', 'geom'],
['.vsh', 'vert'],
])

View file

@ -1,100 +0,0 @@
import { ConfigProvider } from './config'
import { execSync } from 'child_process'
import { extensionMap, ShaderFileExtension } from './fileTypes'
import * as path from 'path'
import fetch from 'node-fetch';
import { platform } from 'os';
import * as unzip from 'adm-zip'
import { createWriteStream } from 'fs'
import { writeFileSync, fstat } from 'fs';
import { connection } from './server';
import { glslProviderLog as log } from './logging';
const url = {
'win32': 'https://github.com/KhronosGroup/glslang/releases/download/master-tot/glslang-master-windows-x64-Release.zip',
'linux': 'https://github.com/KhronosGroup/glslang/releases/download/master-tot/glslang-master-linux-Release.zip',
'darwin': 'https://github.com/KhronosGroup/glslang/releases/download/master-tot/glslang-master-osx-Release.zip'
}
export class GLSLangProvider {
private _config: ConfigProvider
public constructor(c: ConfigProvider) {
this._config = c
}
public lint(document: string, fileExtension: ShaderFileExtension): string {
try {
execSync(`${this._config.config.glslangValidatorPath} --stdin -S ${extensionMap.get(fileExtension)}`, {input: document})
} catch (e) {
return e.stdout.toString()
}
}
public promptDownload = async () => {
const chosen = await connection.window.showErrorMessage(
`[mc-glsl] glslangValidator not found at: '${this._config.config.glslangValidatorPath}'.`,
{title: 'Download'},
{title: 'Cancel'}
)
if (!chosen || chosen.title !== 'Download') return
await this.installExecutable()
}
public installExecutable = async () => {
try {
const glslangBin = '/glslangValidator' + (platform() === 'win32' ? '.exe' : '')
const glslangPath = this._config.config.shaderpacksPath + glslangBin
const response = await fetch(url[platform()])
const zip = new unzip(await response.buffer())
const bin = zip.readFile('bin' + glslangBin)
writeFileSync(glslangPath, bin)
if (!this.testExecutable()) {
connection.window.showErrorMessage(
'Unexpected error occurred. Please try again'
)
return
}
// why doesnt this work????????
log.info(() => `successfully downloaded glslangValidator to ${glslangPath}`)
connection.window.showInformationMessage(
`glslangValidator has been downloaded to ${glslangPath}. Your config should be updated automatically.`
)
connection.sendNotification('update-config', glslangPath)
} catch (e) {
log.error(() => `failed downloading glslangValidator`, e)
connection.window.showErrorMessage(
`Failed to install glslangValidator: ${e}`
)
}
}
public testExecutable(glslangPath?: string): boolean {
let success = false
try {
const stdout = execSync(glslangPath || this._config.config.glslangValidatorPath, {
stdio: 'pipe',
}).toString()
success = stdout.startsWith('Usage')
} catch (e) {
success = (e.stdout.toString() as string).startsWith('Usage')
}
if (success) {
log.info(() => `glslangValidator found at ${this._config.config.glslangValidatorPath}`)
} else {
log.error(() => `glslangValidator not found at ${this._config.config.glslangValidatorPath}`, null)
}
return success
}
}

View file

@ -1,61 +0,0 @@
// can you imagine that some people out there would import a whole library just for this?
export type Pair<T, S> = {
first: T,
second: S
}
export type Node = {
parents: Map<string, Pair<number, Node>>
children: Map<string, Node>
}
export class Graph {
public nodes: Map<string, Node> = new Map()
public hasParents(uri: string): boolean {
return this.nodes.has(uri) ? this.nodes.get(uri).parents.size > 0 : false
}
public get(uri: string): Node {
if (!this.nodes.has(uri)) this.nodes.set(uri, {parents: new Map(), children: new Map()})
return this.nodes.get(uri)
}
public setParent(uri: string, parent: string, lineNum: number) {
const par: Node = this.nodes.has(parent) ? this.nodes.get(parent) : {parents: new Map(), children: new Map()}
if (this.nodes.has(uri)) {
const node = this.nodes.get(uri)
node.parents.set(parent, {first: lineNum, second: par})
par.children.set(uri, node)
} else {
const node: Node = {
parents: new Map([par].map(p => [parent, {first: lineNum, second: p}]) as [string, Pair<number, Node>][]),
children: new Map()
}
par.children.set(uri, node)
this.nodes.set(uri, node)
}
this.nodes.set(parent, par)
}
public toString(): string {
let result = ''
let start = true
this.nodes.forEach((node, key) => {
if (!start) {
key += '\n'
start = false
}
result += `${key}:\n\tchildren: `
node.children.forEach((_, key) => {
result += key + ' '
})
result + '\n\tparents: '
node.parents.forEach((_, key) => {
result += key + ' '
})
})
return result
}
}

View file

@ -1,8 +0,0 @@
import * as vsclang from 'vscode-languageserver'
import { linkLog as log} from './logging'
import { formatURI } from './utils'
export function getDocumentLinks(file: string): vsclang.DocumentLink[] {
log.debug(() => formatURI(file) + ' ' + file)
return [vsclang.DocumentLink.create(vsclang.Range.create(8, 0, 8, 32), 'file:///e:\\shaderpacks\\Sushi-Shader\\shaders\\composite1.vsh')]
}

View file

@ -1,4 +0,0 @@
export class Linter {
}

View file

@ -1,376 +0,0 @@
import { execSync } from 'child_process'
import { readFileSync, statSync } from 'fs'
import { platform } from 'os'
import * as path from 'path'
import { Diagnostic, DiagnosticSeverity, Range } from 'vscode-languageserver'
import { Comment } from './comment'
import { Graph } from './graph'
import { linterLog } from './logging'
import { connection } from './server'
import { formatURI, getDocumentContents, trimPath } from './utils'
const reDiag = /^(ERROR|WARNING): ([^?<>*|"]+?):(\d+): (?:'.*?' : )?(.+)\r?/
const reVersion = /#version [\d]{3}/
const reInclude = /^(?:\s)*?(?:#include) "(.+)"\r?/
const reIncludeExt = /#extension GL_GOOGLE_include_directive ?: ?require/
const include = '#extension GL_GOOGLE_include_directive : require'
export const win = platform() === 'win32'
const errorFilters = [
/stdin/,
/(No code generated)/,
/(compilation terminated)/,
/Could not process include directive for header name:/,
]
export const includeGraph = new Graph()
type IncludeObj = {
lineNum: number,
lineNumTopLevel: number,
path: string,
parent: string,
match: RegExpMatchArray
}
type ErrorMatch = {
type: DiagnosticSeverity,
file: string,
line: number,
msg: string,
}
type LinesProcessingInfo = {
total: number,
comment: Comment.State,
parStack: string[],
count: number[],
}
const tokens = new Map([
['SEMICOLON', ';'],
['COMMA', ','],
['COLON', ':'],
['EQUAL', '='],
['LEFT_PAREN', '('],
['RIGHT_PAREN', ')'],
['DOT', '.'],
['BANG', '!'],
['DASH', '-'],
['TILDE', '~'],
['PLUS', '+'],
['STAR', '*'],
['SLASH', '/'],
['PERCENT', '%'],
['LEFT_ANGEL', '<'],
['RIGHT_ANGEL', '>'],
['VERICAL_BAR', '|'],
['CARET', '^'],
['AMPERSAND', '&'],
['QUESTION', '?'],
['[LEFT_BRACKET', '['],
['RIGHT_BRACKET', ']'],
['LEFT_BRACE', '{'],
['RIGHT_BRACE', '}'],
])
export function preprocess(lines: string[], docURI: string) {
const hasDirective = includeDirective(lines)
const diagnostics = new Map<string, Diagnostic[]>()
processIncludes(lines, [docURI], new Set<IncludeObj>(), diagnostics, hasDirective)
//const includeMap = new Map<string, IncludeObj>(Array.from(allIncludes).map(obj => [obj.path, obj]) as [string, IncludeObj][])
lint(docURI, lines, diagnostics, hasDirective)
}
function includeDirective(lines: string[]): boolean {
if (lines.findIndex(x => reIncludeExt.test(x)) > -1) {
linterLog.info(() => 'include directive found')
return true
}
let hasDirective = true
linterLog.info(() => 'include directive not found')
hasDirective = false
for (let i = 0; i < lines.length; i++) {
const line = lines[i]
if (reVersion.test(line)) {
linterLog.info(() => 'found version on line ' + (i + 1))
lines.splice(i + 1, 0, include)
break
}
/* if (i === lines.length - 1) {
linterLog.warn(() => `no version found for ${docURI}. inserting at top`)
lines.splice(0, 0, include)
break
} */
}
return hasDirective
}
const buildIncludeGraph = (inc: IncludeObj) => includeGraph.setParent(inc.path, inc.parent, inc.lineNum)
function processIncludes(lines: string[], incStack: string[], allIncludes: Set<IncludeObj>, diagnostics: Map<string, Diagnostic[]>, hasDirective: boolean) {
const parent = incStack[incStack.length - 1]
const includes = getIncludes(parent, lines)
includes.forEach(i => allIncludes.add(i))
includeGraph.nodes.get(parent).children.forEach((node, uri) => {
if (!includes.has(uri)) {
includeGraph.nodes.get(parent).children.delete(uri)
node.parents.delete(parent)
}
})
const includeList = Array.from(includes.values())
if (includeList.length > 0) {
linterLog.info(() => `${trimPath(parent)} has ${includeList.length} include(s). [${includeList.map(i => '\n\t\t' + trimPath(i.path))}\n\t]`)
includeList.reverse().forEach(inc => {
buildIncludeGraph(inc)
mergeInclude(inc, lines, incStack, diagnostics, hasDirective)
})
// recursively check for more includes to be merged
processIncludes(lines, incStack, allIncludes, diagnostics, hasDirective)
}
}
function getIncludes(uri: string, lines: string[]) {
const lineInfo: LinesProcessingInfo = {
total: 0,
comment: Comment.State.No,
parStack: [uri],
count: [0],
}
return lines.reduce<Map<string, IncludeObj>>((out, line, i) => processLine(out, line, lines, i, lineInfo), new Map())
}
// TODO can surely be reworked
function processLine(includes: Map<string, IncludeObj>, line: string, lines: string[], i: number, linesInfo: LinesProcessingInfo): Map<string, IncludeObj> {
const updated = Comment.update(line, linesInfo.comment)
linesInfo.comment = updated[0]
if (updated[1] !== line) linterLog.debug(() => `change:\n\t'${line}'\n\t'${updated[1]}'`)
line = updated[1]
lines[i] = line
linesInfo.count[linesInfo.count.length - 1]++
linesInfo.total++
if (linesInfo.comment) return includes
if (line.startsWith('#line')) {
const inc = line.slice(line.indexOf('"') + 1, line.lastIndexOf('"'))
if (inc.length + 1 === line.length) lines[i] = ''
if (inc === linesInfo.parStack[linesInfo.parStack.length - 2]) {
linesInfo.count.pop()
linesInfo.parStack.pop()
} else {
linesInfo.count.push(0)
linesInfo.parStack.push(inc)
}
return includes
}
const match = line.match(reInclude)
if (match) {
includes.set(
formatURI(absPath(linesInfo.parStack[linesInfo.parStack.length - 1], match[1])),
{
path: formatURI(absPath(linesInfo.parStack[linesInfo.parStack.length - 1], match[1])),
lineNum: linesInfo.count[linesInfo.count.length - 1] - 1,
lineNumTopLevel: linesInfo.total - 1,
parent: formatURI(linesInfo.parStack[linesInfo.parStack.length - 1]),
match
}
)
}
return includes
}
function ifInvalidFile(inc: IncludeObj, lines: string[], incStack: string[], diagnostics: Map<string, Diagnostic[]>, hasDirective: boolean) {
const msg = `${trimPath(inc.path)} is missing or an invalid file.`
linterLog.error(msg, null)
const file = incStack[incStack.length - 1]
const diag: Diagnostic = {
severity: DiagnosticSeverity.Error,
range: calcRange(inc.lineNum - ((!hasDirective && includeGraph.get(file).parents.size === 0) ? 1 : 0), file),
message: msg,
source: 'mc-glsl'
}
diagnostics.set(inc.parent, [...(diagnostics.get(inc.parent) || []), diag])
lines[inc.lineNumTopLevel] = lines[inc.lineNumTopLevel].replace(reInclude, '')
const error: ErrorMatch = {
type: DiagnosticSeverity.Error,
line: inc.lineNum,
msg, file,
}
propogateDiagnostic(error, diagnostics, hasDirective)
}
function mergeInclude(inc: IncludeObj, lines: string[], incStack: string[], diagnostics: Map<string, Diagnostic[]>, hasDirective: boolean) {
try {
const stats = statSync(inc.path)
if (!stats.isFile()) {
const err = new Error()
err['code'] = 'ENOENT'
throw err
}
} catch (e) {
if (e.code === 'ENOENT') {
ifInvalidFile(inc, lines, incStack, diagnostics, hasDirective)
return
}
throw e
}
const dataLines = readFileSync(inc.path).toString().split('\n')
// if the includes parent is the top level (aka where the include directive is placed)
// and we had to manually add the directive, - 1 the line number to account for the extra line
if (inc.parent === incStack[0] && !hasDirective) inc.lineNum = inc.lineNum - 1
incStack.push(inc.path)
// add #line indicating we are entering a new include block
lines[inc.lineNumTopLevel] = `#line 0 "${formatURI(inc.path)}"`
// merge the lines of the file into the current document
lines.splice(inc.lineNumTopLevel + 1, 0, ...dataLines)
// add the closing #line indicating we're re-entering a block a level up
lines.splice(inc.lineNumTopLevel + 1 + dataLines.length, 0, `#line ${inc.lineNum + 1} "${inc.parent}"`)
}
function lint(docURI: string, lines: string[], diagnostics: Map<string, Diagnostic[]>, hasDirective: boolean) {
console.log(lines.join('\n'))
let out: string = ''
try {
//execSync(`${conf.glslangPath} --stdin -S ${ext.get(path.extname(docURI))}`, {input: lines.join('\n')})
} catch (e) {
out = e.stdout.toString()
}
if (!diagnostics.has(docURI)) diagnostics.set(docURI, [])
includeGraph.nodes.forEach((node, key) => {
if (!diagnostics.has(key)) diagnostics.set(key, [])
})
processErrors(out, docURI, diagnostics, hasDirective)
diagnostics.forEach((diags, uri) => {
if (diags.length === 0) return
const errors = diags.filter(d => d.severity === DiagnosticSeverity.Error)
const warnings = diags.filter(d => d.severity === DiagnosticSeverity.Warning)
linterLog.info(() => `found ${errors.length} error(s) and ${warnings.length} warning(s) for ${trimPath(uri)}`)
})
const diagsList = daigsArray(diagnostics)
if (diagsList.filter(d => d.diag.length > 0).length === 0) linterLog.info(() => 'no errors found')
//console.log(JSON.stringify(diagsList.filter(d => d.diag.length > 0), null, 2))
diagsList.forEach(d => {
if (win) {
const drive = d.uri[7]
d.uri = d.uri.replace(`file://${drive}:`, `file:///${drive.toLowerCase()}%3A`)
}
connection.sendDiagnostics({uri: d.uri, diagnostics: d.diag})
})
}
function processErrors(out: string, docURI: string, diagnostics: Map<string, Diagnostic[]>, hasDirective: boolean) {
linterLog.debug(() => out.split('\n').filter(s => s.length > 2).join('\n'))
filterMatches(out).forEach(match => {
const error: ErrorMatch = {
type: errorType(match[1]),
file: match[2],
line: parseInt(match[3]),
msg: match[4]
}
const fileName = error.file.length - 1 ? error.file : docURI
const diag: Diagnostic = {
severity: error.type,
//range: calcRange(error.line - 1, fileName),
range: calcRange(error.line - ((!hasDirective && includeGraph.get(fileName).parents.size === 0) ? 2 : 1), fileName),
message: `Line ${error.line + ((!hasDirective && includeGraph.get(fileName).parents.size === 0) ? 2 : 1)} ${replaceWords(error.msg)}`,
source: 'mc-glsl'
}
diagnostics.get(fileName).push(diag)
// if is an include, highlight an error in the parents line of inclusion
propogateDiagnostic(error, diagnostics, hasDirective)
})
}
function propogateDiagnostic(error: ErrorMatch, diagnostics: Map<string, Diagnostic[]>, hasDirective: boolean, parentURI?: string) {
includeGraph.get(parentURI || error.file).parents.forEach((pair, parURI) => {
const diag: Diagnostic = {
severity: error.type,
range: calcRange(pair.first - ((!hasDirective && pair.second.parents.size === 0) ? 1 : 0), parURI),
message: `Line ${error.line + 1} ${trimPath(error.file)} ${replaceWords(error.msg)}`,
source: 'mc-glsl'
}
if (!diagnostics.has(parURI)) diagnostics.set(parURI, [])
diagnostics.get(parURI).push(diag)
if (pair.second.parents.size > 0) {
propogateDiagnostic(error, diagnostics, hasDirective, parURI)
}
})
}
const replaceWords = (msg: string) => Array.from(tokens.entries()).reduce((acc, [key, value]) => acc.replace(key, value), msg)
const errorType = (error: string) => error === 'ERROR' ? DiagnosticSeverity.Error : DiagnosticSeverity.Warning
const daigsArray = (diags: Map<string, Diagnostic[]>) => Array.from(diags).map(kv => ({uri: 'file://' + kv[0], diag: kv[1]}))
const filterMatches = (output: string) => output
.split('\n')
.filter(s => s.length > 1 && !errorFilters.some(reg => reg.test(s)))
.map(s => s.match(reDiag))
.filter(match => match && match.length === 5)
function calcRange(lineNum: number, uri: string) {
linterLog.debug(() => `calculating range for ${trimPath(uri)} at L${lineNum + 1}, index ${lineNum}`)
const lines = getDocumentContents(uri).split('\n')
const line = lines[Math.min(Math.max(lineNum, 0), lines.length - 1)]
const startOfLine = line.length - line.trimLeft().length
const endOfLine = line.trimRight().length + 1
//const endOfLine = line.slice(0, line.indexOf('//')).trimRight().length + 2
return Range.create(lineNum, startOfLine, lineNum, endOfLine)
}
function absPath(currFile: string, includeFile: string) {
if (!currFile.startsWith(conf.shaderpacksPath) || conf.shaderpacksPath === '') {
connection.window.showErrorMessage(`Shaderpacks path may not be correct. Current file is in '${currFile}' but the path is set to '${conf.shaderpacksPath}'`)
return ''
}
// TODO add explanation comment
if (includeFile.charAt(0) === '/' || (includeFile.charAt(0) === '.' && includeFile.charAt(1) === '.')) {
const shaderPath = trimPath(currFile).split('/').slice(0, 3).join('/')
return path.join(conf.shaderpacksPath, shaderPath, includeFile)
} /* else if (includeFile.charAt(0) === '.' && includeFile.charAt(1) === '.') {
} */
return path.join(path.dirname(currFile), includeFile)
}

View file

@ -1,11 +0,0 @@
import { Category, CategoryConfiguration, CategoryServiceFactory, LogLevel } from 'typescript-logging'
CategoryServiceFactory.setDefaultConfiguration(new CategoryConfiguration(LogLevel.Debug))
export const linterLog = new Category('linter')
export const completionLog = new Category('completion')
export const serverLog = new Category('server')
export const linkLog = new Category('links')
export const glslProviderLog = new Category('glslangProvider')
export const uriLog = new Category('uri')

147
server/src/main.rs Normal file
View file

@ -0,0 +1,147 @@
use rust_lsp::lsp::*;
use rust_lsp::ls_types::*;
use rust_lsp::jsonrpc::*;
use rust_lsp::jsonrpc::method_types::*;
use serde_json::Value;
use std::io;
use std::thread;
use std::net::TcpListener;
use std::net::TcpStream;
fn main() {
let listener = TcpListener::bind(("127.0.0.1", 0)).unwrap();
let local_addr = listener.local_addr().unwrap();
let server_listener = thread::spawn(|| {
tcp_server(listener)
});
let stream = TcpStream::connect(local_addr).unwrap();
let out_stream = stream.try_clone().expect("Failed to clone stream");
let mut endpoint = LSPEndpoint::create_lsp_output_with_output_stream(|| { out_stream });
server_rpc_handle(&mut endpoint);
}
fn tcp_server(listener: TcpListener) {
for stream in listener.incoming() {
let stream = stream.expect("Failed to open incoming stream");
let conn_handler = thread::spawn(move|| {
handle_connection(stream)
});
// Only listen to first connection, so that this example can be run as a test
conn_handler.join().unwrap();
break;
}
drop(listener);
}
fn handle_connection(stream: TcpStream) {
let out_stream = stream.try_clone().expect("Failed to clone stream");
let endpoint = LSPEndpoint::create_lsp_output_with_output_stream(|| { out_stream });
let ls = MinecraftShaderLanguageServer { endpoint: endpoint.clone() };
let mut input = io::BufReader::new(stream);
LSPEndpoint::run_server_from_input(&mut input, endpoint, ls);
}
struct MinecraftShaderLanguageServer {
endpoint: Endpoint,
}
impl MinecraftShaderLanguageServer {
pub fn error_not_available<DATA>(data : DATA) -> MethodError<DATA> {
let msg = "Functionality not implemented.".to_string();
MethodError::<DATA> { code : 1, message : msg, data : data }
}
}
impl LanguageServerHandling for MinecraftShaderLanguageServer {
fn initialize(&mut self, _: InitializeParams, completable: MethodCompletable<InitializeResult, InitializeError>) {
let capabilities = ServerCapabilities::default();
completable.complete(Ok(InitializeResult { capabilities : capabilities }))
}
fn shutdown(&mut self, _: (), completable: LSCompletable<()>) {
completable.complete(Ok(()));
}
fn exit(&mut self, _: ()) {
self.endpoint.request_shutdown();
}
fn workspace_change_configuration(&mut self, _: DidChangeConfigurationParams) {}
fn did_open_text_document(&mut self, _: DidOpenTextDocumentParams) {}
fn did_change_text_document(&mut self, _: DidChangeTextDocumentParams) {}
fn did_close_text_document(&mut self, _: DidCloseTextDocumentParams) {}
fn did_save_text_document(&mut self, _: DidSaveTextDocumentParams) {}
fn did_change_watched_files(&mut self, _: DidChangeWatchedFilesParams) {}
fn completion(&mut self, _: TextDocumentPositionParams, completable: LSCompletable<CompletionList>) {
completable.complete(Err(Self::error_not_available(())));
}
fn resolve_completion_item(&mut self, _: CompletionItem, completable: LSCompletable<CompletionItem>) {
completable.complete(Err(Self::error_not_available(())));
}
fn hover(&mut self, _: TextDocumentPositionParams, completable: LSCompletable<Hover>) {
let mut endpoint = self.endpoint.clone();
thread::spawn(move || {
client_rpc_handle(&mut endpoint).telemetry_event(Value::Null)
.unwrap();
let hover_str = "hover_text".to_string();
let hover = Hover { contents: HoverContents::Array(vec![MarkedString::String(hover_str)]), range: None };
completable.complete(Ok(hover));
});
}
fn signature_help(&mut self, _: TextDocumentPositionParams, completable: LSCompletable<SignatureHelp>) {
completable.complete(Err(Self::error_not_available(())));
}
fn goto_definition(&mut self, _: TextDocumentPositionParams, completable: LSCompletable<Vec<Location>>) {
completable.complete(Err(Self::error_not_available(())));
}
fn references(&mut self, _: ReferenceParams, completable: LSCompletable<Vec<Location>>) {
completable.complete(Err(Self::error_not_available(())));
}
fn document_highlight(&mut self, _: TextDocumentPositionParams, completable: LSCompletable<Vec<DocumentHighlight>>) {
completable.complete(Err(Self::error_not_available(())));
}
fn document_symbols(&mut self, _: DocumentSymbolParams, completable: LSCompletable<Vec<SymbolInformation>>) {
completable.complete(Err(Self::error_not_available(())));
}
fn workspace_symbols(&mut self, _: WorkspaceSymbolParams, completable: LSCompletable<Vec<SymbolInformation>>) {
completable.complete(Err(Self::error_not_available(())));
}
fn code_action(&mut self, _: CodeActionParams, completable: LSCompletable<Vec<Command>>) {
completable.complete(Err(Self::error_not_available(())));
}
fn code_lens(&mut self, _: CodeLensParams, completable: LSCompletable<Vec<CodeLens>>) {
completable.complete(Err(Self::error_not_available(())));
}
fn code_lens_resolve(&mut self, _: CodeLens, completable: LSCompletable<CodeLens>) {
completable.complete(Err(Self::error_not_available(())));
}
fn document_link(&mut self, _params: DocumentLinkParams, completable: LSCompletable<Vec<DocumentLink>>) {
completable.complete(Err(Self::error_not_available(())));
}
fn document_link_resolve(&mut self, _params: DocumentLink, completable: LSCompletable<DocumentLink>) {
completable.complete(Err(Self::error_not_available(())));
}
fn formatting(&mut self, _: DocumentFormattingParams, completable: LSCompletable<Vec<TextEdit>>) {
completable.complete(Err(Self::error_not_available(())));
}
fn range_formatting(&mut self, _: DocumentRangeFormattingParams, completable: LSCompletable<Vec<TextEdit>>) {
completable.complete(Err(Self::error_not_available(())));
}
fn on_type_formatting(&mut self, _: DocumentOnTypeFormattingParams, completable: LSCompletable<Vec<TextEdit>>) {
completable.complete(Err(Self::error_not_available(())));
}
fn rename(&mut self, _: RenameParams, completable: LSCompletable<WorkspaceEdit>) {
completable.complete(Err(Self::error_not_available(())));
}
}

View file

@ -1,102 +0,0 @@
import * as vsclang from 'vscode-languageserver'
import * as vsclangproto from 'vscode-languageserver-protocol'
import { completions } from './completionProvider'
import { ConfigProvider } from './config'
import { getDocumentLinks } from './linksProvider'
import { GLSLangProvider } from './glslangValidator';
const reVersion = /#version [\d]{3}/
export let connection = vsclang.createConnection(vsclang.ProposedFeatures.all)
console.log = connection.console.log.bind(connection.console)
console.error = connection.console.error.bind(connection.console)
const configProvider = new ConfigProvider()
const glslangValidator = new GLSLangProvider(configProvider)
configProvider.glslang = glslangValidator
export const documents = new vsclang.TextDocuments()
documents.listen(connection)
connection.onInitialize((_) => (
{
capabilities: {
textDocumentSync: documents.syncKind,
documentLinkProvider: {
resolveProvider: true,
},
completionProvider: {
resolveProvider: true
},
}
}
))
connection.onExit(() => {})
documents.onDidOpen((event) => lint(event.document))
documents.onDidSave((event) => lint(event.document))
// what am i saying here
// dont do this for include files, for non-include files, clear diags for all its includes. Cache this maybe
documents.onDidClose((event) => {
connection.sendDiagnostics({uri: event.document.uri, diagnostics: []})
})
//documents.onDidChangeContent(onEvent)
export function lint(document: vsclangproto.TextDocument) {
if (!glslangValidator.testExecutable()) {
}
/*
let sanitizedPath = conf.shaderpacksPath.replace(dirname(conf.shaderpacksPath), '')
if (sanitizedPath.startsWith('/shaderpacks') || glslangReady) return
const uri = formatURI(document.uri)
if (includeGraph.get(uri).parents.size > 0) {
lintBubbleDown(uri)
return
}
// i think we still need to keep this in case we havent found the root of this files include tree
const lines = document.getText().split('\n')
const hasVersion = lines.filter(l => reVersion.test(l)).length > 0
if (!hasVersion) return
try {
preprocess(document.getText().split('\n'), uri)
} catch (e) {
postError(e)
} */
}
/* function lintBubbleDown(uri: string) {
includeGraph.get(uri).parents.forEach((parent, parentURI) => {
if (parent.second.parents.size > 0) {
lintBubbleDown(parentURI)
} else {
const lines = getDocumentContents(parentURI).split('\n')
// feel like we could perhaps do better? Hope no one puts #version at the top of their includes..
if (lines.filter(l => reVersion.test(l)).length > 0) {
try {
preprocess(lines, parentURI)
} catch (e) {
postError(e)
}
}
}
})
} */
connection.onDocumentLinks((params: vsclang.DocumentLinkParams) => getDocumentLinks(params.textDocument.uri))
connection.onDidChangeConfiguration(configProvider.onConfigChange)
connection.onCompletion((textDocumentPosition: vsclang.TextDocumentPositionParams) => completions)
connection.onCompletionResolve((item: vsclang.CompletionItem): vsclang.CompletionItem => completions[item.data - 1])
connection.listen()

View file

@ -1,52 +0,0 @@
import { Category } from 'typescript-logging'
import { platform } from 'os'
import { uriLog as log } from './logging';
export function formatURI(uri: string): string {
const drive = uri[7]
uri = uri.replace(`file:///${drive.toUpperCase()}%3A`, `file://${drive}:`)
return uri.replace(/^file:\/\//, '').replace(/\\/, '/')
}
export class URI {
public static fromFileURI(uri: string): string {
log.debug(() => `normalizing ${uri}`)
if (URI.isNormalized(uri)) {
log.debug(() => `already normalized ${uri}`)
return uri
}
return ''
}
public static toFileURI(uri: string): string {
let fileURI = uri
if (!fileURI.startsWith('file:///')) {
if (/^\\[a-zA-Z]/.test(fileURI)) {
fileURI = 'file:///' + fileURI.substr(1)
} else if (fileURI.startsWith('/')) {
fileURI = 'file://' + fileURI
}
} else if (fileURI.startsWith('file://\\')) {
fileURI = fileURI.replace('file://\\', 'file:///')
} else if (/^file:\/\/[a-zA-Z]/.test(fileURI)) {
fileURI = fileURI.replace('file://', 'file:///')
}
log.debug(() => `formatted '${uri}' to '${fileURI}'`)
return fileURI
}
private static isNormalized(uri: string): boolean {
if (uri.startsWith('file://') || uri.includes('%3A')) {
return false
}
return true
}
}

View file

@ -1,26 +0,0 @@
import { readFileSync, FSWatcher, ReadStream } from 'fs'
import * as urL from 'url'
import { serverLog as log } from './logging'
import { connection, documents } from './server'
import { url } from 'inspector';
import { Readable } from 'stream';
export function postError(e: Error) {
connection.window.showErrorMessage(e.message)
log.error(() => e.message, null)
}
export function formatURI(uri: string): string {
const drive = uri[7]
uri = uri.replace(`file:///${drive.toUpperCase()}%3A`, `file://${drive}:`)
return uri.replace(/^file:\/\//, '').replace(/\\/, '/')
}
export function getDocumentContents(uri: string): string {
if (documents.keys().includes('file://' + uri)) return documents.get('file://' + uri).getText()
else return readFileSync(uri).toString()
}
/* export function trimPath(path: string): string {
return path.replace(conf.shaderpacksPath, '')
} */

View file

@ -1,17 +0,0 @@
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"outDir": "out",
"rootDir": "src",
"lib": [ "es6", "es2017", "dom" ]
},
"include": [
"src"
],
"exclude": [
"node_modules"
]
}

View file

@ -1,44 +0,0 @@
{
"defaultSeverity": "warning",
"extends": ["tslint:recommended"],
"rules": {
"quotemark": [true, "single"],
"comment-format": false,
"semicolon": [true, "never"],
"no-conditional-assignment": false,
"ordered-imports": false,
"object-literal-sort-keys": false,
"no-string-literal": false,
"array-type": false,
"interface-name": false,
"indent": [true, "spaces", 2],
"triple-equals": false,
"arrow-parens": false,
"max-classes-per-file": false,
"no-console": false,
"object-literal-key-quotes": false,
"object-literal-shorthand": {
"severity": "warning"
},
"eofline": false,
"member-ordering": false,
"interface-over-type-literal": false,
"trailing-comma": false,
"no-namespace": false,
"no-var-requires": false,
"max-line-length": {
"severity": "warning",
"options": [170]
},
"radix": false,
"no-empty": false,
"prefer-const": {
"severity": "warning"
},
"curly": [true, "ignore-same-line"],
"whitespace": false,
"no-trailing-whitespace": {
"severity": "warning"
}
}
}