From 3ca083066d107983437890fef062d15f46dcdbb6 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Fri, 23 Feb 2024 23:37:11 +0100 Subject: [PATCH] refactor isCompilationError function --- apps/vyper/src/app/utils/compiler.tsx | 165 +++++++++++++++----------- 1 file changed, 95 insertions(+), 70 deletions(-) diff --git a/apps/vyper/src/app/utils/compiler.tsx b/apps/vyper/src/app/utils/compiler.tsx index a9715997ee..b9f2fd883e 100644 --- a/apps/vyper/src/app/utils/compiler.tsx +++ b/apps/vyper/src/app/utils/compiler.tsx @@ -31,9 +31,7 @@ export interface VyperCompilationError { export type VyperCompilationOutput = VyperCompilationResult | VyperCompilationError /** Check if the output is an error */ -export function isCompilationError(output: VyperCompilationOutput): output is VyperCompilationError { - return output.status === 'failed' -} +export const isCompilationError = (output: VyperCompilationOutput): output is VyperCompilationError => output.status === 'failed' export function normalizeContractPath(contractPath: string): string[] { const paths = contractPath.split('/') @@ -52,22 +50,99 @@ function parseErrorString(errorString) { // Split the string into lines let lines = errorString.trim().split('\n') // Extract the line number and message - let message = lines[1].trim() + console.log(lines) + let message = errorString.trim() let targetLine = lines[2].split(',') - let lineColumn = targetLine[targetLine.length - 1].split(' ')[2].split(':') + let tline = lines[2].trim().split(' ')[1].split(':') + + console.log('tline', tline) const errorObject = { status: 'failed', message: message, - column: parseInt(lineColumn[1]), - line: parseInt(lineColumn[0]) + column: tline[1], + line: tline[0] } message = null targetLine = null - lineColumn = null lines = null + tline = null return errorObject } +const buildError = (output) => { + if (isCompilationError(output)) { + const line = output.line + if (line) { + const lineColumnPos = { + start: {line: line - 1, column: 10}, + end: {line: line - 1, column: 10} + } + // remixClient.highlight(lineColumnPos as any, _contract.name, '#e0b4b4') + } else { + const regex = output?.message?.match(/line ((\d+):(\d+))+/g) + const errors = output?.message?.split(/line ((\d+):(\d+))+/g) // extract error message + if (regex) { + let errorIndex = 0 + regex.map((errorLocation) => { + const location = errorLocation?.replace('line ', '').split(':') + let message = errors[errorIndex] + errorIndex = errorIndex + 4 + if (message && message?.split('\n\n').length > 0) { + try { + message = message?.split('\n\n')[message.split('\n\n').length - 1] + } catch (e) {} + } + if (location?.length > 0) { + const lineColumnPos = { + start: {line: parseInt(location[0]) - 1, column: 10}, + end: {line: parseInt(location[0]) - 1, column: 10} + } + // remixClient.highlight(lineColumnPos as any, _contract.name, message) + } + }) + } + } + throw new Error(output.message) + } +} + +const compileReturnType = (output, contract) => { + const t: any = toStandardOutput(contract, output) + const temp = _.merge(t['contracts'][contract]) + const normal = normalizeContractPath(contract)[2] + const abi = temp[normal]['abi'] + const evm = _.merge(temp[normal]['evm']) + const dpb = evm.deployedBytecode + const runtimeBytecode = evm.bytecode + const methodIdentifiers = evm.methodIdentifiers + const version = output?.compilers[0]?.version ?? '0.3.10' + const optimized = output?.compilers[0]?.settings?.optimize ?? true + const evmVersion = '' + + const result: { + contractName: any, + abi: any, + bytecode: any, + runtimeBytecode: any, + ir: '', + methodIdentifiers: any, + version?: '', + evmVersion?: '' + optimized?: boolean + } = { + contractName: normal, + abi, + bytecode: dpb, + runtimeBytecode, + ir: '', + methodIdentifiers, + version, + evmVersion, + optimized + } + return result +} + /** * Compile the a contract * @param url The url of the compiler @@ -117,6 +192,7 @@ export async function compile(url: string, contract: Contract): Promise { method: 'Get' })).data result = parseErrorString(intermediate[0]) + console.log('error payload', intermediate) return result } await new Promise((resolve) => setTimeout(() => resolve({}), 3000)) @@ -128,6 +204,7 @@ export async function compile(url: string, contract: Contract): Promise { * @param compilationResult Result returned by the compiler */ export function toStandardOutput(fileName: string, compilationResult: any): any { + console.log(compilationResult) const contractName = normalizeContractPath(fileName)[2] const compiledAbi = compilationResult['contractTypes'][contractName].abi const deployedBytecode = compilationResult['contractTypes'][contractName].deploymentBytecode.bytecode.replace('0x', '') @@ -194,74 +271,20 @@ export async function compileContract(contract: string, compilerUrl: string, set title: 'Compiling' }) let output - try { - output = await compile(compilerUrl, _contract) - remixClient.eventEmitter.emit('setOutput', output) - } catch (e: any) { + // try { + output = await compile(compilerUrl, _contract) + if (output.status === 'failed') { + console.log('possible error', output) remixClient.changeStatus({ key: 'failed', type: 'error', - title: `${e.message} debugging` + title: 'Compilation failed...' }) - remixClient.eventEmitter.emit('setOutput', {status: 'failed', message: e.message, title: 'Error compiling...'}) + remixClient.eventEmitter.emit('setOutput', {status: 'failed', message: output.message, title: 'Error compiling...', line: output.line, column: output.column}) + output = null return } - const compileReturnType = () => { - const t: any = toStandardOutput(contract, output) - const temp = _.merge(t['contracts'][contract]) - const normal = normalizeContractPath(contract)[2] - const abi = temp[normal]['abi'] - const evm = _.merge(temp[normal]['evm']) - const dpb = evm.deployedBytecode - const runtimeBytecode = evm.bytecode - const methodIdentifiers = evm.methodIdentifiers - - const result = { - contractName: normal, - abi: abi, - bytecode: dpb, - runtimeBytecode: runtimeBytecode, - ir: '', - methodIdentifiers: methodIdentifiers - } - return result - } - // ERROR - if (isCompilationError(output)) { - const line = output.line - if (line) { - const lineColumnPos = { - start: {line: line - 1, column: 10}, - end: {line: line - 1, column: 10} - } - // remixClient.highlight(lineColumnPos as any, _contract.name, '#e0b4b4') - } else { - const regex = output?.message?.match(/line ((\d+):(\d+))+/g) - const errors = output?.message?.split(/line ((\d+):(\d+))+/g) // extract error message - if (regex) { - let errorIndex = 0 - regex.map((errorLocation) => { - const location = errorLocation?.replace('line ', '').split(':') - let message = errors[errorIndex] - errorIndex = errorIndex + 4 - if (message && message?.split('\n\n').length > 0) { - try { - message = message?.split('\n\n')[message.split('\n\n').length - 1] - } catch (e) {} - } - if (location?.length > 0) { - const lineColumnPos = { - start: {line: parseInt(location[0]) - 1, column: 10}, - end: {line: parseInt(location[0]) - 1, column: 10} - } - // remixClient.highlight(lineColumnPos as any, _contract.name, message) - } - }) - } - } - throw new Error(output.message) - } // SUCCESS // remixClient.discardHighlight() remixClient.changeStatus({ @@ -271,9 +294,11 @@ export async function compileContract(contract: string, compilerUrl: string, set }) const data = toStandardOutput(_contract.name, output) + console.log('data', data) + console.log('what is the shape of my output', output) remixClient.compilationFinish(_contract.name, _contract.content, data) const contractName = _contract['name'] - const compileResult = compileReturnType() + const compileResult = compileReturnType(output, contractName) if (setOutput === null || setOutput === undefined) { remixClient.eventEmitter.emit('setOutput', { contractName, compileResult }) } else {