-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Fix solidity error parser. Fixes #4896. #4962
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
This pull request has been automatically marked as stale because it has not been updated recently. Make sure to write tests and document your changes. See |
|
Thanks for the fix @bogdan ! Unfortunately some test cases are failing. Did you by any chance have had a look at why? |
|
Yes, it looks like it breaks something. While I was investigating, I found that |
|
So what is missing is updating Both vim and neovim has a diff --git a/ale_linters/solidity/solc.vim b/ale_linters/solidity/solc.vim
index a9479f14..0d5668c1 100644
--- a/ale_linters/solidity/solc.vim
+++ b/ale_linters/solidity/solc.vim
@@ -5,34 +5,31 @@ call ale#Set('solidity_solc_executable', 'solc')
call ale#Set('solidity_solc_options', '')
function! ale_linters#solidity#solc#Handle(buffer, lines) abort
- " Matches patterns like the following:
- " Error: Expected ';' but got '('
- " --> /path/to/file/file.sol:1:10:)
- let l:buffer_name = bufname(a:buffer)
- let l:pattern = '\v(Error|Warning|Note): (.*)$'
- let l:line_and_column_pattern = '\v--\> (.*\.sol):(\d+):(\d+):'
+ try
+ let l:data = json_decode(join(a:lines, ''))
+ catch
+ return []
+ endtry
+
+ if empty(l:data)
+ return []
+ endif
+
let l:output = []
- let l:type = 'Note'
- let l:text = ''
-
- for l:line in a:lines
- let l:match = matchlist(l:line, l:pattern)
-
- if len(l:match) == 0
- let l:match = matchlist(l:line, l:line_and_column_pattern)
-
- if len(l:match) > 0 && l:type isnot# 'Note' && l:match[1] is# l:buffer_name
- call add(l:output, {
- \ 'lnum': l:match[2] + 0,
- \ 'col': l:match[3] + 0,
- \ 'text': l:text,
- \ 'type': l:type is? 'Error' ? 'E' : 'W',
- \})
- endif
- else
- let l:type = l:match[1]
- let l:text = l:match[2]
- endif
+
+ for l:type in ['errors']
+ for l:object in l:data[l:type]
+ let l:line = get(l:object['sourceLocation'], 'start', -1)
+ let l:message = l:object['message']
+ let l:detail = l:object['formattedMessage']
+ " \ 'lnum': l:line,
+ call add(l:output, {
+ \ 'lnum': l:line,
+ \ 'text': l:message,
+ \ 'type': 'E',
+ \ 'detail': l:detail,
+ \})
+ endfor
endfor
return l:output
@@ -41,7 +38,8 @@ endfunction
function! ale_linters#solidity#solc#GetCommand(buffer) abort
let l:executable = ale#Var(a:buffer, 'solidity_solc_executable')
- return l:executable . ale#Pad(ale#Var(a:buffer, 'solidity_solc_options')) . ' %s'
+ return l:executable . ' --standard-json' .
+ \ ale#Pad(ale#Var(a:buffer, 'solidity_solc_options')) . ' %s'
endfunction
call ale#linter#Define('solidity', {It clearly needs a few iterations to get all the details right, but parsing json is indeed to be preferred over the output intended for human eyes. |
|
@rymdbar here is the problem: argotorg/solidity#16107. I am open for advice on how to solve it without the patch to solidity itself. |
Ah! That indeed makes things a bit trickier. I did notice the "line" numbers were unrealistically high, but failed to realize why. While there is a function! OffsetToLine(buffer, offset)
if getbufvar(a:buffer, '&fileformat') == 'dos'
let eol = 2
else
let eol = 1
endif
let l:lines = getbufline(a:buffer, 1, '$')
let l:position = 0
for line in range(1, len(l:lines))
let l:position += len(l:lines[line-1]) + eol
if l:position >= a:offset
return l:line
endif
endfor
return -1
endfunctionI don't know how the performance of looking up like this might be, nor what other problems using it might lead to. |
Fixes #4896 .