fix compilation

pull/5270/head
yann300 1 month ago committed by Aniket
parent bfed26c9e2
commit bca08be13a
  1. 16
      apps/vyper/src/app/app.tsx
  2. 3
      apps/vyper/src/app/components/CompileErrorCard.tsx
  3. 92
      apps/vyper/src/app/utils/compiler.tsx
  4. 18
      apps/vyper/src/app/utils/types.ts

@ -15,6 +15,7 @@ import { CustomTooltip } from '@remix-ui/helper'
import { Form } from 'react-bootstrap' import { Form } from 'react-bootstrap'
import { CompileErrorCard } from './components/CompileErrorCard' import { CompileErrorCard } from './components/CompileErrorCard'
import CustomAccordionToggle from './components/CustomAccordionToggle' import CustomAccordionToggle from './components/CustomAccordionToggle'
import { VyperCompilationError, VyperCompilationResultType } from './utils/types'
interface AppState { interface AppState {
status: 'idle' | 'inProgress' status: 'idle' | 'inProgress'
@ -29,7 +30,7 @@ interface OutputMap {
const App = () => { const App = () => {
const [contract, setContract] = useState<string>() const [contract, setContract] = useState<string>()
const [output, setOutput] = useState<any>(remixClient.compilerOutput) const [output, setOutput] = useState<VyperCompilationError[] | VyperCompilationResultType>(remixClient.compilerOutput)
const [state, setState] = useState<AppState>({ const [state, setState] = useState<AppState>({
status: 'idle', status: 'idle',
environment: 'remote', environment: 'remote',
@ -109,6 +110,7 @@ const App = () => {
const [cloneCount, setCloneCount] = useState(0) const [cloneCount, setCloneCount] = useState(0)
console.log((output))
return ( return (
<main id="vyper-plugin"> <main id="vyper-plugin">
<section> <section>
@ -165,15 +167,17 @@ const App = () => {
<div className="px-3 w-100 mb-3 mt-1" id="compile-btn"> <div className="px-3 w-100 mb-3 mt-1" id="compile-btn">
<CompilerButton compilerUrl={compilerUrl()} contract={contract} setOutput={(name, update) => setOutput({ ...output, [name]: update })} resetCompilerState={resetCompilerResultState} output={output} remixClient={remixClient}/> <CompilerButton compilerUrl={compilerUrl()} contract={contract} setOutput={(name, update) => setOutput({ ...output, [name]: update })} resetCompilerState={resetCompilerResultState} output={output} remixClient={remixClient}/>
</div> </div>
<article id="result" className="p-2 mx-3 border-top mt-2"> <article id="result" className="p-2 mx-3 border-top mt-2">
{output && Object.keys(output).length > 0 && output.status !== 'failed' ? ( {output && output.status === 'success' &&
<> <>
<VyperResult output={output} plugin={remixClient} /> <VyperResult output={output} plugin={remixClient} />
</> </>
) : output.status === 'failed' ? ( }
<CompileErrorCard output={output} plugin={remixClient} /> {output && output.status === 'failed' &&
) : null} output.errors && output.errors.map((error) => {
return <CompileErrorCard output={error} plugin={remixClient} />
})
}
</article> </article>
</section> </section>
</main> </main>

@ -1,8 +1,9 @@
import {CopyToClipboard} from '@remix-ui/clipboard' import {CopyToClipboard} from '@remix-ui/clipboard'
import Reaact from 'react' import Reaact from 'react'
import { RemixClient } from '../utils' import { RemixClient } from '../utils'
import { VyperCompilationError} from '../utils/types'
export function CompileErrorCard(props: { output: any, plugin: RemixClient }) { export function CompileErrorCard(props: { output: VyperCompilationError, plugin: RemixClient }) {
return ( return (
<div <div
id="vyperErrorResult" id="vyperErrorResult"

@ -2,33 +2,13 @@ import { ABIDescription } from '@remixproject/plugin-api'
import axios from 'axios' import axios from 'axios'
import { remixClient } from './remix-client' import { remixClient } from './remix-client'
import _ from 'lodash' import _ from 'lodash'
import { VyperCompilationError , VyperCompilationOutput} from './types'
export interface Contract { export interface Contract {
name: string name: string
content: string content: string
} }
export interface VyperCompilationResult {
status: 'success'
bytecode: string
contractName?: string
bytecode_runtime: string
abi: ABIDescription[]
ir: string
method_identifiers: {
[method: string]: string
}
}
export interface VyperCompilationError {
status: 'failed'
column?: number
line?: number
message: string
}
export type VyperCompilationOutput = VyperCompilationResult | VyperCompilationError
/** Check if the output is an error */ /** Check if the output is an error */
export const isCompilationError = (output: VyperCompilationOutput): output is VyperCompilationError => output.status === 'failed' export const isCompilationError = (output: VyperCompilationOutput): output is VyperCompilationError => output.status === 'failed'
@ -45,35 +25,6 @@ export function normalizeContractPath(contractPath: string): string[] {
return [folders,resultingPath, filename] return [folders,resultingPath, filename]
} }
function parseErrorString(errorStructure: string[]) {
// Split the string into lines
let errorType = ''
let message = ''
let tline = ''
errorStructure.forEach(errorMsg => {
const choppedup = errorMsg.split(': ')
errorType = choppedup[0].trim().split('\n')[1]
message = choppedup[1]
// if (errorStructure.length > 2) {
// console.log(choppedup[2].split(',')[1])
// }
// console.log(choppedup)
})
let lines = errorStructure[0].trim().split('\n')
const errorObject = {
status: 'failed',
message: `${errorType} - ${message}`,
column: '',
line: ''
}
message = null
// targetLine = null
lines = null
tline = null
return errorObject
}
const buildError = (output) => { const buildError = (output) => {
if (isCompilationError(output)) { if (isCompilationError(output)) {
const line = output.line const line = output.line
@ -120,8 +71,9 @@ const compileReturnType = (output, contract) => {
const depByteCode = evm.deployedBytecode const depByteCode = evm.deployedBytecode
const runtimeBytecode = evm.bytecode const runtimeBytecode = evm.bytecode
const methodIdentifiers = evm.methodIdentifiers const methodIdentifiers = evm.methodIdentifiers
const version = output?.compilers[0]?.version ?? '0.4.0' // TODO: verify this is correct
const optimized = output?.compilers[0]?.settings?.optimize ?? true const version = output.version || '0.4.0'
const optimized = output.optimize || true
const evmVersion = '' const evmVersion = ''
const result: { const result: {
@ -179,7 +131,7 @@ const fixContractContent = (content: string) => {
* @param url The url of the compiler * @param url The url of the compiler
* @param contract The name and content of the contract * @param contract The name and content of the contract
*/ */
export async function compile(url: string, contract: Contract): Promise<any> { export async function compile(url: string, contract: Contract): Promise<VyperCompilationOutput> {
if (!contract.name) { if (!contract.name) {
throw new Error('Set your Vyper contract file.') throw new Error('Set your Vyper contract file.')
} }
@ -211,7 +163,6 @@ export async function compile(url: string, contract: Contract): Promise<any> {
contractName = null contractName = null
response = null response = null
let result: any let result: any
let intermediateError
const status = await (await axios.get(url + 'status/' + compileCode , { const status = await (await axios.get(url + 'status/' + compileCode , {
method: 'Get' method: 'Get'
@ -226,10 +177,7 @@ export async function compile(url: string, contract: Contract): Promise<any> {
const intermediate = await(await axios.get(url + 'exceptions/' + compileCode , { const intermediate = await(await axios.get(url + 'exceptions/' + compileCode , {
method: 'Get' method: 'Get'
})).data })).data
// console.log('Errors found', intermediate) return intermediate
result = parseErrorString(intermediate)
intermediateError = intermediate
return result
} }
await new Promise((resolve) => setTimeout(() => resolve({}), 3000)) await new Promise((resolve) => setTimeout(() => resolve({}), 3000))
} }
@ -293,12 +241,13 @@ export async function compileContract(contract: string, compilerUrl: string, set
try { try {
_contract = await remixClient.getContract() _contract = await remixClient.getContract()
} catch (e: any) { } catch (e: any) {
const errorGettingContract = { const errorGettingContract: VyperCompilationError = {
status: 'failed', status: 'failed',
message: e.message message: e.mesaage,
error_type: 'fetch_contract'
} }
remixClient.eventEmitter.emit('setOutput', errorGettingContract) remixClient.eventEmitter.emit('setOutput', { status: 'failed', errors: [errorGettingContract] } )
return return
} }
remixClient.changeStatus({ remixClient.changeStatus({
@ -306,10 +255,9 @@ export async function compileContract(contract: string, compilerUrl: string, set
type: 'info', type: 'info',
title: 'Compiling' title: 'Compiling'
}) })
let output
// try { // try {
output = await compile(compilerUrl, _contract) let output = await compile(compilerUrl, _contract)
if (output.status === 'failed') { if (output && output[0] && output[0].status === 'failed') {
remixClient.changeStatus({ remixClient.changeStatus({
key: 'failed', key: 'failed',
type: 'error', type: 'error',
@ -317,13 +265,11 @@ export async function compileContract(contract: string, compilerUrl: string, set
}) })
setLoadingSpinnerState && setLoadingSpinnerState(false) setLoadingSpinnerState && setLoadingSpinnerState(false)
remixClient.eventEmitter.emit('setOutput', { status: 'failed', message: output.message, title: 'Error compiling...', line: output.line, column: output.column, key: 1 }) remixClient.eventEmitter.emit('setOutput', { status: 'failed', errors: output })
output = null
return return
} }
// SUCCESS // SUCCESS
// remixClient.discardHighlight()
remixClient.changeStatus({ remixClient.changeStatus({
key: 'succeed', key: 'succeed',
type: 'success', type: 'success',
@ -336,9 +282,9 @@ export async function compileContract(contract: string, compilerUrl: string, set
const contractName = _contract['name'] const contractName = _contract['name']
const compileResult = compileReturnType(output, contractName) const compileResult = compileReturnType(output, contractName)
if (setOutput === null || setOutput === undefined) { if (setOutput === null || setOutput === undefined) {
remixClient.eventEmitter.emit('setOutput', { contractName, compileResult }) remixClient.eventEmitter.emit('setOutput', { status: 'success', contractName, compileResult })
} else { } else {
remixClient.eventEmitter.emit('setOutput', { contractName, compileResult }) remixClient.eventEmitter.emit('setOutput', { status: 'success', contractName, compileResult })
} }
} catch (err: any) { } catch (err: any) {
remixClient.changeStatus({ remixClient.changeStatus({
@ -347,8 +293,14 @@ export async function compileContract(contract: string, compilerUrl: string, set
title: `1 error occurred ${err.message}` title: `1 error occurred ${err.message}`
}) })
const errorGettingContract: VyperCompilationError = {
status: 'failed',
message: err.mesaage,
error_type: 'unknown_error'
}
setLoadingSpinnerState && setLoadingSpinnerState(false) setLoadingSpinnerState && setLoadingSpinnerState(false)
remixClient.eventEmitter.emit('setOutput', { status: 'failed', message: err.message }) remixClient.eventEmitter.emit('setOutput', { status: 'failed', errors: [errorGettingContract] })
} }
} }

@ -11,11 +11,27 @@ export interface VyperCompilationResult {
} }
} }
export interface VyperCompilationError { export type VyperCompilationError = {
status: 'failed' status: 'failed'
column?: number column?: number
line?: number line?: number
message: string message: string
error_type: string
}
export type VyperCompilationOutput = VyperCompilationResult | VyperCompilationError
export type VyperCompilationResult = {
contractName: string
abi: any,
bytecode: any,
runtimeBytecode: any,
ir: string,
methodIdentifiers: any,
version?: string,
evmVersion?: string
optimized?: boolean
} }
export type VyperCompilationResultType = { export type VyperCompilationResultType = {

Loading…
Cancel
Save