pull/2774/head
bunsenstraat 2 years ago
parent 3e280d5ffa
commit 169e1bb700
  1. 84
      apps/remix-ide-e2e/src/tests/editor_error_marker.test.ts
  2. 79
      libs/remix-ui/editor/src/lib/remix-ui-editor.tsx

@ -0,0 +1,84 @@
'use strict'
import { NightwatchBrowser } from 'nightwatch'
import init from '../helpers/init'
module.exports = {
before: function (browser: NightwatchBrowser, done: VoidFunction) {
init(browser, done, 'http://127.0.0.1:8080', true)
},
'Should add error marker': function (browser: NightwatchBrowser) {
browser
.openFile('contracts')
.openFile('contracts/1_Storage.sol')
.addFile('scripts/adderror.ts', {content: addErrorMarker})
.pause(4000)
.executeScriptInTerminal('remix.exeCurrent()')
.pause(4000)
.openFile('contracts/1_Storage.sol')
.useXpath()
.waitForElementVisible("//*[@class='cdr squiggly-error']")
.waitForElementVisible("//*[@class='cdr squiggly-warning']")
},
'Should clear error marker': function (browser: NightwatchBrowser) {
browser
.useCss()
.addFile('scripts/clear.ts', {content: clearMarkers})
.pause(4000)
.executeScriptInTerminal('remix.exeCurrent()')
.pause(4000)
.openFile('contracts/1_Storage.sol')
.useXpath()
.waitForElementNotPresent("//*[@class='cdr squiggly-error']")
.waitForElementNotPresent("//*[@class='cdr squiggly-warning']")
}
}
const clearMarkers =`
(async () => {
await remix.call('editor', 'clearErrorMarkers' as any, ['contracts/1_Storage.sol'])
})()`
const addErrorMarker = `
(async () => {
let errors = [
{
position: {
start: {
line: 10,
column: 1,
},
end: {
line: 10,
column: 10
}
},
message: 'testing',
severity: 'error',
file: 'contracts/1_Storage.sol'
},
{
position: {
start: {
line: 18,
column: 1,
},
end: {
line: 18,
column: 10
}
},
message: 'testing2',
severity: 'warning',
file: 'contracts/1_Storage.sol'
},
]
await remix.call('editor', 'addErrorMarker' as any, errors)
})()`

@ -42,6 +42,22 @@ type sourceMarker = {
hide: boolean hide: boolean
} }
type errorMarker = {
message: string
severity: MarkerSeverity
position: {
start: {
line: number
column: number
},
end: {
line: number
column: number
}
},
file: string
}
loader.config({ paths: { vs: 'assets/js/monaco-editor/dev/vs' } }) loader.config({ paths: { vs: 'assets/js/monaco-editor/dev/vs' } })
export type DecorationsReturn = { export type DecorationsReturn = {
@ -104,7 +120,7 @@ export const EditorUI = (props: EditorUIProps) => {
const currentFileRef = useRef('') const currentFileRef = useRef('')
// const currentDecorations = useRef({ sourceAnnotationsPerFile: {}, markerPerFile: {} }) // decorations that are currently in use by the editor // const currentDecorations = useRef({ sourceAnnotationsPerFile: {}, markerPerFile: {} }) // decorations that are currently in use by the editor
// const registeredDecorations = useRef({}) // registered decorations // const registeredDecorations = useRef({}) // registered decorations
const [editorModelsState, dispatch] = useReducer(reducerActions, initialState) const [editorModelsState, dispatch] = useReducer(reducerActions, initialState)
const formatColor = (name) => { const formatColor = (name) => {
@ -262,7 +278,7 @@ export const EditorUI = (props: EditorUIProps) => {
monacoRef.current.editor.setModelLanguage(file.model, 'remix-cairo') monacoRef.current.editor.setModelLanguage(file.model, 'remix-cairo')
} else if (file.language === 'zokrates') { } else if (file.language === 'zokrates') {
monacoRef.current.editor.setModelLanguage(file.model, 'remix-zokrates') monacoRef.current.editor.setModelLanguage(file.model, 'remix-zokrates')
} }
}, [props.currentFile]) }, [props.currentFile])
const convertToMonacoDecoration = (decoration: sourceAnnotation | sourceMarker, typeOfDecoration: string) => { const convertToMonacoDecoration = (decoration: sourceAnnotation | sourceMarker, typeOfDecoration: string) => {
@ -318,7 +334,7 @@ export const EditorUI = (props: EditorUIProps) => {
registeredDecorations: newRegisteredDecorations registeredDecorations: newRegisteredDecorations
} }
} }
props.editorAPI.keepDecorationsFor = (filePath: string, plugin: string, typeOfDecoration: string, registeredDecorations: any, currentDecorations: any) => { props.editorAPI.keepDecorationsFor = (filePath: string, plugin: string, typeOfDecoration: string, registeredDecorations: any, currentDecorations: any) => {
const model = editorModelsState[filePath]?.model const model = editorModelsState[filePath]?.model
if (!model) return { if (!model) return {
@ -347,25 +363,22 @@ export const EditorUI = (props: EditorUIProps) => {
registeredDecorations: [{ value: decoration, type: typeOfDecoration }] registeredDecorations: [{ value: decoration, type: typeOfDecoration }]
} }
} }
props.editorAPI.addDecoration = (marker: sourceMarker, filePath: string, typeOfDecoration: string) => { props.editorAPI.addDecoration = (marker: sourceMarker, filePath: string, typeOfDecoration: string) => {
return addDecoration(marker, filePath, typeOfDecoration) return addDecoration(marker, filePath, typeOfDecoration)
} }
props.editorAPI.addErrorMarker = async (errors: []) => { props.editorAPI.addErrorMarker = async (errors: errorMarker[]) => {
const allMarkersPerfile: Record<string, Array<monaco.editor.IMarkerData>> = {} const allMarkersPerfile: Record<string, Array<monaco.editor.IMarkerData>> = {}
console.log(errors)
for (const error of errors) { for (const error of errors) {
const marker = (error as any).error let filePath = error.file
const lineColumn = (error as any).lineColumn
let filePath = marker.sourceLocation.file
if (!filePath) return if (!filePath) return
const fileFromUrl = await props.plugin.call('fileManager', 'getPathFromUrl', filePath) const fileFromUrl = await props.plugin.call('fileManager', 'getPathFromUrl', filePath)
filePath = fileFromUrl.file filePath = fileFromUrl.file
const model = editorModelsState[filePath]?.model const model = editorModelsState[filePath]?.model
console.log(filePath)
const errorServerityMap = { const errorServerityMap = {
'error': MarkerSeverity.Error, 'error': MarkerSeverity.Error,
'warning': MarkerSeverity.Warning, 'warning': MarkerSeverity.Warning,
@ -373,14 +386,13 @@ export const EditorUI = (props: EditorUIProps) => {
} }
if (model) { if (model) {
const markerData: monaco.editor.IMarkerData = { const markerData: monaco.editor.IMarkerData = {
severity: errorServerityMap[marker.severity], severity: errorServerityMap[error.severity],
startLineNumber: ((lineColumn.start && lineColumn.start.line) || 0) + 1, startLineNumber: ((error.position.start && error.position.start.line) || 0),
startColumn: ((lineColumn.start && lineColumn.start.column) || 0) + 1, startColumn: ((error.position.start && error.position.start.column) || 0),
endLineNumber: ((lineColumn.end && lineColumn.end.line) || 0) + 1, endLineNumber: ((error.position.end && error.position.end.line) || 0),
endColumn: ((lineColumn.end && lineColumn.end.column) || 0) + 1, endColumn: ((error.position.end && error.position.end.column) || 0),
message: marker.message, message: error.message,
} }
console.log(markerData)
if (!allMarkersPerfile[filePath]) { if (!allMarkersPerfile[filePath]) {
allMarkersPerfile[filePath] = [] allMarkersPerfile[filePath] = []
} }
@ -391,7 +403,6 @@ export const EditorUI = (props: EditorUIProps) => {
for (const filePath in allMarkersPerfile) { for (const filePath in allMarkersPerfile) {
const model = editorModelsState[filePath]?.model const model = editorModelsState[filePath]?.model
if (model) { if (model) {
console.log(model)
monacoRef.current.editor.setModelMarkers(model, 'remix-solidity', allMarkersPerfile[filePath]) monacoRef.current.editor.setModelMarkers(model, 'remix-solidity', allMarkersPerfile[filePath])
} }
} }
@ -463,7 +474,7 @@ export const EditorUI = (props: EditorUIProps) => {
} }
} }
function handleEditorDidMount (editor) { function handleEditorDidMount(editor) {
editorRef.current = editor editorRef.current = editor
defineAndSetTheme(monacoRef.current) defineAndSetTheme(monacoRef.current)
reducerListener(props.plugin, dispatch, monacoRef.current, editorRef.current, props.events) reducerListener(props.plugin, dispatch, monacoRef.current, editorRef.current, props.events)
@ -481,7 +492,7 @@ export const EditorUI = (props: EditorUIProps) => {
editor.addCommand(monacoRef.current.KeyMod.CtrlCmd | monacoRef.current.KeyCode.US_MINUS, () => { editor.addCommand(monacoRef.current.KeyMod.CtrlCmd | monacoRef.current.KeyCode.US_MINUS, () => {
editor.updateOptions({ fontSize: editor.getOption(43).fontSize - 1 }) editor.updateOptions({ fontSize: editor.getOption(43).fontSize - 1 })
}) })
// add context menu items // add context menu items
const zoominAction = { const zoominAction = {
id: "zoomIn", id: "zoomIn",
@ -511,25 +522,25 @@ export const EditorUI = (props: EditorUIProps) => {
const editorService = editor._codeEditorService; const editorService = editor._codeEditorService;
const openEditorBase = editorService.openCodeEditor.bind(editorService); const openEditorBase = editorService.openCodeEditor.bind(editorService);
editorService.openCodeEditor = async (input, source) => { editorService.openCodeEditor = async (input, source) => {
const result = await openEditorBase(input, source) const result = await openEditorBase(input, source)
if (input && input.resource && input.resource.path) { if (input && input.resource && input.resource.path) {
try { try {
await props.plugin.call('fileManager', 'open', input.resource.path) await props.plugin.call('fileManager', 'open', input.resource.path)
} catch (e) { } catch (e) {
console.log(e) console.log(e)
}
} }
return result }
return result
} }
} }
function handleEditorWillMount (monaco) { function handleEditorWillMount(monaco) {
monacoRef.current = monaco monacoRef.current = monaco
// Register a new language // Register a new language
monacoRef.current.languages.register({ id: 'remix-solidity' }) monacoRef.current.languages.register({ id: 'remix-solidity' })
monacoRef.current.languages.register({ id: 'remix-cairo' }) monacoRef.current.languages.register({ id: 'remix-cairo' })
monacoRef.current.languages.register({ id: 'remix-zokrates' }) monacoRef.current.languages.register({ id: 'remix-zokrates' })
// Register a tokens provider for the language // Register a tokens provider for the language
monacoRef.current.languages.setMonarchTokensProvider('remix-solidity', solidityTokensProvider) monacoRef.current.languages.setMonarchTokensProvider('remix-solidity', solidityTokensProvider)
monacoRef.current.languages.setLanguageConfiguration('remix-solidity', solidityLanguageConfig) monacoRef.current.languages.setLanguageConfiguration('remix-solidity', solidityLanguageConfig)
@ -551,7 +562,7 @@ export const EditorUI = (props: EditorUIProps) => {
language={editorModelsState[props.currentFile] ? editorModelsState[props.currentFile].language : 'text'} language={editorModelsState[props.currentFile] ? editorModelsState[props.currentFile].language : 'text'}
onMount={handleEditorDidMount} onMount={handleEditorDidMount}
beforeMount={handleEditorWillMount} beforeMount={handleEditorWillMount}
options={{ glyphMargin: true, readOnly: true}} options={{ glyphMargin: true, readOnly: true }}
defaultValue={defaultEditorValue} defaultValue={defaultEditorValue}
/> />
<div className="contextview"> <div className="contextview">
@ -559,9 +570,9 @@ export const EditorUI = (props: EditorUIProps) => {
hide={false} hide={false}
gotoLine={(line, column) => props.plugin.call('editor', 'gotoLine', line, column)} gotoLine={(line, column) => props.plugin.call('editor', 'gotoLine', line, column)}
openFile={(file) => props.plugin.call('fileManager', 'switchFile', file)} openFile={(file) => props.plugin.call('fileManager', 'switchFile', file)}
getLastCompilationResult={() => { return props.plugin.call('compilerArtefacts', 'getLastCompilationResult') } } getLastCompilationResult={() => { return props.plugin.call('compilerArtefacts', 'getLastCompilationResult') }}
offsetToLineColumn={(position, file, sources, asts) => { return props.plugin.call('offsetToLineColumnConverter', 'offsetToLineColumn', position, file, sources, asts) } } offsetToLineColumn={(position, file, sources, asts) => { return props.plugin.call('offsetToLineColumnConverter', 'offsetToLineColumn', position, file, sources, asts) }}
getCurrentFileName={() => { return props.plugin.call('fileManager', 'file') } } getCurrentFileName={() => { return props.plugin.call('fileManager', 'file') }}
onContextListenerChanged={(listener) => { props.plugin.on('contextualListener', 'contextChanged', listener) }} onContextListenerChanged={(listener) => { props.plugin.on('contextualListener', 'contextChanged', listener) }}
onCurrentFileChanged={(listener) => { props.plugin.on('fileManager', 'currentFileChanged', listener) }} onCurrentFileChanged={(listener) => { props.plugin.on('fileManager', 'currentFileChanged', listener) }}
referencesOf={(node: astNode) => { return props.plugin.call('contextualListener', 'referencesOf', node) }} referencesOf={(node: astNode) => { return props.plugin.call('contextualListener', 'referencesOf', node) }}

Loading…
Cancel
Save