Skip to content

Commit f445b4e

Browse files
committed
show compile button for .nr files
1 parent a685500 commit f445b4e

File tree

7 files changed

+185
-66
lines changed

7 files changed

+185
-66
lines changed

apps/noir-compiler/src/app/app.tsx

+14
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,20 @@ function App() {
2323
plugin.on('locale', 'localeChanged', (locale: any) => {
2424
setLocale(locale)
2525
})
26+
plugin.on('fileManager', 'currentFileChanged', (filePath) => {
27+
if (filePath.endsWith('.nr')) {
28+
dispatch({ type: 'SET_FILE_PATH', payload: filePath })
29+
plugin.parse(filePath)
30+
}
31+
})
32+
// @ts-ignore
33+
plugin.on('editor', 'contentChanged', async (path: string, content: string) => {
34+
setIsContentChanged(true)
35+
// check if autoCompile is enabled
36+
// if (path.endsWith('.nr')) {
37+
// plugin.parse(path, content)
38+
// }
39+
})
2640
setIsPluginActivated(true)
2741
})
2842
}, [])

apps/noir-compiler/src/app/components/container.tsx

+54-59
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,17 @@ export function Container () {
2121
}
2222
}
2323

24-
// const handleOpenErrorLocation = async (location: string, startRange: string) => {
25-
// if (location) {
26-
// const fullPathLocation = await circuitApp.plugin.resolveReportPath(location)
24+
const handleOpenErrorLocation = async (location: string, startRange: string) => {
25+
if (location) {
26+
const fullPathLocation = await circuitApp.plugin.resolveReportPath(location)
2727

28-
// await circuitApp.plugin.call('fileManager', 'open', fullPathLocation)
29-
// // @ts-ignore
30-
// const startPosition: { lineNumber: number; column: number } = await circuitApp.plugin.call('editor', 'getPositionAt', startRange)
31-
// // @ts-ignore
32-
// await circuitApp.plugin.call('editor', 'gotoLine', startPosition.lineNumber - 1, startPosition.column)
33-
// }
34-
// }
35-
36-
// const handlePrimeChange = (value: PrimeValue) => {
37-
// circuitApp.plugin.compilerPrime = value
38-
// circuitApp.dispatch({ type: 'SET_PRIME_VALUE', payload: value as PrimeValue })
39-
// }
28+
await circuitApp.plugin.call('fileManager', 'open', fullPathLocation)
29+
// @ts-ignore
30+
const startPosition: { lineNumber: number; column: number } = await circuitApp.plugin.call('editor', 'getPositionAt', startRange)
31+
// @ts-ignore
32+
await circuitApp.plugin.call('editor', 'gotoLine', startPosition.lineNumber - 1, startPosition.column)
33+
}
34+
}
4035

4136
const handleCircuitAutoCompile = (value: boolean) => {
4237
noirApp.dispatch({ type: 'SET_AUTO_COMPILE', payload: value })
@@ -46,48 +41,48 @@ export function Container () {
4641
noirApp.dispatch({ type: 'SET_HIDE_WARNINGS', payload: value })
4742
}
4843

49-
// const askGPT = async (report: CompilerReport) => {
50-
// if (report.labels.length > 0) {
51-
// const location = circuitApp.appState.filePathToId[report.labels[0].file_id]
52-
// const error = report.labels[0].message
44+
const askGPT = async (report: CompilerReport) => {
45+
if (report.labels.length > 0) {
46+
const location = circuitApp.appState.filePathToId[report.labels[0].file_id]
47+
const error = report.labels[0].message
5348

54-
// if (location) {
55-
// const fullPathLocation = await circuitApp.plugin.resolveReportPath(location)
56-
// const content = await circuitApp.plugin.call('fileManager', 'readFile', fullPathLocation)
57-
// const message = `
58-
// circom code: ${content}
59-
// error message: ${error}
60-
// full circom error: ${JSON.stringify(report, null, 2)}
61-
// explain why the error occurred and how to fix it.
62-
// `
63-
// await circuitApp.plugin.call('popupPanel' as any, 'showPopupPanel', true)
64-
// setTimeout(async () => {
65-
// await circuitApp.plugin.call('remixAI' as any, 'chatPipe', 'error_explaining', message)
66-
// }, 500)
67-
// } else {
68-
// const message = `
69-
// error message: ${error}
70-
// full circom error: ${JSON.stringify(report, null, 2)}
71-
// explain why the error occurred and how to fix it.
72-
// `
73-
// await circuitApp.plugin.call('popupPanel' as any, 'showPopupPanel', true)
74-
// setTimeout(async () => {
75-
// await circuitApp.plugin.call('remixAI' as any, 'chatPipe', 'error_explaining', message)
76-
// }, 500)
77-
// }
78-
// } else {
79-
// const error = report.message
80-
// const message = `
81-
// error message: ${error}
82-
// full circom error: ${JSON.stringify(report, null, 2)}
83-
// explain why the error occurred and how to fix it.
84-
// `
85-
// await circuitApp.plugin.call('popupPanel' as any, 'showPopupPanel', true)
86-
// setTimeout(async () => {
87-
// await circuitApp.plugin.call('remixAI' as any, 'chatPipe', 'error_explaining', message)
88-
// }, 500)
89-
// }
90-
// }
49+
if (location) {
50+
const fullPathLocation = await circuitApp.plugin.resolveReportPath(location)
51+
const content = await circuitApp.plugin.call('fileManager', 'readFile', fullPathLocation)
52+
const message = `
53+
circom code: ${content}
54+
error message: ${error}
55+
full circom error: ${JSON.stringify(report, null, 2)}
56+
explain why the error occurred and how to fix it.
57+
`
58+
await circuitApp.plugin.call('popupPanel' as any, 'showPopupPanel', true)
59+
setTimeout(async () => {
60+
await circuitApp.plugin.call('remixAI' as any, 'chatPipe', 'error_explaining', message)
61+
}, 500)
62+
} else {
63+
const message = `
64+
error message: ${error}
65+
full circom error: ${JSON.stringify(report, null, 2)}
66+
explain why the error occurred and how to fix it.
67+
`
68+
await circuitApp.plugin.call('popupPanel' as any, 'showPopupPanel', true)
69+
setTimeout(async () => {
70+
await circuitApp.plugin.call('remixAI' as any, 'chatPipe', 'error_explaining', message)
71+
}, 500)
72+
}
73+
} else {
74+
const error = report.message
75+
const message = `
76+
error message: ${error}
77+
full circom error: ${JSON.stringify(report, null, 2)}
78+
explain why the error occurred and how to fix it.
79+
`
80+
await circuitApp.plugin.call('popupPanel' as any, 'showPopupPanel', true)
81+
setTimeout(async () => {
82+
await circuitApp.plugin.call('remixAI' as any, 'chatPipe', 'error_explaining', message)
83+
}, 500)
84+
}
85+
}
9186

9287
const handleCompileClick = () => {
9388
compileNoirCircuit(noirApp.plugin, noirApp.appState)
@@ -113,9 +108,9 @@ export function Container () {
113108
<div className="pb-2">
114109
<CompileBtn id="noir" plugin={noirApp.plugin} appState={noirApp.appState} compileAction={handleCompileClick} />
115110
</div>
116-
{/* <RenderIf condition={circuitApp.appState.status !== 'compiling'}>
117-
<CompilerFeedback feedback={circuitApp.appState.compilerFeedback} filePathToId={circuitApp.appState.filePathToId} openErrorLocation={handleOpenErrorLocation} hideWarnings={circuitApp.appState.hideWarnings} askGPT={askGPT} />
118-
</RenderIf> */}
111+
<RenderIf condition={noirApp.appState.status !== 'compiling'}>
112+
<CompilerFeedback feedback={noirApp.appState.compilerFeedback} filePathToId={noirApp.appState.filePathToId} openErrorLocation={handleOpenErrorLocation} hideWarnings={noirApp.appState.hideWarnings} askGPT={askGPT} />
113+
</RenderIf>
119114
</div>
120115
</div>
121116
</article>

apps/noir-compiler/src/app/reducers/state.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
import { Actions, AppState } from '../types'
22

3-
export interface ActionPayloadTypes {
4-
SET_AUTO_COMPILE: boolean,
5-
SET_HIDE_WARNINGS: boolean
6-
}
7-
83
export const appInitialState: AppState = {
94
filePath: '',
105
filePathToId: {},
@@ -28,6 +23,12 @@ export const appReducer = (state = appInitialState, action: Actions): AppState =
2823
hideWarnings: action.payload
2924
}
3025

26+
case 'SET_FILE_PATH':
27+
return {
28+
...state,
29+
filePath: action.payload
30+
}
31+
3132
default:
3233
throw new Error()
3334
}

apps/noir-compiler/src/app/types/index.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { compiler_list } from 'circom_wasm'
22
import { Dispatch } from 'react'
33
import type { NoirPluginClient } from '../services/noirPluginClient'
4-
import { ActionPayloadTypes } from '../reducers/state'
54

65
export type CompilerStatus = "compiling" | "idle" | "errored" | "warning"
76
export interface INoirAppContext {
@@ -18,6 +17,11 @@ export interface AppState {
1817
status: CompilerStatus
1918
}
2019

20+
export interface ActionPayloadTypes {
21+
SET_AUTO_COMPILE: boolean,
22+
SET_HIDE_WARNINGS: boolean,
23+
SET_FILE_PATH: string
24+
}
2125
export interface Action<T extends keyof ActionPayloadTypes> {
2226
type: T
2327
payload: ActionPayloadTypes[T]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { useState } from 'react'
2+
import { CompilerFeedbackProps, CompilerReport } from '../types'
3+
import { RenderIf } from '@remix-ui/helper'
4+
import { CopyToClipboard } from '@remix-ui/clipboard'
5+
import { FeedbackAlert } from './feedbackAlert'
6+
7+
export function CompilerFeedback ({ feedback, filePathToId, hideWarnings, openErrorLocation, askGPT }: CompilerFeedbackProps) {
8+
const [showException, setShowException] = useState<boolean>(true)
9+
10+
const handleCloseException = () => {
11+
setShowException(false)
12+
}
13+
14+
const handleOpenError = (report: CompilerReport) => {
15+
if (report.labels.length > 0) {
16+
openErrorLocation(filePathToId[report.labels[0].file_id], report.labels[0].range.start)
17+
}
18+
}
19+
20+
const handleAskGPT = (report: CompilerReport) => {
21+
askGPT(report)
22+
}
23+
24+
return (
25+
<div>
26+
{
27+
(feedback && typeof feedback === 'string') || (Array.isArray(feedback) && feedback.length > 0) ? (
28+
<div className="circuit_errors_box">
29+
<RenderIf condition={ (typeof feedback === "string") && showException }>
30+
<div className="circuit_feedback error alert alert-danger" data-id="circuit_feedback">
31+
<span> <>{ feedback }</> </span>
32+
<div className="close" data-id="renderer" onClick={handleCloseException}>
33+
<i className="fas fa-times"></i>
34+
</div>
35+
<div className="d-flex pt-1 flex-row-reverse">
36+
<span className="ml-3 pt-1 py-1" >
37+
<CopyToClipboard content={feedback} className="p-0 m-0 far fa-copy error" direction={'top'} />
38+
</span>
39+
</div>
40+
</div>
41+
</RenderIf>
42+
<RenderIf condition={ Array.isArray(feedback) }>
43+
<>
44+
{
45+
Array.isArray(feedback) && feedback.map((response, index) => (
46+
<div key={index} onClick={() => handleOpenError(response)}>
47+
<RenderIf condition={response.type === 'Error'}>
48+
<div className={`circuit_feedback ${response.type.toLowerCase()} alert alert-danger`} data-id="circuit_feedback">
49+
<FeedbackAlert
50+
message={response.message + (response.labels[0] ? ": " + response.labels[0].message + ` ${filePathToId[response.labels[0].file_id]}:${response.labels[0].range.start}:${response.labels[0].range.end}` : '')}
51+
askGPT={ () => handleAskGPT(response) } />
52+
</div>
53+
</RenderIf>
54+
<RenderIf condition={(response.type === 'Warning') && !hideWarnings}>
55+
<div className={`circuit_feedback ${response.type.toLowerCase()} alert alert-warning`} data-id="circuit_feedback">
56+
<FeedbackAlert
57+
message={response.message}
58+
askGPT={() => { handleAskGPT(response) }} />
59+
</div>
60+
</RenderIf>
61+
</div>
62+
)
63+
)
64+
}
65+
</>
66+
</RenderIf>
67+
</div>
68+
) : <></>
69+
}
70+
</div>
71+
)
72+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { useState } from 'react'
2+
import { FeedbackAlertProps } from '../types'
3+
import { RenderIf } from '@remix-ui/helper'
4+
import {CopyToClipboard} from '@remix-ui/clipboard'
5+
6+
export function FeedbackAlert ({ message, askGPT }: FeedbackAlertProps) {
7+
const [ showAlert, setShowAlert] = useState<boolean>(true)
8+
9+
const handleCloseAlert = () => {
10+
setShowAlert(false)
11+
}
12+
13+
return (
14+
<RenderIf condition={showAlert}>
15+
<>
16+
<span> { message } </span>
17+
<div className="close" data-id="renderer" onClick={handleCloseAlert}>
18+
<i className="fas fa-times"></i>
19+
</div>
20+
<div className="d-flex pt-1 flex-row-reverse">
21+
<span className="ml-3 pt-1 py-1" >
22+
<CopyToClipboard content={message} className="p-0 m-0 far fa-copy error" direction={'top'} />
23+
</span>
24+
<span className="border border-success text-success btn-sm" onClick={(e) => {
25+
e.stopPropagation()
26+
askGPT()
27+
}}>Ask RemixAI</span>
28+
</div>
29+
</>
30+
</RenderIf>
31+
)
32+
}

libs/remix-ui/helper/src/lib/remix-ui-helper.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ export const getPathIcon = (path: string) => {
8282
? 'fad fa-brackets-curly' : path.endsWith('.cairo')
8383
? 'small fa-kit fa-cairo' : path.endsWith('.circom')
8484
? 'fa-kit fa-circom' : path.endsWith('.nr')
85-
? 'fa-kit fa-noir' : 'far fa-file'
85+
? 'fa-kit fa-noir' : path.endsWith('.toml')
86+
? 'fad fa-cog': 'far fa-file'
8687
}
8788

8889
export const isNumeric = (value) => {

0 commit comments

Comments
 (0)