summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsumneko <sumneko@hotmail.com>2021-12-21 22:49:59 +0800
committersumneko <sumneko@hotmail.com>2021-12-21 22:49:59 +0800
commitb7344640a0ab9a07551ee5ebc435657b45659553 (patch)
tree0fef08a7dbb0a115e0e1249b6123fd529cf1fc58
parentc47baf932309a05673b7931fdf6a1be207fb7bc4 (diff)
parentec4f497aa2624d9dce29e1de0cfd28ecd85e7df3 (diff)
downloadlua-language-server-b7344640a0ab9a07551ee5ebc435657b45659553.zip
Merge remote-tracking branch 'origin/master' into multi-workspace
-rw-r--r--.github/workflows/build.yml130
-rw-r--r--.github/workflows/checkPR.yml16
-rw-r--r--.gitignore7
-rw-r--r--.vscode/launch.json6
m---------3rd/bee.lua0
m---------3rd/lovr-api0
m---------3rd/luamake0
-rw-r--r--README.md1
-rw-r--r--changelog.md21
-rw-r--r--make.lua83
-rw-r--r--make/bootstrap.lua2
-rw-r--r--make/copy_vcrt.lua7
-rw-r--r--meta/3rd/OpenResty/library/resty.websocket.client.lua75
-rw-r--r--meta/3rd/OpenResty/library/resty.websocket.lua116
-rw-r--r--meta/3rd/OpenResty/library/resty.websocket.protocol.lua59
-rw-r--r--meta/3rd/OpenResty/library/resty.websocket.server.lua25
-rw-r--r--meta/template/math.lua2
-rw-r--r--script/core/completion/completion.lua29
-rw-r--r--script/core/definition.lua3
-rw-r--r--script/core/diagnostics/different-requires.lua4
-rw-r--r--script/core/diagnostics/unused-local.lua3
-rw-r--r--script/core/hint.lua2
-rw-r--r--script/core/hover/arg.lua10
-rw-r--r--script/core/hover/description.lua5
-rw-r--r--script/core/hover/init.lua20
-rw-r--r--script/core/hover/label.lua27
-rw-r--r--script/core/hover/name.lua11
-rw-r--r--script/core/infer.lua17
-rw-r--r--script/core/searcher.lua4
-rw-r--r--script/core/type-definition.lua3
-rw-r--r--script/encoder/utf16.lua2
-rw-r--r--script/library.lua13
-rw-r--r--script/log.lua25
-rw-r--r--script/parser/guide.lua12
-rw-r--r--script/parser/luadoc.lua79
-rw-r--r--script/parser/newparser.lua12
-rw-r--r--script/provider/diagnostic.lua2
-rw-r--r--script/vm/getLinks.lua4
-rw-r--r--script/workspace/require-path.lua49
-rw-r--r--script/workspace/workspace.lua82
-rw-r--r--test.lua2
-rw-r--r--test/completion/common.lua27
-rw-r--r--test/crossfile/definition.lua90
-rw-r--r--test/crossfile/hover.lua84
-rw-r--r--test/diagnostics/init.lua11
45 files changed, 885 insertions, 297 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 946e7490..31c8d7f8 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,20 +1,124 @@
name: build
-on: push
+
+on:
+ push:
+ branches:
+ - master
+ tags:
+ - "*"
+ pull_request:
+ branches:
+ - master
+
+env:
+ PROJECT: lua-language-server
+ BIN_DIR: bin
+
jobs:
compile:
- runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
- os: [windows-latest, ubuntu-18.04, macos-latest]
+ include:
+ - { os: ubuntu-18.04, target: linux, platform: linux-x64 }
+ - { os: macos-11, target: darwin, platform: darwin-x64 }
+ - { os: macos-11, target: darwin, platform: darwin-arm64 }
+ - { os: windows-latest, target: windows, platform: win32-ia32 }
+ - { os: windows-latest, target: windows, platform: win32-x64 }
+ runs-on: ${{ matrix.os }}
steps:
- - uses: actions/checkout@v1
- with:
- ref: refs/heads/master
- submodules : recursive
- - uses: actboy168/setup-luamake@master
- - run: luamake
- - uses: actions/upload-artifact@v1.0.0
- with:
- name: lua-language-server
- path: bin
+ - uses: actions/checkout@v2
+ with:
+ submodules: recursive
+ - uses: actboy168/setup-luamake@master
+ - run: luamake -platform ${{ matrix.platform }}
+
+ - name: Setting up workflow variables
+ id: vars
+ shell: bash
+ run: |
+ # Package version
+ if [[ $GITHUB_REF = refs/tags/* ]]; then
+ PKG_VERSION=${GITHUB_REF##*/}
+ else
+ PKG_VERSION=${GITHUB_SHA:0:7}
+ fi
+
+ # Package suffix relative to the platform
+ if [[ "${{ matrix.target }}" = windows ]]; then
+ PKG_SUFFIX="zip"
+ else
+ PKG_SUFFIX="tar.gz"
+ fi
+
+ # Package name w/ version
+ PKG_BASENAME="${{ env.PROJECT }}-${PKG_VERSION}-${{ matrix.platform }}"
+
+ # Full name of the tarball asset
+ PKG_NAME="${PKG_BASENAME}.${PKG_SUFFIX}"
+
+ # Staging area for tarballs
+ PKG_STAGING="ci_staging/$PKG_BASENAME"
+
+ echo ::set-output name=PKG_VERSION::${PKG_VERSION}
+ echo ::set-output name=PKG_BASENAME::${PKG_BASENAME}
+ echo ::set-output name=PKG_NAME::${PKG_NAME}
+ echo ::set-output name=PKG_PATH::"${PKG_STAGING}/${PKG_NAME}"
+ echo ::set-output name=PKG_STAGING::${PKG_STAGING}
+
+ - uses: actions/upload-artifact@v2
+ with:
+ name: ${{ steps.vars.outputs.PKG_BASENAME }}
+ path: |
+ ${{ env.BIN_DIR }}
+ main.lua
+ debugger.lua
+ LICENSE
+ changelog.md
+ locale
+ meta
+ script
+
+ - name: Package tarballs
+ if: startsWith(github.ref, 'refs/tags/')
+ shell: bash
+ run: |
+ STAGING=${{ steps.vars.outputs.PKG_STAGING }}
+ NAME=${{ steps.vars.outputs.PKG_NAME }}
+
+ # Making the staging area
+ mkdir -p ${STAGING}
+
+ # Copying binary and runtime files to staging area
+ cp -r main.lua debugger.lua LICENSE changelog.md locale meta script ${{ env.BIN_DIR }} ${STAGING}
+
+ # Creating release assets
+ pushd "${STAGING}/" >/dev/null
+ if [[ "${{ matrix.target }}" = windows ]]; then
+ 7z -y a ${NAME} * | tail -2
+ else
+ tar czf ${NAME} *
+ fi
+ popd >/dev/null
+
+ # Packaging submodules for homebrew distribution
+ - name: Package submodules
+ id: submodules
+ if: ${{ startsWith(github.ref, 'refs/tags/') && matrix.platform == 'darwin-x64' }}
+ run: |
+ STAGING=${{ steps.vars.outputs.PKG_STAGING }}
+ PKG_SUBMOD_NAME="${{ env.PROJECT }}-${{ steps.vars.outputs.PKG_VERSION }}-submodules.zip"
+ PKG_SUBMOD_PATH="${STAGING}/$PKG_SUBMOD_NAME"
+
+ zip -r $PKG_SUBMOD_PATH ./ -x "*.git*" -x "*.vscode*" -x "build*" -x "${{ env.BIN_DIR }}*" -x "${STAGING}*"
+
+ echo ::set-output name=PKG_SUBMOD_PATH::${PKG_SUBMOD_PATH}
+
+ - name: Publish release assets
+ uses: softprops/action-gh-release@v1
+ if: startsWith(github.ref, 'refs/tags/')
+ with:
+ generate_release_notes: true
+ files: |
+ ${{ steps.vars.outputs.PKG_PATH }}
+ ${{ steps.submodules.outputs.PKG_SUBMOD_PATH }}
diff --git a/.github/workflows/checkPR.yml b/.github/workflows/checkPR.yml
deleted file mode 100644
index c83bf3ab..00000000
--- a/.github/workflows/checkPR.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-name: checkPR
-on: pull_request
-jobs:
- compile:
- runs-on: ${{ matrix.os }}
- strategy:
- fail-fast: false
- matrix:
- os: [windows-latest, ubuntu-18.04, macos-latest]
- steps:
- - uses: actions/checkout@v1
- with:
- ref: ${{ github.event.pull_request.head.sha }}
- submodules : recursive
- - uses: actboy168/setup-luamake@master
- - run: luamake
diff --git a/.gitignore b/.gitignore
index 00ee8c15..b88e4489 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,9 +1,10 @@
/log
/build
-/bin
-!*.exe
/test/temp.lua
/meta/*
!/meta/template
!/meta/3rd
-/bin2
+/bin-Windows
+/bin-Linux
+/bin-macOS
+/bin
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 671a0662..bfb5c94c 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -8,7 +8,7 @@
"request": "launch",
"stopOnEntry": false,
"program": "${workspaceRoot}/test.lua",
- "luaexe": "${workspaceFolder}/bin/Windows/lua-language-server.exe",
+ "luaexe": "${workspaceFolder}/bin/lua-language-server.exe",
"cpath": null,
"arg": [
],
@@ -40,9 +40,9 @@
"type": "lua",
"request": "launch",
"stopOnEntry": false,
- "luaexe": "${workspaceFolder}/bin/Windows/lua-language-server.exe",
+ "luaexe": "${workspaceFolder}/bin/lua-language-server",
"program": "${workspaceRoot}/tools/build-3rd-meta.lua",
- "cpath": "${workspaceFolder}/bin/Windows/?.dll",
+ "cpath": "${workspaceFolder}/bin/?.dll",
"arg": [
],
"luaVersion": "latest",
diff --git a/3rd/bee.lua b/3rd/bee.lua
-Subproject 1794c607d3c16533a0d117da38ed15e6be2d6ba
+Subproject 9132c7ecb4a68c40d52a6d750308237bf054feb
diff --git a/3rd/lovr-api b/3rd/lovr-api
-Subproject 58580f0f8ba3852fa7fe1b31a275e0d2a657ec3
+Subproject 92d3742eb6c3f4999a0c575984c82a75652e2b7
diff --git a/3rd/luamake b/3rd/luamake
-Subproject 0aa2dbeaf7606db71718f17bcea489b0ff846e6
+Subproject 637ca44922ac125ceaebfb53650e4d7c6ae9247
diff --git a/README.md b/README.md
index 554869bf..9494e933 100644
--- a/README.md
+++ b/README.md
@@ -141,6 +141,7 @@ If you need to compile by yourself, please refer to [here](https://github.com/su
* [CppCXY](https://github.com/CppCXY)
* [Ketho](https://github.com/Ketho)
* [Folke Lemaitre](https://github.com/folke)
+* [Vikas Raj](https://github.com/numToStr)
## Telemetry
diff --git a/changelog.md b/changelog.md
index af0ea081..92465e50 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,26 @@
# changelog
+## 2.5.6
+* `CHG` diagnostic: now syntax errors in `LuaDoc` are shown as `Warning`
+* `FIX` return type of `math.floor`
+* `FIX` runtime errors
+
+## 2.5.5
+`2021-12-16`
+* `FIX` dose not work in VSCode
+
+## 2.5.4
+`2021-12-16`
+* `FIX` [#847](https://github.com/sumneko/lua-language-server/issues/847)
+* `FIX` [#848](https://github.com/sumneko/lua-language-server/issues/848)
+* `FIX` completion: incorrect cache
+* `FIX` hover: always view string
+
+## 2.5.3
+`2021-12-6`
+* `FIX` [#842](https://github.com/sumneko/lua-language-server/issues/844)
+* `FIX` [#844](https://github.com/sumneko/lua-language-server/issues/844)
+
## 2.5.2
`2021-12-2`
* `FIX` [#815](https://github.com/sumneko/lua-language-server/issues/815)
diff --git a/make.lua b/make.lua
index cee14c4a..9c4c08de 100644
--- a/make.lua
+++ b/make.lua
@@ -2,9 +2,30 @@ local lm = require 'luamake'
local platform = require 'bee.platform'
local exe = platform.OS == 'Windows' and ".exe" or ""
-lm.bindir = "bin/"..platform.OS
+lm.bindir = "bin"
lm.EXE_DIR = ""
+
+if platform.OS == 'macOS' then
+ if lm.platform == nil then
+ elseif lm.platform == "darwin-arm64" then
+ lm.target = "arm64-apple-macos11"
+ elseif lm.platform == "darwin-x64" then
+ lm.target = "x86_64-apple-macos10.12"
+ else
+ error "unknown platform"
+ end
+elseif platform.OS == 'Windows' then
+ if lm.platform == nil then
+ elseif lm.platform == "win32-ia32" then
+ lm.arch = "x86"
+ elseif lm.platform == "win32-x64" then
+ lm.arch = "x86_64"
+ else
+ error "unknown platform"
+ end
+end
+
lm:import "3rd/bee.lua/make.lua"
lm:source_set 'lpeglabel' {
@@ -33,18 +54,16 @@ lm:executable "lua-language-server" {
}
}
-lm:build 'copy_vcrt' {
- '$luamake', 'lua', 'make/copy_vcrt.lua', lm.bindir,
-}
-
lm:copy "copy_bootstrap" {
input = "make/bootstrap.lua",
output = lm.bindir.."/main.lua",
}
-lm:build "bee-test" {
- lm.bindir.."/lua-language-server"..exe, "3rd/bee.lua/test/test.lua",
- pool = "console",
+lm:build 'copy_vcrt' {
+ '$luamake', 'lua', 'make/copy_vcrt.lua', lm.bindir, lm.arch,
+}
+
+lm:phony "all" {
deps = {
"lua-language-server",
"copy_bootstrap",
@@ -56,6 +75,54 @@ lm:build "bee-test" {
}
}
+local function detectWindowsArch()
+ if os.getenv "PROCESSOR_ARCHITECTURE" == "ARM64" then
+ return "arm64"
+ end
+ if os.getenv "PROCESSOR_ARCHITECTURE" == "AMD64" or os.getenv "PROCESSOR_ARCHITEW6432" == "AMD64" then
+ return "x64"
+ end
+ return "ia32"
+end
+
+local function detectPosixArch()
+ local f <close> = assert(io.popen("uname -m", 'r'))
+ return f:read 'l':lower()
+end
+
+local function detectArch()
+ if platform.OS == 'Windows' then
+ return detectWindowsArch()
+ end
+ return detectPosixArch()
+end
+
+local function targetPlatformArch()
+ if lm.platform == nil then
+ return detectArch()
+ end
+ return lm.platform:match "^[^-]*-(.*)$"
+end
+
+local notest = platform.OS == 'macOS'
+ and targetPlatformArch() == "arm64"
+ and detectArch() == "x86_64"
+
+if notest then
+ lm:default {
+ "all",
+ }
+ return
+end
+
+lm:build "bee-test" {
+ lm.bindir.."/lua-language-server"..exe, "3rd/bee.lua/test/test.lua",
+ pool = "console",
+ deps = {
+ "all",
+ }
+}
+
lm:build 'unit-test' {
lm.bindir.."/lua-language-server"..exe, 'test.lua',
pool = "console",
diff --git a/make/bootstrap.lua b/make/bootstrap.lua
index e9e61c77..36b9ce96 100644
--- a/make/bootstrap.lua
+++ b/make/bootstrap.lua
@@ -49,7 +49,7 @@ local root; do
sep = '/\\'
end
local pattern = "["..sep.."][^"..sep.."]+"
- root = package.cpath:match("([^;]+)"..pattern..pattern..pattern.."$")
+ root = package.cpath:match("([^;]+)"..pattern..pattern.."$")
arg[0] = root .. package.config:sub(1,1) .. 'main.lua'
end
root = root:gsub('[/\\]', package.config:sub(1,1))
diff --git a/make/copy_vcrt.lua b/make/copy_vcrt.lua
index b1eb3cf5..bd08a9fa 100644
--- a/make/copy_vcrt.lua
+++ b/make/copy_vcrt.lua
@@ -1,3 +1,6 @@
-local output = ...
+local output, arch = ...
local fs = require 'bee.filesystem'
-require 'msvc'.copy_vcrt('x64', fs.current_path() / output)
+require 'msvc'.copy_vcrt(
+ arch == "x86" and 'x86' or 'x64',
+ fs.current_path() / output
+)
diff --git a/meta/3rd/OpenResty/library/resty.websocket.client.lua b/meta/3rd/OpenResty/library/resty.websocket.client.lua
index f933c941..c722faf9 100644
--- a/meta/3rd/OpenResty/library/resty.websocket.client.lua
+++ b/meta/3rd/OpenResty/library/resty.websocket.client.lua
@@ -1,16 +1,63 @@
---@meta
-resty_websocket_client={}
-function resty_websocket_client.send_text(self, data) end
-function resty_websocket_client.new(self, opts) end
-function resty_websocket_client.send_ping(self, data) end
-function resty_websocket_client.connect(self, uri, opts) end
-function resty_websocket_client.set_timeout(self, time) end
-function resty_websocket_client.set_keepalive(self, ...) end
-function resty_websocket_client.send_binary(self, data) end
-function resty_websocket_client.send_close() end
-function resty_websocket_client.send_frame() end
-function resty_websocket_client.recv_frame(self) end
-function resty_websocket_client.close(self) end
-resty_websocket_client._VERSION="0.07"
-function resty_websocket_client.send_pong(self, data) end
+
+---@class resty.websocket.client : resty.websocket
+resty_websocket_client = {
+ _VERSION = "0.09"
+}
+
+---Instantiates a WebSocket client object.
+---
+---In case of error, it returns nil and a string describing the error.
+---
+---An optional options table can be specified.
+---
+---@param opts? resty.websocket.new.opts
+---@return resty.websocket.client? client
+---@return string? error
+function resty_websocket_client:new(opts) end
+
+---Connects to the remote WebSocket service port and performs the websocket
+---handshake process on the client side.
+---
+---Before actually resolving the host name and connecting to the remote backend,
+---this method will always look up the connection pool for matched idle
+---connections created by previous calls of this method.
+---
+---@param url string
+---@param opts? resty.websocket.client.connect.opts
+---@return boolean ok
+---@return string? error
+function resty_websocket_client:connect(uri, opts) end
+
+--- Puts the current WebSocket connection immediately into the ngx_lua cosocket connection pool.
+---
+--- You can specify the max idle timeout (in ms) when the connection is in the pool and the maximal size of the pool every nginx worker process.
+---
+--- In case of success, returns 1. In case of errors, returns nil with a string describing the error.
+---
+--- Only call this method in the place you would have called the close method instead. Calling this method will immediately turn the current WebSocket object into the closed state. Any subsequent operations other than connect() on the current object will return the closed error.
+----
+---@param max_idle_timeout number
+---@param pool_size integer
+---@return boolean ok
+---@return string? error
+function resty_websocket_client:set_keepalive(max_idle_timeout, pool_size) end
+
+---Closes the current WebSocket connection.
+---
+---If no close frame is sent yet, then the close frame will be automatically sent.
+---
+---@return boolean ok
+---@return string? error
+function resty_websocket_client:close() end
+
+---@class resty.websocket.client.connect.opts : table
+---
+---@field protocols string|string[] subprotocol(s) used for the current WebSocket session
+---@field origin string the value of the Origin request header
+---@field pool string custom name for the connection pool being used. If omitted, then the connection pool name will be generated from the string template <host>:<port>.
+---@field ssl_verify boolean whether to perform SSL certificate verification during the SSL handshake if the wss:// scheme is used.
+---@field headers string[] custom headers to be sent in the handshake request. The table is expected to contain strings in the format {"a-header: a header value", "another-header: another header value"}.
+
+
return resty_websocket_client \ No newline at end of file
diff --git a/meta/3rd/OpenResty/library/resty.websocket.lua b/meta/3rd/OpenResty/library/resty.websocket.lua
new file mode 100644
index 00000000..9ddd4921
--- /dev/null
+++ b/meta/3rd/OpenResty/library/resty.websocket.lua
@@ -0,0 +1,116 @@
+---@meta
+
+--- websocket object
+--- https://github.com/openresty/lua-resty-websocket
+---
+---@class resty.websocket : table
+---@field sock tcpsock
+---@field fatal boolean
+---@field max_payload_len number
+---@field send_masked boolean
+resty_websocket = {}
+
+---@param ms integer sets the timeout delay (in milliseconds) for the network-related operations
+function resty_websocket:set_timeout(ms) end
+
+---Sends the text argument out as an unfragmented data frame of the text type.
+---
+---Returns the number of bytes that have actually been sent on the TCP level.
+---
+---In case of errors, returns nil and a string describing the error.
+---
+---@param text string
+---@return integer? bytes
+---@return string? error
+function resty_websocket:send_text(text) end
+
+---Sends the data argument out as an unfragmented data frame of the binary type.
+---
+---Returns the number of bytes that have actually been sent on the TCP level.
+---
+---In case of errors, returns nil and a string describing the error.
+---
+---@param data string
+---@return integer? bytes
+---@return string? error
+function resty_websocket:send_binary(data) end
+
+---Sends out a ping frame with an optional message specified by the msg argument.
+---Returns the number of bytes that have actually been sent on the TCP level.
+---
+---In case of errors, returns nil and a string describing the error.
+---
+---Note that this method does not wait for a pong frame from the remote end.
+---
+---@param msg? string
+---@return integer? bytes
+---@return string? error
+function resty_websocket:send_ping(msg) end
+
+---Sends out a pong frame with an optional message specified by the msg argument.
+---Returns the number of bytes that have actually been sent on the TCP level.
+---
+---In case of errors, returns nil and a string describing the error.
+---@param msg? string
+---@return integer? bytes
+---@return string? error
+function resty_websocket:send_pong(msg) end
+
+---Sends out a close frame with an optional status code and a message.
+---
+---In case of errors, returns nil and a string describing the error.
+---
+---For a list of valid status code, see the following document:
+---
+---http://tools.ietf.org/html/rfc6455#section-7.4.1
+---
+---Note that this method does not wait for a close frame from the remote end.
+---@param code? integer
+---@param msg? string
+---@return integer? bytes
+---@return string? error
+function resty_websocket:send_close(code, msg) end
+
+---Sends out a raw websocket frame by specifying the fin field (boolean value), the opcode, and the payload.
+---
+---For a list of valid opcode, see
+---
+---http://tools.ietf.org/html/rfc6455#section-5.2
+---
+---In case of errors, returns nil and a string describing the error.
+---
+---To control the maximal payload length allowed, you can pass the max_payload_len option to the new constructor.
+---
+---To control whether to send masked frames, you can pass true to the send_masked option in the new constructor method. By default, unmasked frames are sent.
+---@param fin boolean
+---@param opcode resty.websocket.protocol.opcode
+---@param payload string
+---@return integer? bytes
+---@return string? error
+function resty_websocket:send_frame(fin, opcode, payload) end
+
+---Receives a WebSocket frame from the wire.
+---
+---In case of an error, returns two nil values and a string describing the error.
+---
+---The second return value is always the frame type, which could be one of continuation, text, binary, close, ping, pong, or nil (for unknown types).
+---
+---For close frames, returns 3 values: the extra status message (which could be an empty string), the string "close", and a Lua number for the status code (if any). For possible closing status codes, see
+---
+---http://tools.ietf.org/html/rfc6455#section-7.4.1
+---
+---For other types of frames, just returns the payload and the type.
+---
+---For fragmented frames, the err return value is the Lua string "again".
+---
+---@return string? data
+---@return resty.websocket.protocol.type? typ
+---@return string|integer? error_or_status_code
+function resty_websocket:recv_frame() end
+
+---@class resty.websocket.new.opts : table
+---@field max_payload_len integer maximal length of payload allowed when sending and receiving WebSocket frames
+---@field send_masked boolean whether to send out masked WebSocket frames
+---@field timeout integer network timeout threshold in milliseconds
+
+return resty_websocket
diff --git a/meta/3rd/OpenResty/library/resty.websocket.protocol.lua b/meta/3rd/OpenResty/library/resty.websocket.protocol.lua
index 9ef52bbb..c3455969 100644
--- a/meta/3rd/OpenResty/library/resty.websocket.protocol.lua
+++ b/meta/3rd/OpenResty/library/resty.websocket.protocol.lua
@@ -1,8 +1,59 @@
---@meta
-resty_websocket_protocol={}
-function resty_websocket_protocol.build_frame() end
-function resty_websocket_protocol.new_tab() end
+
+---@class resty.websocket.protocol
+resty_websocket_protocol = {
+ _VERSION = "0.09",
+}
+
+--- Websocket op code
+---
+--- Defines the interpretation of the payload data.
+---
+--- See RFC 6455 section 5.2
+---
+---@alias resty.websocket.protocol.opcode
+---| '0x0' # continuation
+---| '0x1' # text
+---| '0x2' # binary
+---| '0x8' # close
+---| '0x9' # ping
+---| '0xa' # pong
+
+---@alias resty.websocket.protocol.type
+---| '"continuation"'
+---| '"text"'
+---| '"binary"'
+---| '"close"'
+---| '"ping"'
+---| '"pong"'
+
+--- Builds a raw WebSocket frame.
+---@param fin boolean
+---@param opcode resty.websocket.protocol.opcode
+---@param payload_len integer
+---@param payload string
+---@param masking boolean
+---@return string
+function resty_websocket_protocol.build_frame(fin, opcode, payload_len, payload, masking) end
+
+--- Sends a raw WebSocket frame.
+---@param sock tcpsock
+---@param fin boolean
+---@param opcode resty.websocket.protocol.opcode
+---@param payload string
+---@param max_payload_len interger
+---@param masking boolean
+---@return bytes? number
+---@return string? error
function resty_websocket_protocol.send_frame(sock, fin, opcode, payload, max_payload_len, masking) end
-resty_websocket_protocol._VERSION="0.07"
+
+--- Receives a WebSocket frame from the wire.
+---@param sock tcpsock
+---@param max_payload_len interger
+---@param force_masking boolean
+---@return string? data
+---@return resty.websocket.protocol.type? typ
+---@return string? error
function resty_websocket_protocol.recv_frame(sock, max_payload_len, force_masking) end
+
return resty_websocket_protocol \ No newline at end of file
diff --git a/meta/3rd/OpenResty/library/resty.websocket.server.lua b/meta/3rd/OpenResty/library/resty.websocket.server.lua
index c9041a96..f590fcc8 100644
--- a/meta/3rd/OpenResty/library/resty.websocket.server.lua
+++ b/meta/3rd/OpenResty/library/resty.websocket.server.lua
@@ -1,13 +1,16 @@
---@meta
-resty_websocket_server={}
-function resty_websocket_server.send_text(self, data) end
-function resty_websocket_server.new(self, opts) end
-function resty_websocket_server.send_ping(self, data) end
-function resty_websocket_server.set_timeout(self, time) end
-function resty_websocket_server.send_binary(self, data) end
-function resty_websocket_server.send_frame() end
-function resty_websocket_server.recv_frame(self) end
-function resty_websocket_server.send_close(self, code, msg) end
-resty_websocket_server._VERSION="0.07"
-function resty_websocket_server.send_pong(self, data) end
+
+---@class resty.websocket.server : resty.websocket
+resty_websocket_server = {
+ _VERSION = "0.09"
+}
+
+---Performs the websocket handshake process on the server side and returns a WebSocket server object.
+---
+---In case of error, it returns nil and a string describing the error.
+---@param opts? resty.websocket.new.opts
+---@return resty.websocket.server? server
+---@return string? error
+function resty_websocket_server:new(opts) end
+
return resty_websocket_server \ No newline at end of file
diff --git a/meta/template/math.lua b/meta/template/math.lua
index f987eb0b..d9837424 100644
--- a/meta/template/math.lua
+++ b/meta/template/math.lua
@@ -87,7 +87,7 @@ function math.exp(x) end
---#DES 'math.floor'
---@param x number
----@return number
+---@return integer
---@nodiscard
function math.floor(x) end
diff --git a/script/core/completion/completion.lua b/script/core/completion/completion.lua
index dc005b52..d0bf5164 100644
--- a/script/core/completion/completion.lua
+++ b/script/core/completion/completion.lua
@@ -1064,14 +1064,14 @@ local function tryLabelInString(label, source)
if not source or source.type ~= 'string' then
return label
end
- local str = parser.grammar(label, 'String')
- if not str then
+ local state = parser.parse(label, 'String')
+ if not state or not state.ast then
return label
end
- if not matchKey(source[1], str[1]) then
+ if not matchKey(source[1], state.ast[1]) then
return nil
end
- return util.viewString(str[1], source[2])
+ return util.viewString(state.ast[1], source[2])
end
local function mergeEnums(a, b, source)
@@ -1354,20 +1354,6 @@ local function getCallEnumsAndFuncs(source, index, oop, call)
end
end
if source.type == 'doc.type.function' then
- --[[
- always use literal index, that is:
- ```
- ---@class Class
- ---@field f(x: number, y: boolean)
- local c
-
- c.f(1, true) -- correct
- c:f(1, true) -- also correct
- ```
- --]]
- if oop then
- index = index - 1
- end
local arg = source.args[index]
if arg and arg.extends then
return pushCallEnumsAndFuncs(vm.getDefs(arg.extends))
@@ -1959,6 +1945,7 @@ local function makeCache(uri, position, results)
cache.position= position
cache.word = word:lower()
cache.length = #word
+ cache.uri = uri
end
local function isValidCache(word, result)
@@ -1983,6 +1970,9 @@ local function getCache(uri, position)
if not cache.results then
return nil
end
+ if cache.uri ~= uri then
+ return nil
+ end
local text = files.getText(uri)
local state = files.getState(uri)
local word = lookBackward.findWord(text, guide.positionToOffset(state, position))
@@ -2058,6 +2048,9 @@ local function completion(uri, position, triggerCharacter)
await.delay()
tracy.ZoneBeginN 'completion #1'
local state = files.getState(uri)
+ if not state then
+ return nil
+ end
results = {}
clearStack()
tracy.ZoneEnd()
diff --git a/script/core/definition.lua b/script/core/definition.lua
index a1f46afc..eadae30f 100644
--- a/script/core/definition.lua
+++ b/script/core/definition.lua
@@ -4,6 +4,7 @@ local files = require 'files'
local vm = require 'vm'
local findSource = require 'core.find-source'
local guide = require 'parser.guide'
+local rpath = require 'workspace.require-path'
local function sortResults(results)
-- 先按照顺序排序
@@ -74,7 +75,7 @@ local function checkRequire(source, offset)
return nil
end
if libName == 'require' then
- return workspace.findUrisByRequirePath(literal)
+ return rpath.findUrisByRequirePath(literal)
elseif libName == 'dofile'
or libName == 'loadfile' then
return workspace.findUrisByFilePath(literal)
diff --git a/script/core/diagnostics/different-requires.lua b/script/core/diagnostics/different-requires.lua
index fd7415b6..3a49ceef 100644
--- a/script/core/diagnostics/different-requires.lua
+++ b/script/core/diagnostics/different-requires.lua
@@ -3,7 +3,7 @@ local guide = require 'parser.guide'
local lang = require 'language'
local config = require 'config'
local vm = require 'vm'
-local ws = require 'workspace'
+local rpath = require 'workspace.require-path'
return function (uri, callback)
local state = files.getState(uri)
@@ -21,7 +21,7 @@ return function (uri, callback)
return
end
local literal = arg1[1]
- local results = ws.findUrisByRequirePath(literal)
+ local results = rpath.findUrisByRequirePath(literal)
if not results or #results ~= 1 then
return
end
diff --git a/script/core/diagnostics/unused-local.lua b/script/core/diagnostics/unused-local.lua
index 072cbd31..7e7bd9d7 100644
--- a/script/core/diagnostics/unused-local.lua
+++ b/script/core/diagnostics/unused-local.lua
@@ -2,6 +2,7 @@ local files = require 'files'
local guide = require 'parser.guide'
local define = require 'proto.define'
local lang = require 'language'
+local vm = require 'vm.vm'
local function hasGet(loc)
if not loc.ref then
@@ -96,7 +97,7 @@ return function (uri, callback)
if isDocClass(source) then
return
end
- if isDocParam(source) then
+ if vm.isMetaFile(uri) and isDocParam(source) then
return
end
local data = hasGet(source)
diff --git a/script/core/hint.lua b/script/core/hint.lua
index b3aec88e..82c7371b 100644
--- a/script/core/hint.lua
+++ b/script/core/hint.lua
@@ -100,7 +100,7 @@ end
---@async
local function paramName(uri, results, start, finish)
local paramConfig = config.get(nil, 'Lua.hint.paramName')
- if not paramConfig or paramConfig == 'None' then
+ if not paramConfig or paramConfig == 'Disable' then
return
end
local state = files.getState(uri)
diff --git a/script/core/hover/arg.lua b/script/core/hover/arg.lua
index 4e6a1ace..d03f55f2 100644
--- a/script/core/hover/arg.lua
+++ b/script/core/hover/arg.lua
@@ -55,7 +55,7 @@ local function asFunction(source, oop)
end
end
-local function asDocFunction(source)
+local function asDocFunction(source, oop)
if not source.args then
return ''
end
@@ -69,7 +69,11 @@ local function asDocFunction(source)
arg.extends and infer.searchAndViewInfers(arg.extends) or 'any'
)
end
- return table.concat(args, ', ')
+ if oop then
+ return table.concat(args, ', ', 2)
+ else
+ return table.concat(args, ', ')
+ end
end
return function (source, oop)
@@ -77,7 +81,7 @@ return function (source, oop)
return asFunction(source, oop)
end
if source.type == 'doc.type.function' then
- return asDocFunction(source)
+ return asDocFunction(source, oop)
end
return ''
end
diff --git a/script/core/hover/description.lua b/script/core/hover/description.lua
index 51027aed..59605f0d 100644
--- a/script/core/hover/description.lua
+++ b/script/core/hover/description.lua
@@ -9,12 +9,13 @@ local lang = require 'language'
local util = require 'utility'
local guide = require 'parser.guide'
local noder = require 'core.noder'
+local rpath = require 'workspace.require-path'
local function collectRequire(mode, literal)
local rootPath = ws.rootPath or ''
local result, searchers
if mode == 'require' then
- result, searchers = ws.findUrisByRequirePath(literal)
+ result, searchers = rpath.findUrisByRequirePath(literal)
elseif mode == 'dofile'
or mode == 'loadfile' then
result = ws.findUrisByFilePath(literal)
@@ -63,7 +64,7 @@ end
local function asStringView(source, literal)
-- 内部包含转义符?
- local rawLen = source.finish - source.start - 2 * #source[2] + 1
+ local rawLen = source.finish - source.start - 2 * #source[2]
if config.get(nil, 'Lua.hover.viewString')
and (source[2] == '"' or source[2] == "'")
and rawLen > #literal then
diff --git a/script/core/hover/init.lua b/script/core/hover/init.lua
index 7d99a006..baa24139 100644
--- a/script/core/hover/init.lua
+++ b/script/core/hover/init.lua
@@ -6,6 +6,7 @@ local util = require 'utility'
local findSource = require 'core.find-source'
local markdown = require 'provider.markdown'
local infer = require 'core.infer'
+local guide = require 'parser.guide'
---@async
local function getHover(source)
@@ -15,14 +16,14 @@ local function getHover(source)
local descMark = {}
---@async
- local function addHover(def, checkLable)
+ local function addHover(def, checkLable, oop)
if defMark[def] then
return
end
defMark[def] = true
if checkLable then
- local label = getLabel(def)
+ local label = getLabel(def, oop)
if not labelMark[tostring(label)] then
labelMark[tostring(label)] = true
md:add('lua', label)
@@ -38,27 +39,34 @@ local function getHover(source)
end
end
+ local oop
if infer.searchAndViewInfers(source) == 'function' then
local hasFunc
for _, def in ipairs(vm.getDefs(source)) do
+ if guide.isOOP(def) then
+ oop = true
+ end
if def.type == 'function'
or def.type == 'doc.type.function' then
hasFunc = true
- addHover(def, true)
+ addHover(def, true, oop)
end
end
if not hasFunc then
- addHover(source, true)
+ addHover(source, true, oop)
end
else
- addHover(source, true)
+ addHover(source, true, oop)
for _, def in ipairs(vm.getDefs(source)) do
+ if guide.isOOP(def) then
+ oop = true
+ end
local isFunction
if def.type == 'function'
or def.type == 'doc.type.function' then
isFunction = true
end
- addHover(def, isFunction)
+ addHover(def, isFunction, oop)
end
end
diff --git a/script/core/hover/label.lua b/script/core/hover/label.lua
index f797d520..436ff913 100644
--- a/script/core/hover/label.lua
+++ b/script/core/hover/label.lua
@@ -11,30 +11,20 @@ local files = require 'files'
local guide = require 'parser.guide'
local function asFunction(source, oop)
- local name
- name, oop = buildName(source, oop)
+ local name = buildName(source, oop)
local arg = buildArg(source, oop)
local rtn = buildReturn(source)
local lines = {}
- lines[1] = ('%s%s %s(%s)'):format(
- vm.isAsync(source) and 'async ' or '',
- oop and 'method' or 'function',
- name or '', arg
+ lines[1] = string.format('%s%s %s(%s)'
+ , vm.isAsync(source) and 'async ' or ''
+ , oop and 'method' or 'function'
+ , name or ''
+ , arg
)
lines[2] = rtn
return table.concat(lines, '\n')
end
-local function asDocFunction(source)
- local name = buildName(source)
- local arg = buildArg(source)
- local rtn = buildReturn(source)
- local lines = {}
- lines[1] = ('function %s(%s)'):format(name or '', arg)
- lines[2] = rtn
- return table.concat(lines, '\n')
-end
-
local function asDocTypeName(source)
local defs = vm.getDefs(source)
for _, doc in ipairs(defs) do
@@ -188,7 +178,8 @@ end
---@async
return function (source, oop)
- if source.type == 'function' then
+ if source.type == 'function'
+ or source.type == 'doc.type.function' then
return asFunction(source, oop)
elseif source.type == 'local'
or source.type == 'getlocal'
@@ -210,8 +201,6 @@ return function (source, oop)
elseif source.type == 'number'
or source.type == 'integer' then
return asNumber(source)
- elseif source.type == 'doc.type.function' then
- return asDocFunction(source)
elseif source.type == 'doc.type.name' then
return asDocTypeName(source)
elseif source.type == 'doc.field.name' then
diff --git a/script/core/hover/name.lua b/script/core/hover/name.lua
index 0de13c9a..5d8f0b3d 100644
--- a/script/core/hover/name.lua
+++ b/script/core/hover/name.lua
@@ -46,14 +46,14 @@ local function asGlobal(source)
return guide.getKeyName(source)
end
-local function asDocFunction(source)
+local function asDocFunction(source, oop)
local doc = guide.getParentType(source, 'doc.type')
or guide.getParentType(source, 'doc.overload')
if not doc or not doc.bindSources then
return ''
end
for _, src in ipairs(doc.bindSources) do
- local name = buildName(src)
+ local name = buildName(src, oop)
if name ~= '' then
return name
end
@@ -66,11 +66,6 @@ local function asDocField(source)
end
function buildName(source, oop)
- if oop == nil then
- oop = source.type == 'setmethod'
- or source.type == 'getmethod'
- or nil
- end
if source.type == 'local' then
return asLocal(source) or '', oop
end
@@ -94,7 +89,7 @@ function buildName(source, oop)
return asTableField(source) or '', oop
end
if source.type == 'doc.type.function' then
- return asDocFunction(source), oop
+ return asDocFunction(source, oop), oop
end
if source.type == 'doc.field' then
return asDocField(source), oop
diff --git a/script/core/infer.lua b/script/core/infer.lua
index 9166168b..9bb1e447 100644
--- a/script/core/infer.lua
+++ b/script/core/infer.lua
@@ -28,6 +28,7 @@ local function mergeTable(a, b)
for v in pairs(b) do
a[v] = true
end
+ a[CACHE] = nil
end
local function isBaseType(source, mark)
@@ -519,6 +520,9 @@ end
---@param mark? table
---@return table
function m.searchLiterals(source, field, mark)
+ if not source then
+ return nil
+ end
local defs = vm.getDefs(source, field)
local literals = {}
mark = mark or {}
@@ -540,6 +544,9 @@ function m.searchAndViewLiterals(source, field, mark)
return nil
end
local literals = m.searchLiterals(source, field, mark)
+ if not literals then
+ return nil
+ end
local view = m.viewLiterals(literals)
return view
end
@@ -558,10 +565,12 @@ function m.isTrue(source, mark)
if mark.isTrue[source] == nil then
mark.isTrue[source] = false
local literals = m.searchLiterals(source, nil, mark)
- for literal in pairs(literals) do
- if literal ~= false then
- mark.isTrue[source] = true
- break
+ if literals then
+ for literal in pairs(literals) do
+ if literal ~= false then
+ mark.isTrue[source] = true
+ break
+ end
end
end
end
diff --git a/script/core/searcher.lua b/script/core/searcher.lua
index 1f4091b3..8e4873aa 100644
--- a/script/core/searcher.lua
+++ b/script/core/searcher.lua
@@ -2,7 +2,7 @@ local noder = require 'core.noder'
local guide = require 'parser.guide'
local files = require 'files'
local generic = require 'core.generic'
-local ws = require 'workspace'
+local rpath = require 'workspace.require-path'
local vm = require 'vm.vm'
local collector = require 'core.collector'
local util = require 'utility'
@@ -796,7 +796,7 @@ function m.searchRefsByID(status, suri, expect, mode)
if not requireName then
return
end
- local uris = ws.findUrisByRequirePath(requireName)
+ local uris = rpath.findUrisByRequirePath(requireName)
footprint(status, 'require:', requireName)
for i = 1, #uris do
local ruri = uris[i]
diff --git a/script/core/type-definition.lua b/script/core/type-definition.lua
index dee07c61..e9cf3e47 100644
--- a/script/core/type-definition.lua
+++ b/script/core/type-definition.lua
@@ -5,6 +5,7 @@ local vm = require 'vm'
local findSource = require 'core.find-source'
local guide = require 'parser.guide'
local infer = require 'core.infer'
+local rpath = require 'workspace.require-path'
local function sortResults(results)
-- 先按照顺序排序
@@ -75,7 +76,7 @@ local function checkRequire(source, offset)
return nil
end
if libName == 'require' then
- return workspace.findUrisByRequirePath(literal)
+ return rpath.findUrisByRequirePath(literal)
elseif libName == 'dofile'
or libName == 'loadfile' then
return workspace.findUrisByFilePath(literal)
diff --git a/script/encoder/utf16.lua b/script/encoder/utf16.lua
index 744da174..7b08e082 100644
--- a/script/encoder/utf16.lua
+++ b/script/encoder/utf16.lua
@@ -92,6 +92,8 @@ local function utf8next(s, n)
return n+3, utf8byte(s, n)
elseif strmatch(s, "^[\xED][\x80-\x9F][\x80-\xBF]", n) then
return n+3, utf8byte(s, n)
+ elseif strmatch(s, "^[\xEE-\xEF][\x80-\xBF][\x80-\xBF]", n) then
+ return n+3, utf8byte(s, n)
elseif strmatch(s, "^[\xF0][\x90-\xBF][\x80-\xBF][\x80-\xBF]", n) then
return n+4, utf8byte(s, n)
elseif strmatch(s, "^[\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF]", n) then
diff --git a/script/library.lua b/script/library.lua
index ef62ceab..cddb19fd 100644
--- a/script/library.lua
+++ b/script/library.lua
@@ -221,8 +221,13 @@ local function initBuiltIn()
end
m.metaPath = metaPath:string()
m.metaPaths = {}
- if not fs.exists(metaPath) then
- fs.create_directories(metaPath)
+ local suc = xpcall(function ()
+ if not fs.exists(metaPath) then
+ fs.create_directories(metaPath)
+ end
+ end, log.error)
+ if not suc then
+ return
end
local out = fsu.dummyFS()
local templateDir = ROOT / 'meta' / 'template'
@@ -462,7 +467,9 @@ local function check3rd(uri)
if checkedUri(uri) then
if files.isLua(uri) then
local text = files.getText(uri)
- check3rdByWords(text, thirdConfigs)
+ if text then
+ check3rdByWords(text, thirdConfigs)
+ end
end
check3rdByFileName(uri, thirdConfigs)
end
diff --git a/script/log.lua b/script/log.lua
index c3bf02d4..90de895a 100644
--- a/script/log.lua
+++ b/script/log.lua
@@ -12,8 +12,6 @@ local mathModf = math.modf
local debugGetInfo = debug.getinfo
local ioStdErr = io.stderr
-_ENV = nil
-
local m = {}
m.file = nil
@@ -91,9 +89,6 @@ function m.raw(thd, level, msg, source, currentline, clock)
return
end
init_log_file()
- if not m.file then
- return ''
- end
local sec, ms = mathModf((m.startTime + clock) / 1000)
local timestr = osDate('%H:%M:%S', sec)
local agl = ''
@@ -107,11 +102,13 @@ function m.raw(thd, level, msg, source, currentline, clock)
buf = ('[%s.%03.f][%s]%s[#%d:%s:%s]: %s\n'):format(timestr, ms * 1000, level, agl, thd, trimSrc(source), currentline, msg)
end
m.size = m.size + #buf
- if m.size > m.maxSize then
- m.file:write(buf:sub(1, m.size - m.maxSize))
- m.file:write('[REACH MAX SIZE]')
- else
- m.file:write(buf)
+ if m.file then
+ if m.size > m.maxSize then
+ m.file:write(buf:sub(1, m.size - m.maxSize))
+ m.file:write('[REACH MAX SIZE]')
+ else
+ m.file:write(buf)
+ end
end
return buf
end
@@ -130,9 +127,11 @@ function m.init(root, path)
m.path = path:string()
m.prefixLen = #root:string()
m.size = 0
- if not fs.exists(path:parent_path()) then
- fs.create_directories(path:parent_path())
- end
+ pcall(function ()
+ if not fs.exists(path:parent_path()) then
+ fs.create_directories(path:parent_path())
+ end
+ end)
if lastBuf then
init_log_file()
if m.file then
diff --git a/script/parser/guide.lua b/script/parser/guide.lua
index 54e61e7f..d55ba099 100644
--- a/script/parser/guide.lua
+++ b/script/parser/guide.lua
@@ -1160,5 +1160,17 @@ function m.isInString(ast, position)
end)
end
+function m.isOOP(source)
+ if source.type == 'setmethod'
+ or source.type == 'getmethod' then
+ return true
+ end
+ if source.type == 'method'
+ or source.type == 'field'
+ or source.type == 'function' then
+ return m.isOOP(source.parent)
+ end
+ return false
+end
return m
diff --git a/script/parser/luadoc.lua b/script/parser/luadoc.lua
index bfadcf8a..4d46d674 100644
--- a/script/parser/luadoc.lua
+++ b/script/parser/luadoc.lua
@@ -4,7 +4,7 @@ local guide = require 'parser.guide'
local parser = require 'parser.newparser'
local TokenTypes, TokenStarts, TokenFinishs, TokenContents, TokenMarks
-local Ci, Offset, pushError, NextComment, Lines
+local Ci, Offset, pushWarning, NextComment, Lines
local parseType
local Parser = re.compile([[
Main <- (Token / Sp)*
@@ -204,7 +204,7 @@ local function nextSymbolOrError(symbol)
nextToken()
return true
end
- pushError {
+ pushWarning {
type = 'LUADOC_MISS_SYMBOL',
start = getFinish(),
finish = getFinish(),
@@ -229,7 +229,7 @@ local function parseIndexField(tp, parent)
local indexTP, index = nextToken()
if indexTP ~= 'integer'
and indexTP ~= 'string' then
- pushError {
+ pushWarning {
type = 'LUADOC_INDEX_MUST_INT',
start = getStart(),
finish = getFinish(),
@@ -249,7 +249,7 @@ local function parseClass(parent)
}
result.class = parseName('doc.class.name', result)
if not result.class then
- pushError {
+ pushWarning {
type = 'LUADOC_MISS_CLASS_NAME',
start = getFinish(),
finish = getFinish(),
@@ -268,7 +268,7 @@ local function parseClass(parent)
while true do
local extend = parseName('doc.extends.name', result)
if not extend then
- pushError {
+ pushWarning {
type = 'LUADOC_MISS_CLASS_EXTENDS_NAME',
start = getFinish(),
finish = getFinish(),
@@ -371,7 +371,7 @@ local function parseTypeUnitFunction()
arg.name = parseName('doc.type.name', arg)
or parseDots('doc.type.name', arg)
if not arg.name then
- pushError {
+ pushWarning {
type = 'LUADOC_MISS_ARG_NAME',
start = getFinish(),
finish = getFinish(),
@@ -443,7 +443,7 @@ local function parseTypeUnitLiteralTable()
field.name = parseName('doc.field.name', field)
or parseIndexField('doc.field.name', field)
if not field.name then
- pushError {
+ pushWarning {
type = 'LUADOC_MISS_FIELD_NAME',
start = getFinish(),
finish = getFinish(),
@@ -480,7 +480,9 @@ local function parseTypeUnitLiteralTable()
return typeUnit
end
-local function parseTypeUnit(parent, content)
+local parseTypeUnit
+
+local function parseDocFunction(parent, content)
if content == 'async' then
local tp, cont = peekToken()
if tp == 'name' then
@@ -494,12 +496,17 @@ local function parseTypeUnit(parent, content)
end
end
end
- local result
if content == 'fun' then
- result = parseTypeUnitFunction()
+ return parseTypeUnitFunction()
end
- if content == '{' then
- result = parseTypeUnitLiteralTable()
+end
+
+function parseTypeUnit(parent, content)
+ local result = parseDocFunction(parent, content)
+ if not result then
+ if content == '{' then
+ result = parseTypeUnitLiteralTable()
+ end
end
if not result then
result = {
@@ -542,7 +549,7 @@ local function parseResume(parent)
local tp = peekToken()
if tp ~= 'string' then
- pushError {
+ pushWarning {
type = 'LUADOC_MISS_STRING',
start = getFinish(),
finish = getFinish(),
@@ -709,7 +716,7 @@ function parseType(parent)
end
if #result.types == 0 and #result.enums == 0 and #result.resumes == 0 then
- pushError {
+ pushWarning {
type = 'LUADOC_MISS_TYPE_NAME',
start = getFinish(),
finish = getFinish(),
@@ -725,7 +732,7 @@ local function parseAlias()
}
result.alias = parseName('doc.alias.name', result)
if not result.alias then
- pushError {
+ pushWarning {
type = 'LUADOC_MISS_ALIAS_NAME',
start = getFinish(),
finish = getFinish(),
@@ -735,7 +742,7 @@ local function parseAlias()
result.start = getStart()
result.extends = parseType(result)
if not result.extends then
- pushError {
+ pushWarning {
type = 'LUADOC_MISS_ALIAS_EXTENDS',
start = getFinish(),
finish = getFinish(),
@@ -753,7 +760,7 @@ local function parseParam()
result.param = parseName('doc.param.name', result)
or parseDots('doc.param.name', result)
if not result.param then
- pushError {
+ pushWarning {
type = 'LUADOC_MISS_PARAM_NAME',
start = getFinish(),
finish = getFinish(),
@@ -768,7 +775,7 @@ local function parseParam()
result.finish = getFinish()
result.extends = parseType(result)
if not result.extends then
- pushError {
+ pushWarning {
type = 'LUADOC_MISS_PARAM_EXTENDS',
start = getFinish(),
finish = getFinish(),
@@ -831,7 +838,7 @@ local function parseField()
result.field = parseName('doc.field.name', result)
or parseIndexField('doc.field.name', result)
if not result.field then
- pushError {
+ pushWarning {
type = 'LUADOC_MISS_FIELD_NAME',
start = getFinish(),
finish = getFinish(),
@@ -847,7 +854,7 @@ local function parseField()
end
result.extends = parseType(result)
if not result.extends then
- pushError {
+ pushWarning {
type = 'LUADOC_MISS_FIELD_EXTENDS',
start = getFinish(),
finish = getFinish(),
@@ -870,7 +877,7 @@ local function parseGeneric()
}
object.generic = parseName('doc.generic.name', object)
if not object.generic then
- pushError {
+ pushWarning {
type = 'LUADOC_MISS_GENERIC_NAME',
start = getFinish(),
finish = getFinish(),
@@ -902,7 +909,7 @@ local function parseVararg()
}
result.vararg = parseType(result)
if not result.vararg then
- pushError {
+ pushWarning {
type = 'LUADOC_MISS_VARARG_TYPE',
start = getFinish(),
finish = getFinish(),
@@ -916,8 +923,9 @@ end
local function parseOverload()
local tp, name = peekToken()
- if tp ~= 'name' or name ~= 'fun' then
- pushError {
+ if tp ~= 'name'
+ or (name ~= 'fun' and name ~= 'async') then
+ pushWarning {
type = 'LUADOC_MISS_FUN_AFTER_OVERLOAD',
start = getFinish(),
finish = getFinish(),
@@ -928,7 +936,7 @@ local function parseOverload()
local result = {
type = 'doc.overload',
}
- result.overload = parseTypeUnitFunction()
+ result.overload = parseDocFunction(result, name)
if not result.overload then
return nil
end
@@ -962,7 +970,7 @@ local function parseVersion()
while true do
local tp, text = nextToken()
if not tp then
- pushError {
+ pushWarning {
type = 'LUADOC_MISS_VERSION',
start = getFinish(),
finish = getFinish(),
@@ -985,7 +993,7 @@ local function parseVersion()
tp, text = nextToken()
end
if tp ~= 'name' then
- pushError {
+ pushWarning {
type = 'LUADOC_MISS_VERSION',
start = getStart(),
finish = getFinish(),
@@ -1031,7 +1039,7 @@ local function parseDiagnostic()
}
local nextTP, mode = nextToken()
if nextTP ~= 'name' then
- pushError {
+ pushWarning {
type = 'LUADOC_MISS_DIAG_MODE',
start = getFinish(),
finish = getFinish(),
@@ -1045,7 +1053,7 @@ local function parseDiagnostic()
and mode ~= 'disable-line'
and mode ~= 'disable'
and mode ~= 'enable' then
- pushError {
+ pushWarning {
type = 'LUADOC_ERROR_DIAG_MODE',
start = result.start,
finish = result.finish,
@@ -1058,7 +1066,7 @@ local function parseDiagnostic()
while true do
local name = parseName('doc.diagnostic.name', result)
if not name then
- pushError {
+ pushWarning {
type = 'LUADOC_MISS_DIAG_NAME',
start = getFinish(),
finish = getFinish(),
@@ -1092,7 +1100,7 @@ local function parseModule()
result.finish = getFinish()
result.smark = getMark()
else
- pushError {
+ pushWarning {
type = 'LUADOC_MISS_MODULE_NAME',
start = getFinish(),
finish = getFinish(),
@@ -1123,7 +1131,7 @@ local function convertTokens()
return
end
if tp ~= 'name' then
- pushError {
+ pushWarning {
type = 'LUADOC_MISS_CATE_NAME',
start = getStart(),
finish = getFinish(),
@@ -1420,8 +1428,11 @@ return function (state)
groups = {},
}
- pushError = state.pushError
- Lines = state.lines
+ pushWarning = function (err)
+ err.level = err.level or 'Warning'
+ state.pushError(err)
+ end
+ Lines = state.lines
local ci = 1
NextComment = function (offset, peek)
diff --git a/script/parser/newparser.lua b/script/parser/newparser.lua
index 187de9b3..15d2d600 100644
--- a/script/parser/newparser.lua
+++ b/script/parser/newparser.lua
@@ -942,7 +942,7 @@ local function parseShortString()
end
if not token then
stringIndex = stringIndex + 1
- stringPool[stringIndex] = ssub(Lua, currentOffset)
+ stringPool[stringIndex] = ssub(Lua, currentOffset or -1)
missSymbol(mark)
break
end
@@ -1649,11 +1649,13 @@ local function parseTable()
wantSep = true
local tindex = parseIndex()
skipSpace()
+ tindex.type = 'tableindex'
+ tindex.parent = tbl
+ index = index + 1
+ tbl[index] = tindex
if expectAssign() then
skipSpace()
local ivalue = parseExp()
- tindex.type = 'tableindex'
- tindex.parent = tbl
if ivalue then
ivalue.parent = tindex
tindex.finish = ivalue.finish
@@ -1661,8 +1663,6 @@ local function parseTable()
else
missExp()
end
- index = index + 1
- tbl[index] = tindex
else
missSymbol '='
end
@@ -3714,7 +3714,7 @@ local function initState(lua, version, options)
return
end
end
- err.level = err.level or 'error'
+ err.level = err.level or 'Error'
errs[#errs+1] = err
return err
end
diff --git a/script/provider/diagnostic.lua b/script/provider/diagnostic.lua
index a6724a29..fb9a745e 100644
--- a/script/provider/diagnostic.lua
+++ b/script/provider/diagnostic.lua
@@ -58,7 +58,7 @@ local function buildSyntaxError(uri, err)
return {
code = err.type:lower():gsub('_', '-'),
range = converter.packRange(uri, err.start, err.finish),
- severity = define.DiagnosticSeverity.Error,
+ severity = define.DiagnosticSeverity[err.level],
source = lang.script.DIAG_SYNTAX_CHECK,
message = message,
relatedInformation = relatedInformation,
diff --git a/script/vm/getLinks.lua b/script/vm/getLinks.lua
index b245bdaa..77d869f8 100644
--- a/script/vm/getLinks.lua
+++ b/script/vm/getLinks.lua
@@ -2,9 +2,9 @@ local guide = require 'parser.guide'
---@class vm
local vm = require 'vm.vm'
local files = require 'files'
+local rpath = require 'workspace.require-path'
local function getFileLinks(uri)
- local ws = require 'workspace'
local links = {}
local state = files.getState(uri)
if not state then
@@ -20,7 +20,7 @@ local function getFileLinks(uri)
if not args or not args[1] or args[1].type ~= 'string' then
return
end
- local uris = ws.findUrisByRequirePath(args[1][1])
+ local uris = rpath.findUrisByRequirePath(args[1][1])
for _, u in ipairs(uris) do
if not links[u] then
links[u] = {}
diff --git a/script/workspace/require-path.lua b/script/workspace/require-path.lua
index e6bb6c78..04c8abf8 100644
--- a/script/workspace/require-path.lua
+++ b/script/workspace/require-path.lua
@@ -30,7 +30,7 @@ end
function m.getVisiblePath(path)
local searchers = config.get(nil, 'Lua.runtime.path')
local strict = config.get(nil, 'Lua.runtime.pathStrict')
- path = path:gsub('^[/\\]+', '')
+ path = workspace.normalize(path)
local uri = furi.encode(path)
local libraryPath = files.getLibraryPath(uri)
if not m.cache[path] then
@@ -42,6 +42,7 @@ function m.getVisiblePath(path)
for _, searcher in ipairs(searchers) do
local isAbsolute = searcher:match '^[/\\]'
or searcher:match '^%a+%:'
+ searcher = workspace.normalize(searcher)
local cutedPath = path
local currentPath = path
local head
@@ -59,10 +60,8 @@ function m.getVisiblePath(path)
pos = currentPath:match('[/\\]+()', pos)
if platform.OS == 'Windows' then
searcher = searcher :gsub('[/\\]+', '\\')
- :gsub('^[/\\]+', '')
else
searcher = searcher :gsub('[/\\]+', '/')
- :gsub('^[/\\]+', '')
end
local expect = getOnePath(cutedPath, searcher)
if expect then
@@ -81,6 +80,50 @@ function m.getVisiblePath(path)
return m.cache[path]
end
+--- 查找符合指定require path的所有uri
+---@param path string
+function m.findUrisByRequirePath(path)
+ if type(path) ~= 'string' then
+ return {}
+ end
+ local separator = config.get 'Lua.completion.requireSeparator'
+ local fspath = path:gsub('%' .. separator, '/')
+ local vm = require 'vm'
+ local cache = vm.getCache 'findUrisByRequirePath'
+ if cache[path] then
+ return cache[path].results, cache[path].searchers
+ end
+ tracy.ZoneBeginN('findUrisByRequirePath')
+ local results = {}
+ local searchers = {}
+ for uri in files.eachDll() do
+ local opens = files.getDllOpens(uri) or {}
+ for _, open in ipairs(opens) do
+ if open == fspath then
+ results[#results+1] = uri
+ end
+ end
+ end
+
+ for uri in files.eachFile() do
+ local infos = m.getVisiblePath(furi.decode(uri))
+ for _, info in ipairs(infos) do
+ local fsexpect = info.expect:gsub('%' .. separator, '/')
+ if fsexpect == fspath then
+ results[#results+1] = uri
+ searchers[uri] = info.searcher
+ end
+ end
+ end
+
+ tracy.ZoneEnd()
+ cache[path] = {
+ results = results,
+ searchers = searchers,
+ }
+ return results, searchers
+end
+
function m.flush()
m.cache = {}
end
diff --git a/script/workspace/workspace.lua b/script/workspace/workspace.lua
index 12971ae5..a2f99b3e 100644
--- a/script/workspace/workspace.lua
+++ b/script/workspace/workspace.lua
@@ -262,89 +262,20 @@ function m.findUrisByFilePath(path)
if type(path) ~= 'string' then
return {}
end
- local lpath = furi.encode(path):gsub('^file:///', '')
+ local myUri = furi.encode(path)
local vm = require 'vm'
local resultCache = vm.getCache 'findUrisByRequirePath.result'
if resultCache[path] then
- return resultCache[path].results, resultCache[path].posts
+ return resultCache[path]
end
- tracy.ZoneBeginN('findUrisByFilePath #1')
- local strict = config.get(nil, 'Lua.runtime.pathStrict')
local results = {}
- local posts = {}
for uri in files.eachFile() do
- if not uri:find(lpath, 1, true) then
- goto CONTINUE
- end
- local relat = m.getRelativePath(uri)
- local pathLen = #path
- local curPath = relat
- local curLen = #curPath
- local seg = curPath:sub(curLen - pathLen, curLen - pathLen)
- if seg == '/' or seg == '\\' or seg == '' then
- if strict and seg ~= '' then
- goto CONTINUE
- end
- local see = curPath:sub(curLen - pathLen + 1, curLen)
- if see == path then
- results[#results+1] = uri
- local post = curPath:sub(1, curLen - pathLen)
- posts[uri] = post:gsub('^[/\\]+', '')
- end
- end
- ::CONTINUE::
- end
- tracy.ZoneEnd()
- resultCache[path] = {
- results = results,
- posts = posts,
- }
- return results, posts
-end
-
---- 查找符合指定require path的所有uri
----@param path string
-function m.findUrisByRequirePath(path)
- if type(path) ~= 'string' then
- return {}
- end
- local vm = require 'vm'
- local cache = vm.getCache 'findUrisByRequirePath'
- if cache[path] then
- return cache[path].results, cache[path].searchers
- end
- tracy.ZoneBeginN('findUrisByRequirePath')
- local results = {}
- local mark = {}
- local searchers = {}
- for uri in files.eachDll() do
- local opens = files.getDllOpens(uri) or {}
- for _, open in ipairs(opens) do
- if open == path then
- results[#results+1] = uri
- end
- end
- end
-
- local input = path:gsub('%.', '/')
- :gsub('%%', '%%%%')
- for _, luapath in ipairs(config.get(nil, 'Lua.runtime.path')) do
- local part = m.normalize(luapath:gsub('%?', input))
- local uris, posts = m.findUrisByFilePath(part)
- for _, uri in ipairs(uris) do
- if not mark[uri] then
- mark[uri] = true
- results[#results+1] = uri
- searchers[uri] = posts[uri] .. luapath
- end
+ if uri == myUri then
+ results[#results+1] = uri
end
end
- tracy.ZoneEnd()
- cache[path] = {
- results = results,
- searchers = searchers,
- }
- return results, searchers
+ resultCache[path] = results
+ return results
end
function m.normalize(path)
@@ -361,6 +292,7 @@ function m.normalize(path)
end
end)
path = util.expandPath(path)
+ path = path:gsub('^%.[/\\]+', '')
if platform.OS == 'Windows' then
path = path:gsub('[/\\]+', '\\')
:gsub('[/\\]+$', '')
diff --git a/test.lua b/test.lua
index 8bf17e8b..48cccee4 100644
--- a/test.lua
+++ b/test.lua
@@ -2,7 +2,7 @@ package.path = package.path
.. ';./test/?.lua'
.. ';./test/?/init.lua'
local fs = require 'bee.filesystem'
-local rootPath = fs.exe_path():parent_path():parent_path():parent_path():string()
+local rootPath = fs.exe_path():parent_path():parent_path():string()
ROOT = fs.path(rootPath)
TEST = true
DEVELOP = true
diff --git a/test/completion/common.lua b/test/completion/common.lua
index 94b55514..b03d55ca 100644
--- a/test/completion/common.lua
+++ b/test/completion/common.lua
@@ -2593,7 +2593,7 @@ c:<??>
TEST [[
---@class Class
----@field on fun(x: "'aaa'"|"'bbb'")
+---@field on fun(self, x: "'aaa'"|"'bbb'")
local c
c:on(<??>)
@@ -2605,7 +2605,7 @@ TEST [[
---@field on fun(x: "'aaa'"|"'bbb'")
local c
-c:on('<??>')
+c.on('<??>')
]]
(EXISTS)
@@ -3037,3 +3037,26 @@ end)
}
},
}
+
+TEST [[
+---@meta
+
+---@alias testAlias
+---| "'test1'"
+---| "'test2'"
+---| "'test3'"
+
+---@class TestClass
+local TestClass = {}
+
+---@overload fun(self: TestClass, arg2: testAlias)
+---@param arg1 integer
+---@param arg2 testAlias
+function TestClass:testFunc2(arg1, arg2) end
+
+---@type TestClass
+local t
+
+t:testFunc2(<??>)
+]]
+(EXISTS)
diff --git a/test/crossfile/definition.lua b/test/crossfile/definition.lua
index 8f4dd7e8..c9a95658 100644
--- a/test/crossfile/definition.lua
+++ b/test/crossfile/definition.lua
@@ -867,3 +867,93 @@ print(t.<?x?>)
]]
}
}
+
+local originRuntimePath = config.get 'Lua.runtime.path'
+
+config.set('Lua.runtime.path', {
+ './?.lua'
+})
+TEST {
+ {
+ path = 'a.lua',
+ content = [[
+return {
+ <!x!> = 1,
+}
+]],
+ },
+ {
+ path = 'b.lua',
+ content = [[
+local t = require 'a'
+print(t.<?x?>)
+ ]]
+ }
+}
+
+config.set('Lua.runtime.path', {
+ '/home/?.lua'
+})
+TEST {
+ {
+ path = '/home/a.lua',
+ content = [[
+return {
+ <!x!> = 1,
+}
+]],
+ },
+ {
+ path = 'b.lua',
+ content = [[
+local t = require 'a'
+print(t.<?x?>)
+ ]]
+ }
+}
+
+config.set('Lua.runtime.pathStrict', true)
+config.set('Lua.runtime.path', {
+ './?.lua'
+})
+TEST {
+ {
+ path = 'a.lua',
+ content = [[
+return {
+ <!x!> = 1,
+}
+]],
+ },
+ {
+ path = 'b.lua',
+ content = [[
+local t = require 'a'
+print(t.<?x?>)
+ ]]
+ }
+}
+
+config.set('Lua.runtime.path', {
+ '/home/?.lua'
+})
+TEST {
+ {
+ path = '/home/a.lua',
+ content = [[
+return {
+ <!x!> = 1,
+}
+]],
+ },
+ {
+ path = 'b.lua',
+ content = [[
+local t = require 'a'
+print(t.<?x?>)
+ ]]
+ }
+}
+
+config.set('Lua.runtime.pathStrict', false)
+config.set('Lua.runtime.path', originRuntimePath)
diff --git a/test/crossfile/hover.lua b/test/crossfile/hover.lua
index 86471936..492efe43 100644
--- a/test/crossfile/hover.lua
+++ b/test/crossfile/hover.lua
@@ -41,20 +41,17 @@ end
function TEST(expect)
files.removeAll()
- local targetScript, targetList = catch(expect[1].content, '?')
- local targetUri = furi.encode(expect[1].path)
-
- local sourceScript, sourceList = catch(expect[2].content, '?')
- local sourceUri = furi.encode(expect[2].path)
-
- files.setText(targetUri, targetScript)
- files.setText(sourceUri, sourceScript)
-
- if targetList['?'] then
- local targetPos = (targetList['?'][1][1] + targetList['?'][1][2]) // 2
- core.byUri(targetUri, targetPos)
+ local sourcePos, sourceUri
+ for _, file in ipairs(expect) do
+ local script, list = catch(file.content, '?')
+ local uri = furi.encode(file.path)
+ files.setText(uri, script)
+ if list['?'] then
+ sourceUri = uri
+ sourcePos = (list['?'][1][1] + list['?'][1][2]) // 2
+ end
end
- local sourcePos = (sourceList['?'][1][1] + sourceList['?'][1][2]) // 2
+
local hover = core.byUri(sourceUri, sourcePos)
assert(hover)
hover = tostring(hover):gsub('\r\n', '\n')
@@ -1075,3 +1072,64 @@ global G: A {
}
```]]
}
+
+TEST {
+ {
+ path = 'a.lua',
+ content = [[
+ ---@overload fun(self, a)
+ function C:<?f?>(a, b) end
+ ]]
+ },
+ hover = [[
+```lua
+method C:f(a: any, b: any)
+```
+
+---
+
+```lua
+method C:f(a: any)
+```]]
+}
+
+TEST {
+ {
+ path = 'a.lua',
+ content = [[
+ ---@overload fun(self, a)
+ function C.<?f?>(a, b) end
+ ]]
+ },
+ hover = [[
+```lua
+function C.f(a: any, b: any)
+```
+
+---
+
+```lua
+function C.f(self: any, a: any)
+```]]
+}
+
+TEST {
+ {
+ path = 'a.lua',
+ content = [[
+ ---@async
+ ---@overload async fun(self, a)
+ function C:<?f?>(a, b) end
+ ]]
+ },
+ hover = [[
+```lua
+async method C:f(a: any, b: any)
+```
+
+---
+
+```lua
+async method C:f(a: any)
+```]]
+}
diff --git a/test/diagnostics/init.lua b/test/diagnostics/init.lua
index f95c0bad..16c85a63 100644
--- a/test/diagnostics/init.lua
+++ b/test/diagnostics/init.lua
@@ -975,6 +975,14 @@ end
TEST [[
---@param a number
+return function (<!a!>)
+end
+]]
+
+TEST [[
+---@meta
+
+---@param a number
return function (a)
end
]]
@@ -1154,6 +1162,7 @@ TEST [[
local emit = {}
]]
+config.get 'Lua.diagnostics.neededFileStatus' ['unused-local'] = 'None'
TEST [[
---@param table table
---@param metatable table
@@ -1292,6 +1301,8 @@ trim('str', 'left')
trim('str', nil)
]]
+config.get 'Lua.diagnostics.neededFileStatus' ['unused-local'] = 'Any'
+
---不完整的函数参数定义,会跳过检查
TEST [[
---@param mode string