|
|
|
@ -57,6 +57,11 @@ export class CodeParser extends Plugin { |
|
|
|
|
await this.compile() |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
this.on('filePanel', 'setWorkspace', async() => { |
|
|
|
|
await this.call('fileDecorator', 'setFileDecorators', []) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.on('fileManager', 'currentFileChanged', async () => { |
|
|
|
|
await this.getCurrentFileAST() |
|
|
|
|
await this.compile() |
|
|
|
@ -79,13 +84,11 @@ export class CodeParser extends Plugin { |
|
|
|
|
console.log('compile success', success, data, this) |
|
|
|
|
this.call('editor', 'clearAnnotations') |
|
|
|
|
this.errorState = true |
|
|
|
|
let noFatalErrors = true // ie warnings are ok
|
|
|
|
|
const checkIfFatalError = (error: CompilationError) => { |
|
|
|
|
// Ignore warnings and the 'Deferred import' error as those are generated by us as a workaround
|
|
|
|
|
const isValidError = (error.message && error.message.includes('Deferred import')) ? false : error.severity !== 'warning' |
|
|
|
|
if (isValidError) { |
|
|
|
|
console.log(error) |
|
|
|
|
noFatalErrors = false |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
const result = new CompilerAbstract('soljson', data, source, input) |
|
|
|
@ -94,100 +97,105 @@ export class CodeParser extends Plugin { |
|
|
|
|
if (data.errors) data.errors.forEach((err) => checkIfFatalError(err)) |
|
|
|
|
const allErrors = [] |
|
|
|
|
if (data.errors) { |
|
|
|
|
const sources = result.getSourceCode().sources |
|
|
|
|
for (const error of data.errors) { |
|
|
|
|
console.log('ERROR POS', error) |
|
|
|
|
const pos = helper.getPositionDetails(error.formattedMessage) |
|
|
|
|
console.log('ERROR POS', pos) |
|
|
|
|
const sources = result.getSourceCode().sources |
|
|
|
|
const filePosition = Object.keys(sources).findIndex((fileName) => fileName === error.sourceLocation.file) |
|
|
|
|
const source = sources[pos.file] |
|
|
|
|
const lineColumn = await this.call('offsetToLineColumnConverter', 'offsetToLineColumn', |
|
|
|
|
{ |
|
|
|
|
start: error.sourceLocation.start, |
|
|
|
|
length: error.sourceLocation.end - error.sourceLocation.start |
|
|
|
|
}, |
|
|
|
|
0, |
|
|
|
|
sources, |
|
|
|
|
null) |
|
|
|
|
console.log('lineColumn', lineColumn) |
|
|
|
|
filePosition, |
|
|
|
|
result.getSourceCode().sources, |
|
|
|
|
result.getAsts()) |
|
|
|
|
allErrors.push({ error, lineColumn }) |
|
|
|
|
} |
|
|
|
|
console.log('allErrors', allErrors) |
|
|
|
|
await this.call('editor', 'addErrorMarker', allErrors) |
|
|
|
|
|
|
|
|
|
for(const error of allErrors){ |
|
|
|
|
const errorsPerFiles = {} |
|
|
|
|
for (const error of allErrors) { |
|
|
|
|
if (!errorsPerFiles[error.error.sourceLocation.file]) { |
|
|
|
|
errorsPerFiles[error.error.sourceLocation.file] = [] |
|
|
|
|
} |
|
|
|
|
errorsPerFiles[error.error.sourceLocation.file].push(error.error) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const errorPriority = { |
|
|
|
|
'error': 0, |
|
|
|
|
'warning': 1, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// sort errorPerFiles by error priority
|
|
|
|
|
const sortedErrorsPerFiles = {} |
|
|
|
|
for (const fileName in errorsPerFiles) { |
|
|
|
|
const errors = errorsPerFiles[fileName] |
|
|
|
|
errors.sort((a, b) => { |
|
|
|
|
return errorPriority[a.severity] - errorPriority[b.severity] |
|
|
|
|
} |
|
|
|
|
) |
|
|
|
|
sortedErrorsPerFiles[fileName] = errors |
|
|
|
|
} |
|
|
|
|
console.log('sortedErrorsPerFiles', sortedErrorsPerFiles) |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
const filesWithOutErrors = Object.keys(sources).filter((fileName) => !sortedErrorsPerFiles[fileName]) |
|
|
|
|
|
|
|
|
|
let fileState:fileDecoration = { |
|
|
|
|
path: this.currentFile, |
|
|
|
|
console.log('filesWithOutErrors', filesWithOutErrors) |
|
|
|
|
// add decorators
|
|
|
|
|
const decorators: fileDecoration[] = [] |
|
|
|
|
for (const fileName in sortedErrorsPerFiles) { |
|
|
|
|
const errors = sortedErrorsPerFiles[fileName] |
|
|
|
|
const decorator: fileDecoration = { |
|
|
|
|
path: fileName, |
|
|
|
|
isDirectory: false, |
|
|
|
|
fileStateType: fileDecorationType.Error, |
|
|
|
|
fileStateLabelClass: 'text-success', |
|
|
|
|
fileStateType: errors[0].severity === 'error' ? fileDecorationType.Error : fileDecorationType.Warning, |
|
|
|
|
fileStateLabelClass: errors[0].severity === 'error' ? 'text-danger' : 'text-warning', |
|
|
|
|
fileStateIconClass: '', |
|
|
|
|
fileStateIcon: <i className="text-success fas fa-smile"></i>, |
|
|
|
|
text: '2', |
|
|
|
|
fileStateIcon: '', |
|
|
|
|
text: errors.length, |
|
|
|
|
owner: 'code-parser', |
|
|
|
|
bubble: true |
|
|
|
|
} |
|
|
|
|
await this.call('fileDecorator', 'setFileDecorators', fileState) |
|
|
|
|
fileState = { |
|
|
|
|
...fileState, |
|
|
|
|
fileStateLabelClass: 'text-danger', |
|
|
|
|
fileStateIcon: <i className="text-danger fas fa-spinner fa-spin"></i>, |
|
|
|
|
decorators.push(decorator) |
|
|
|
|
} |
|
|
|
|
fileState = { |
|
|
|
|
...fileState, |
|
|
|
|
path: 'scripts/ethers-lib.ts', |
|
|
|
|
fileStateLabelClass: 'text-danger', |
|
|
|
|
fileStateIcon: <div className='btn btn-danger btn-sm'>call rob now!</div>, |
|
|
|
|
} |
|
|
|
|
await this.call('fileDecorator', 'setFileDecorators', fileState) |
|
|
|
|
|
|
|
|
|
const states:fileDecoration[] = [ |
|
|
|
|
{ |
|
|
|
|
path: 'contracts/2_Owner.sol', |
|
|
|
|
for (const fileName of filesWithOutErrors) { |
|
|
|
|
const decorator: fileDecoration = { |
|
|
|
|
path: fileName, |
|
|
|
|
isDirectory: false, |
|
|
|
|
fileStateType: fileDecorationType.Custom, |
|
|
|
|
fileStateLabelClass: 'text-success', |
|
|
|
|
fileStateType: fileDecorationType.None, |
|
|
|
|
fileStateLabelClass: '', |
|
|
|
|
fileStateIconClass: '', |
|
|
|
|
fileStateIcon: <i className="text-success fas fa-smile"></i>, |
|
|
|
|
fileStateIcon: '', |
|
|
|
|
text: '', |
|
|
|
|
owner: 'code-parser', |
|
|
|
|
bubble: true |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
path: 'contracts/2_Owner.sol', |
|
|
|
|
bubble: false |
|
|
|
|
} |
|
|
|
|
decorators.push(decorator) |
|
|
|
|
} |
|
|
|
|
console.log(decorators) |
|
|
|
|
await this.call('fileDecorator', 'setFileDecorators', decorators) |
|
|
|
|
await this.call('editor', 'clearErrorMarkers', filesWithOutErrors) |
|
|
|
|
} else { |
|
|
|
|
await this.call('editor', 'clearErrorMarkers', result.getSourceCode().sources) |
|
|
|
|
const decorators: fileDecoration[] = [] |
|
|
|
|
for (const fileName of Object.keys(result.getSourceCode().sources)) { |
|
|
|
|
const decorator: fileDecoration = { |
|
|
|
|
path: fileName, |
|
|
|
|
isDirectory: false, |
|
|
|
|
fileStateType: fileDecorationType.Custom, |
|
|
|
|
fileStateLabelClass: 'text-danger', |
|
|
|
|
fileStateType: fileDecorationType.None, |
|
|
|
|
fileStateLabelClass: '', |
|
|
|
|
fileStateIconClass: '', |
|
|
|
|
fileStateIcon: <i className="text-danger fas fa-smile"></i>, |
|
|
|
|
fileStateIcon: '', |
|
|
|
|
text: '', |
|
|
|
|
owner: 'code-parser', |
|
|
|
|
bubble: true |
|
|
|
|
bubble: false |
|
|
|
|
} |
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
await this.call('fileDecorator', 'setFileDecorators', states) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
console.log('error calling filePanel', e) |
|
|
|
|
decorators.push(decorator) |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
await this.call('fileDecorator', 'setFileDecorators', [{ |
|
|
|
|
path: this.currentFile, |
|
|
|
|
isDirectory: false, |
|
|
|
|
fileStateType: [], |
|
|
|
|
fileStateClass: '', |
|
|
|
|
comment: '', |
|
|
|
|
owner: 'code-parser', |
|
|
|
|
bubble: true |
|
|
|
|
}]) |
|
|
|
|
await this.call('editor', 'clearErrorMarkers', result.getSourceCode().sources) |
|
|
|
|
console.log(decorators) |
|
|
|
|
await this.call('fileDecorator', 'setFileDecorators', decorators) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -522,6 +530,7 @@ export class CodeParser extends Plugin { |
|
|
|
|
async positionOfDefinition(node: any): Promise<any | null> { |
|
|
|
|
if (node) { |
|
|
|
|
if (node.src) { |
|
|
|
|
console.log('positionOfDefinition', node) |
|
|
|
|
const position = sourceMappingDecoder.decode(node.src) |
|
|
|
|
if (position) { |
|
|
|
|
return position |
|
|
|
|