mirror of
https://github.com/Strum355/mcshader-lsp.git
synced 2025-07-19 09:15:54 +00:00
Created GLSLangProvider class with API for linting and downloading glslangValidator
Moved glslang stuff from Config to GLSLangProvider. ConfigProvider invokes GLSLangValidator to prompt and download glslangValidator instead
This commit is contained in:
parent
156d76e7de
commit
41995c3f38
16 changed files with 819 additions and 607 deletions
189
client/package-lock.json
generated
189
client/package-lock.json
generated
|
@ -8,6 +8,7 @@
|
|||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
|
||||
"integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"es6-promisify": "^5.0.0"
|
||||
}
|
||||
|
@ -16,6 +17,7 @@
|
|||
"version": "6.10.2",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
|
||||
"integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fast-deep-equal": "^2.0.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
|
@ -27,6 +29,7 @@
|
|||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
|
||||
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safer-buffer": "~2.1.0"
|
||||
}
|
||||
|
@ -34,32 +37,38 @@
|
|||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
|
||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
||||
"dev": true
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
|
||||
"dev": true
|
||||
},
|
||||
"aws-sign2": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
||||
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
|
||||
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
|
||||
"dev": true
|
||||
},
|
||||
"aws4": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
|
||||
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
|
||||
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
|
||||
"dev": true
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||
"dev": true
|
||||
},
|
||||
"bcrypt-pbkdf": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
|
||||
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tweetnacl": "^0.14.3"
|
||||
}
|
||||
|
@ -68,6 +77,7 @@
|
|||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
|
@ -76,22 +86,26 @@
|
|||
"browser-stdout": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
|
||||
"integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw=="
|
||||
"integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
|
||||
"dev": true
|
||||
},
|
||||
"buffer-from": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
|
||||
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
|
||||
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
|
||||
"dev": true
|
||||
},
|
||||
"caseless": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
||||
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
|
||||
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
|
||||
"dev": true
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
|
@ -99,22 +113,26 @@
|
|||
"commander": {
|
||||
"version": "2.15.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
|
||||
"integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag=="
|
||||
"integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
|
||||
"dev": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"dev": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
||||
"dev": true
|
||||
},
|
||||
"dashdash": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
|
||||
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
|
@ -123,6 +141,7 @@
|
|||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
|
@ -130,17 +149,20 @@
|
|||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
|
||||
"dev": true
|
||||
},
|
||||
"diff": {
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
|
||||
"integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA=="
|
||||
"integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
|
||||
"dev": true
|
||||
},
|
||||
"ecc-jsbn": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
||||
"integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.1.0"
|
||||
|
@ -149,12 +171,14 @@
|
|||
"es6-promise": {
|
||||
"version": "4.2.8",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
|
||||
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
|
||||
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==",
|
||||
"dev": true
|
||||
},
|
||||
"es6-promisify": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
|
||||
"integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"es6-promise": "^4.0.3"
|
||||
}
|
||||
|
@ -162,37 +186,44 @@
|
|||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
|
||||
"dev": true
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
|
||||
"dev": true
|
||||
},
|
||||
"extsprintf": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
|
||||
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
|
||||
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
|
||||
"dev": true
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
|
||||
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk="
|
||||
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
|
||||
"dev": true
|
||||
},
|
||||
"fast-json-stable-stringify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
|
||||
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
|
||||
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
|
||||
"dev": true
|
||||
},
|
||||
"forever-agent": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
|
||||
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
|
||||
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
|
||||
"dev": true
|
||||
},
|
||||
"form-data": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
|
||||
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.6",
|
||||
|
@ -202,12 +233,14 @@
|
|||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"dev": true
|
||||
},
|
||||
"getpass": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
|
||||
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
|
@ -216,6 +249,7 @@
|
|||
"version": "7.1.4",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
|
||||
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
|
@ -228,17 +262,20 @@
|
|||
"growl": {
|
||||
"version": "1.10.5",
|
||||
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
|
||||
"integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA=="
|
||||
"integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
|
||||
"dev": true
|
||||
},
|
||||
"har-schema": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
|
||||
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
|
||||
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
|
||||
"dev": true
|
||||
},
|
||||
"har-validator": {
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
|
||||
"integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^6.5.5",
|
||||
"har-schema": "^2.0.0"
|
||||
|
@ -247,17 +284,20 @@
|
|||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
|
||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
|
||||
"dev": true
|
||||
},
|
||||
"he": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
|
||||
"integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0="
|
||||
"integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
|
||||
"dev": true
|
||||
},
|
||||
"http-proxy-agent": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz",
|
||||
"integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"agent-base": "4",
|
||||
"debug": "3.1.0"
|
||||
|
@ -267,6 +307,7 @@
|
|||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
|
||||
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"jsprim": "^1.2.2",
|
||||
|
@ -277,6 +318,7 @@
|
|||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz",
|
||||
"integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"agent-base": "^4.3.0",
|
||||
"debug": "^3.1.0"
|
||||
|
@ -286,6 +328,7 @@
|
|||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
|
@ -294,42 +337,50 @@
|
|||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true
|
||||
},
|
||||
"is-typedarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
|
||||
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
|
||||
"dev": true
|
||||
},
|
||||
"isstream": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
|
||||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
|
||||
"dev": true
|
||||
},
|
||||
"jsbn": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
|
||||
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
|
||||
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
|
||||
"dev": true
|
||||
},
|
||||
"json-schema": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
|
||||
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
|
||||
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
|
||||
"dev": true
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||
"dev": true
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
|
||||
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
|
||||
"dev": true
|
||||
},
|
||||
"jsprim": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
|
||||
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "1.0.0",
|
||||
"extsprintf": "1.3.0",
|
||||
|
@ -340,12 +391,14 @@
|
|||
"mime-db": {
|
||||
"version": "1.40.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
|
||||
"integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA=="
|
||||
"integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==",
|
||||
"dev": true
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.24",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
|
||||
"integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mime-db": "1.40.0"
|
||||
}
|
||||
|
@ -354,6 +407,7 @@
|
|||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
|
@ -361,12 +415,14 @@
|
|||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
||||
"dev": true
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
|
@ -375,6 +431,7 @@
|
|||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz",
|
||||
"integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"browser-stdout": "1.3.1",
|
||||
"commander": "2.15.1",
|
||||
|
@ -393,6 +450,7 @@
|
|||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
|
||||
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
|
@ -407,17 +465,20 @@
|
|||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
|
||||
"dev": true
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
|
||||
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
|
||||
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
|
||||
"dev": true
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
|
@ -425,37 +486,44 @@
|
|||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"dev": true
|
||||
},
|
||||
"performance-now": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
||||
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
|
||||
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
|
||||
"dev": true
|
||||
},
|
||||
"psl": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz",
|
||||
"integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag=="
|
||||
"integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==",
|
||||
"dev": true
|
||||
},
|
||||
"punycode": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
|
||||
"dev": true
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
||||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
|
||||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
|
||||
"dev": true
|
||||
},
|
||||
"querystringify": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz",
|
||||
"integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA=="
|
||||
"integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==",
|
||||
"dev": true
|
||||
},
|
||||
"request": {
|
||||
"version": "2.88.0",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
|
||||
"integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"aws-sign2": "~0.7.0",
|
||||
"aws4": "^1.8.0",
|
||||
|
@ -482,32 +550,38 @@
|
|||
"requires-port": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
|
||||
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
|
||||
"dev": true
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
|
||||
"integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
|
||||
"integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
|
||||
"dev": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||
"dev": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
|
||||
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA=="
|
||||
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
|
||||
"dev": true
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true
|
||||
},
|
||||
"source-map-support": {
|
||||
"version": "0.5.13",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
|
||||
"integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"source-map": "^0.6.0"
|
||||
|
@ -517,6 +591,7 @@
|
|||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
|
||||
"integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"asn1": "~0.2.3",
|
||||
"assert-plus": "^1.0.0",
|
||||
|
@ -533,6 +608,7 @@
|
|||
"version": "5.4.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
|
||||
"integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
|
@ -541,6 +617,7 @@
|
|||
"version": "2.4.3",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
|
||||
"integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"psl": "^1.1.24",
|
||||
"punycode": "^1.4.1"
|
||||
|
@ -549,7 +626,8 @@
|
|||
"punycode": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
|
||||
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -557,6 +635,7 @@
|
|||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
|
@ -564,12 +643,14 @@
|
|||
"tweetnacl": {
|
||||
"version": "0.14.5",
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
|
||||
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
|
||||
"dev": true
|
||||
},
|
||||
"uri-js": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
|
||||
"integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
|
@ -578,6 +659,7 @@
|
|||
"version": "1.4.7",
|
||||
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz",
|
||||
"integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"querystringify": "^2.1.1",
|
||||
"requires-port": "^1.0.0"
|
||||
|
@ -586,12 +668,14 @@
|
|||
"uuid": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
|
||||
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
|
||||
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
|
||||
"dev": true
|
||||
},
|
||||
"verror": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
|
||||
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"core-util-is": "1.0.2",
|
||||
|
@ -602,6 +686,7 @@
|
|||
"version": "1.1.36",
|
||||
"resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.36.tgz",
|
||||
"integrity": "sha512-cGFh9jmGLcTapCpPCKvn8aG/j9zVQ+0x5hzYJq5h5YyUXVGa1iamOaB2M2PZXoumQPES4qeAP1FwkI0b6tL4bQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "^7.1.2",
|
||||
"mocha": "^5.2.0",
|
||||
|
@ -643,6 +728,7 @@
|
|||
"version": "0.4.3",
|
||||
"resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.4.3.tgz",
|
||||
"integrity": "sha512-EkMGqBSefZH2MgW65nY05rdRSko15uvzq4VAPM5jVmwYuFQKE7eikKXNJDRxL+OITXHB6pI+a3XqqD32Y3KC5w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"http-proxy-agent": "^2.1.0",
|
||||
"https-proxy-agent": "^2.2.1"
|
||||
|
@ -651,7 +737,8 @@
|
|||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,9 +19,9 @@
|
|||
"compile": "tsc -p ./"
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-languageclient": "^4.4.2"
|
||||
"vscode-languageclient": "^4.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vscode": "^1.1.36"
|
||||
"vscode": "^1.1.36"
|
||||
}
|
||||
}
|
||||
|
|
60
server/package-lock.json
generated
60
server/package-lock.json
generated
|
@ -4,6 +4,14 @@
|
|||
"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",
|
||||
|
@ -17,27 +25,10 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"binary": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz",
|
||||
"integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=",
|
||||
"requires": {
|
||||
"buffers": "~0.1.1",
|
||||
"chainsaw": "~0.1.0"
|
||||
}
|
||||
},
|
||||
"buffers": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz",
|
||||
"integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s="
|
||||
},
|
||||
"chainsaw": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz",
|
||||
"integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=",
|
||||
"requires": {
|
||||
"traverse": ">=0.3.0 <0.4"
|
||||
}
|
||||
"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",
|
||||
|
@ -47,19 +38,6 @@
|
|||
"stackframe": "^0.3.1"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
|
||||
|
@ -109,11 +87,6 @@
|
|||
"stacktrace-gps": "^2.4.3"
|
||||
}
|
||||
},
|
||||
"traverse": {
|
||||
"version": "0.3.9",
|
||||
"resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz",
|
||||
"integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk="
|
||||
},
|
||||
"typescript-logging": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript-logging/-/typescript-logging-0.6.3.tgz",
|
||||
|
@ -122,15 +95,6 @@
|
|||
"stacktrace-js": "1.3.1"
|
||||
}
|
||||
},
|
||||
"unzip-stream": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/unzip-stream/-/unzip-stream-0.3.0.tgz",
|
||||
"integrity": "sha512-NG1h/MdGIX3HzyqMjyj1laBCmlPYhcO4xEy7gEqqzGiSLw7XqDQCnY4nYSn5XSaH8mQ6TFkaujrO8d/PIZN85A==",
|
||||
"requires": {
|
||||
"binary": "^0.3.0",
|
||||
"mkdirp": "^0.5.1"
|
||||
}
|
||||
},
|
||||
"vscode-jsonrpc": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.6.2.tgz",
|
||||
|
|
|
@ -12,10 +12,11 @@
|
|||
"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",
|
||||
"unzip-stream": "^0.3.0",
|
||||
"vscode-languageserver": "^4.4.2"
|
||||
},
|
||||
"scripts": {
|
||||
|
|
|
@ -1,14 +1,8 @@
|
|||
import { connection, documents, onEvent } from './server'
|
||||
import fetch from 'node-fetch'
|
||||
import { platform } from 'os'
|
||||
import { createWriteStream, chmodSync, createReadStream, unlinkSync, read } from 'fs'
|
||||
import * as unzip from 'unzip-stream'
|
||||
import { postError } from './utils'
|
||||
import { execSync } from 'child_process'
|
||||
import { serverLog } from './logging'
|
||||
import { connection } from './server'
|
||||
import { serverLog as log } from './logging'
|
||||
import { dirname } from 'path'
|
||||
import { DidChangeConfigurationParams } from 'vscode-languageserver'
|
||||
import { win } from './linter'
|
||||
import { GLSLangProvider } from './glslangValidator'
|
||||
|
||||
const url = {
|
||||
'win32': 'https://github.com/KhronosGroup/glslang/releases/download/master-tot/glslang-master-windows-x64-Release.zip',
|
||||
|
@ -18,26 +12,75 @@ const url = {
|
|||
|
||||
export let glslangReady = false
|
||||
|
||||
export interface Config {
|
||||
readonly shaderpacksPath: string
|
||||
readonly glslangPath: string
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
export let conf: Config = {shaderpacksPath: '', glslangPath: ''}
|
||||
interface Config {
|
||||
shaderpacksPath: string
|
||||
glslangValidatorPath: string
|
||||
}
|
||||
|
||||
let supress = false
|
||||
|
||||
export async function onConfigChange(change: DidChangeConfigurationParams) {
|
||||
const temp = change.settings.mcglsl as Config
|
||||
if (temp.shaderpacksPath === conf.shaderpacksPath && temp.glslangPath === conf.glslangPath) return
|
||||
conf = {shaderpacksPath: temp['shaderpacksPath'].replace(/\\/g, '/'), glslangPath: temp['glslangValidatorPath'].replace(/\\/g, '/')}
|
||||
serverLog.debug(() => 'new config: ' + JSON.stringify(temp))
|
||||
serverLog.debug(() => 'old config: ' + JSON.stringify(conf))
|
||||
async function onConfigChange(confProv: ConfigProvider, old: Config) {
|
||||
if (!confProv.config == undefined &&
|
||||
old.shaderpacksPath === confProv.config.shaderpacksPath &&
|
||||
old.glslangValidatorPath === confProv.config.glslangValidatorPath) return
|
||||
|
||||
if (conf.shaderpacksPath === '' || conf.shaderpacksPath.replace(dirname(conf.shaderpacksPath), '') !== '/shaderpacks') {
|
||||
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
|
||||
|
||||
serverLog.error(() => 'shaderpack path not set or doesn\'t end in \'shaderpacks\'', null)
|
||||
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(
|
||||
|
@ -48,81 +91,9 @@ export async function onConfigChange(change: DidChangeConfigurationParams) {
|
|||
return
|
||||
}
|
||||
|
||||
try {
|
||||
if (!execSync(conf.glslangPath).toString().startsWith('Usage')) {
|
||||
documents.all().forEach(onEvent)
|
||||
glslangReady = true
|
||||
} else {
|
||||
promptDownloadGlslang()
|
||||
}
|
||||
} catch (e) {
|
||||
if ((e.stdout.toString() as string).startsWith('Usage')) {
|
||||
documents.all().forEach(onEvent)
|
||||
glslangReady = true
|
||||
} else {
|
||||
promptDownloadGlslang()
|
||||
}
|
||||
if (!confProv.glslang.testExecutable()) {
|
||||
await confProv.glslang.promptDownload()
|
||||
} else {
|
||||
glslangReady = true
|
||||
}
|
||||
}
|
||||
|
||||
async function promptDownloadGlslang() {
|
||||
const chosen = await connection.window.showErrorMessage(
|
||||
`[mc-glsl] glslangValidator not found at: '${conf.glslangPath}'.`,
|
||||
{title: 'Download'},
|
||||
{title: 'Cancel'}
|
||||
)
|
||||
|
||||
if (!chosen || chosen.title !== 'Download') return
|
||||
|
||||
downloadGlslang()
|
||||
}
|
||||
|
||||
async function downloadGlslang() {
|
||||
connection.window.showInformationMessage('Downloading. Your settings will be updated automatically and you\'ll be notified when its done.')
|
||||
|
||||
serverLog.info(() => 'downloading glslangValidator...')
|
||||
|
||||
const res = await fetch(url[platform()])
|
||||
|
||||
serverLog.info(() => 'glslangValidator downloaded. Extracting...')
|
||||
|
||||
try {
|
||||
const zip = createWriteStream(conf.shaderpacksPath + '/glslangValidator.zip')
|
||||
res.body.pipe(zip)
|
||||
|
||||
const glslang = '/glslangValidator' + (win ? '.exe' : '')
|
||||
|
||||
zip.on('finish', () => {
|
||||
try {
|
||||
createReadStream(conf.shaderpacksPath + '/glslangValidator.zip')
|
||||
.pipe(unzip.Parse())
|
||||
.on('entry', entry => {
|
||||
try {
|
||||
if (entry.path === 'bin' + glslang) {
|
||||
entry.pipe(createWriteStream(conf.shaderpacksPath + glslang))
|
||||
return
|
||||
}
|
||||
entry.autodrain()
|
||||
} catch (e) {
|
||||
postError(e)
|
||||
}
|
||||
})
|
||||
.on('close', () => {
|
||||
try {
|
||||
chmodSync(conf.shaderpacksPath + glslang, 0o775)
|
||||
unlinkSync(conf.shaderpacksPath + '/glslangValidator.zip')
|
||||
connection.sendNotification('update-config', conf.shaderpacksPath + glslang)
|
||||
connection.window.showInformationMessage('glslangValidator has been downloaded to ' + conf.shaderpacksPath + '/glslangValidator. Your config should be updated automatically.')
|
||||
glslangReady = true
|
||||
} catch (e) {
|
||||
postError(e)
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
postError(e)
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
postError(e)
|
||||
}
|
||||
}
|
9
server/src/fileTypes.ts
Normal file
9
server/src/fileTypes.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
|
||||
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'],
|
||||
])
|
100
server/src/glslangValidator.ts
Normal file
100
server/src/glslangValidator.ts
Normal file
|
@ -0,0 +1,100 @@
|
|||
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
|
||||
}
|
||||
}
|
|
@ -38,4 +38,24 @@ export class Graph {
|
|||
}
|
||||
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
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
import * as vsclang from 'vscode-languageserver'
|
||||
import { linkLog } from './logging'
|
||||
import { linkLog as log} from './logging'
|
||||
import { formatURI } from './utils'
|
||||
|
||||
export function getDocumentLinks(file: string): vsclang.DocumentLink[] {
|
||||
linkLog.debug(() => formatURI(file) + ' ' + file)
|
||||
return [vsclang.DocumentLink.create(vsclang.Range.create(8, 0, 8, 32), 'file:///home/noah/.minecraft/shaderpacks/robobo1221Shaders-7.9.01/shaders/lib/utilities.glsl')]
|
||||
log.debug(() => formatURI(file) + ' ' + file)
|
||||
return [vsclang.DocumentLink.create(vsclang.Range.create(8, 0, 8, 32), 'file:///e:\\shaderpacks\\Sushi-Shader\\shaders\\composite1.vsh')]
|
||||
}
|
|
@ -1,383 +1,4 @@
|
|||
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 { conf } from './config'
|
||||
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[],
|
||||
}
|
||||
|
||||
export const ext = new Map([
|
||||
['.fsh', 'frag'],
|
||||
['.gsh', 'geom'],
|
||||
['.vsh', 'vert'],
|
||||
])
|
||||
|
||||
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)
|
||||
|
||||
export class Linter {
|
||||
|
||||
}
|
376
server/src/linter.ts.old
Normal file
376
server/src/linter.ts.old
Normal file
|
@ -0,0 +1,376 @@
|
|||
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)
|
||||
}
|
|
@ -2,7 +2,10 @@ import { Category, CategoryConfiguration, CategoryServiceFactory, LogLevel } fro
|
|||
|
||||
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 linkLog = new Category('links')
|
||||
export const glslProviderLog = new Category('glslangProvider')
|
||||
export const uriLog = new Category('uri')
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
import { dirname } from 'path'
|
||||
import * as vsclang from 'vscode-languageserver'
|
||||
import * as vsclangproto from 'vscode-languageserver-protocol'
|
||||
import { completions } from './completionProvider'
|
||||
import { conf, glslangReady, onConfigChange } from './config'
|
||||
import { ConfigProvider } from './config'
|
||||
import { getDocumentLinks } from './linksProvider'
|
||||
import { includeGraph, preprocess } from './linter'
|
||||
import { formatURI, getDocumentContents, postError } from './utils'
|
||||
import { GLSLangProvider } from './glslangValidator';
|
||||
|
||||
const reVersion = /#version [\d]{3}/
|
||||
|
||||
|
@ -14,10 +12,14 @@ 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((params) => (
|
||||
connection.onInitialize((_) => (
|
||||
{
|
||||
capabilities: {
|
||||
textDocumentSync: documents.syncKind,
|
||||
|
@ -33,9 +35,9 @@ connection.onInitialize((params) => (
|
|||
|
||||
connection.onExit(() => {})
|
||||
|
||||
documents.onDidOpen((event) => onEvent(event.document))
|
||||
documents.onDidOpen((event) => lint(event.document))
|
||||
|
||||
documents.onDidSave((event) => onEvent(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
|
||||
|
@ -45,8 +47,13 @@ documents.onDidClose((event) => {
|
|||
|
||||
//documents.onDidChangeContent(onEvent)
|
||||
|
||||
export function onEvent(document: vsclangproto.TextDocument) {
|
||||
if (conf.shaderpacksPath.replace(dirname(conf.shaderpacksPath), '') !== '/shaderpacks' || !glslangReady) return
|
||||
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) {
|
||||
|
@ -63,10 +70,10 @@ export function onEvent(document: vsclangproto.TextDocument) {
|
|||
preprocess(document.getText().split('\n'), uri)
|
||||
} catch (e) {
|
||||
postError(e)
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
||||
function lintBubbleDown(uri: string) {
|
||||
/* function lintBubbleDown(uri: string) {
|
||||
includeGraph.get(uri).parents.forEach((parent, parentURI) => {
|
||||
if (parent.second.parents.size > 0) {
|
||||
lintBubbleDown(parentURI)
|
||||
|
@ -82,11 +89,11 @@ function lintBubbleDown(uri: string) {
|
|||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
} */
|
||||
|
||||
connection.onDocumentLinks((params: vsclang.DocumentLinkParams) => getDocumentLinks(params.textDocument.uri))
|
||||
|
||||
connection.onDidChangeConfiguration(onConfigChange)
|
||||
connection.onDidChangeConfiguration(configProvider.onConfigChange)
|
||||
|
||||
connection.onCompletion((textDocumentPosition: vsclang.TextDocumentPositionParams) => completions)
|
||||
|
||||
|
|
52
server/src/uri.ts
Normal file
52
server/src/uri.ts
Normal file
|
@ -0,0 +1,52 @@
|
|||
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
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +1,19 @@
|
|||
import { readFileSync } from 'fs'
|
||||
import { conf } from './config'
|
||||
import { serverLog } from './logging'
|
||||
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)
|
||||
serverLog.error(e.message, null)
|
||||
console.log(e)
|
||||
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(/\\/g, '/')
|
||||
return uri.replace(/^file:\/\//, '').replace(/\\/, '/')
|
||||
}
|
||||
|
||||
export function getDocumentContents(uri: string): string {
|
||||
|
@ -20,6 +21,6 @@ export function getDocumentContents(uri: string): string {
|
|||
else return readFileSync(uri).toString()
|
||||
}
|
||||
|
||||
export function trimPath(path: string): string {
|
||||
/* export function trimPath(path: string): string {
|
||||
return path.replace(conf.shaderpacksPath, '')
|
||||
}
|
||||
} */
|
|
@ -6,7 +6,7 @@
|
|||
"sourceMap": true,
|
||||
"outDir": "out",
|
||||
"rootDir": "src",
|
||||
"lib": [ "es6", "es2017" ]
|
||||
"lib": [ "es6", "es2017", "dom" ]
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue