editorcontextDummy
filip mertens 2 years ago
parent 1303bac2e0
commit 63bbfbb692
  1. 151
      apps/remix-ide/src/app/plugins/code-parser.tsx
  2. 18
      libs/remix-core-plugin/src/lib/editor-context-listener.ts
  3. 41
      libs/remix-ui/editor/src/lib/remix-ui-editor.tsx
  4. 1
      libs/remix-ui/file-decorators/src/lib/types/index.ts

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

@ -35,6 +35,7 @@ export class EditorContextListener extends Plugin {
} }
async onActivation() { async onActivation() {
return
this.on('editor', 'contentChanged', async () => { this.on('editor', 'contentChanged', async () => {
console.log('contentChanged') console.log('contentChanged')
this._stopHighlighting() this._stopHighlighting()
@ -45,6 +46,7 @@ export class EditorContextListener extends Plugin {
}) })
setInterval(async () => { setInterval(async () => {
console.log('interval')
const compilationResult = await this.call('codeParser', 'getLastCompilationResult') const compilationResult = await this.call('codeParser', 'getLastCompilationResult')
if (compilationResult && compilationResult.languageversion.indexOf('soljson') === 0) { if (compilationResult && compilationResult.languageversion.indexOf('soljson') === 0) {
@ -163,7 +165,7 @@ export class EditorContextListener extends Plugin {
} }
async _highlightExpressions(node, compilationResult) { async _highlightExpressions(node, compilationResult) {
const highlights = async (id) => { const highlights = async (id) => {
const refs = await this.call('codeParser', 'getDeclaration', id) const refs = await this.call('codeParser', 'getDeclaration', id)
if (refs) { if (refs) {
@ -183,7 +185,7 @@ export class EditorContextListener extends Plugin {
} }
this.results = compilationResult this.results = compilationResult
} }
_stopHighlighting() { _stopHighlighting() {
@ -221,11 +223,13 @@ export class EditorContextListener extends Plugin {
for (const i in this.nodes) { for (const i in this.nodes) {
if (this.nodes[i].id === node.scope) { if (this.nodes[i].id === node.scope) {
const contract = this.nodes[i] const contract = this.nodes[i]
this.contract = this.results.data.contracts[path][contract.name] this.contract = this.results.data.contracts && this.results.data.contracts[path] && this.results.data.contracts[path][contract.name]
if (contract) { if (this.contract) {
this.estimationObj = this.contract.evm.gasEstimates this.estimationObj = this.contract.evm && this.contract.evm.gasEstimates
this.creationCost = this.estimationObj === null ? '-' : this.estimationObj.creation.totalCost if (this.estimationObj) {
this.codeDepositCost = this.estimationObj === null ? '-' : this.estimationObj.creation.codeDepositCost this.creationCost = this.estimationObj === null ? '-' : this.estimationObj.creation.totalCost
this.codeDepositCost = this.estimationObj === null ? '-' : this.estimationObj.creation.codeDepositCost
}
} }
} }
} }

@ -78,7 +78,7 @@ export interface EditorUIProps {
getHoverPosition: (position: IPosition) => number getHoverPosition: (position: IPosition) => number
addDecoration: (marker: sourceMarker, filePath: string, typeOfDecoration: string) => DecorationsReturn addDecoration: (marker: sourceMarker, filePath: string, typeOfDecoration: string) => DecorationsReturn
addErrorMarker: (errors: []) => void addErrorMarker: (errors: []) => void
clearErrorMarkers: (sources: {}) => void clearErrorMarkers: (sources: any) => void
clearDecorationsByPlugin: (filePath: string, plugin: string, typeOfDecoration: string, registeredDecorations: any, currentDecorations: any) => DecorationsReturn clearDecorationsByPlugin: (filePath: string, plugin: string, typeOfDecoration: string, registeredDecorations: any, currentDecorations: any) => DecorationsReturn
keepDecorationsFor: (filePath: string, plugin: string, typeOfDecoration: string, registeredDecorations: any, currentDecorations: any) => DecorationsReturn keepDecorationsFor: (filePath: string, plugin: string, typeOfDecoration: string, registeredDecorations: any, currentDecorations: any) => DecorationsReturn
} }
@ -359,7 +359,7 @@ export const EditorUI = (props: EditorUIProps) => {
props.editorAPI.addErrorMarker = async (errors: []) => { props.editorAPI.addErrorMarker = async (errors: []) => {
let allMarkersPerfile: Record<string, Array<monaco.editor.IMarkerData>> = {} const allMarkersPerfile: Record<string, Array<monaco.editor.IMarkerData>> = {}
for (const error of errors) { for (const error of errors) {
const marker = (error as any).error const marker = (error as any).error
const lineColumn = (error as any).lineColumn const lineColumn = (error as any).lineColumn
@ -378,10 +378,10 @@ 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[marker.severity],
startLineNumber: lineColumn.start.line + 1, startLineNumber: (lineColumn.start && lineColumn.start.line) || 0 + 1,
startColumn: lineColumn.start.column + 1, startColumn: (lineColumn.start && lineColumn.start.column) || 0 + 1,
endLineNumber: lineColumn.end.line + 1, endLineNumber: (lineColumn.end && lineColumn.end.line) || 0 + 1,
endColumn: lineColumn.end.column + 1, endColumn: (lineColumn.end && lineColumn.end.column) || 0 + 1,
message: marker.message, message: marker.message,
} }
console.log(markerData) console.log(markerData)
@ -399,13 +399,15 @@ export const EditorUI = (props: EditorUIProps) => {
} }
} }
props.editorAPI.clearErrorMarkers = async (sources: {}) => { props.editorAPI.clearErrorMarkers = async (sources: any) => {
console.log('clear', sources) if (sources) {
for (const source of Object.keys(sources)) { console.log('clear', sources)
const filePath = source for (const source of (Array.isArray(sources) ? sources : Object.keys(sources))) {
const model = editorModelsState[filePath]?.model const filePath = source
if (model) { const model = editorModelsState[filePath]?.model
monacoRef.current.editor.setModelMarkers(model, 'remix-solidity', []) if (model) {
monacoRef.current.editor.setModelMarkers(model, 'remix-solidity', [])
}
} }
} }
} }
@ -519,6 +521,19 @@ export const EditorUI = (props: EditorUIProps) => {
noSyntaxValidation: false, noSyntaxValidation: false,
}); });
monacoRef.current.languages.registerDocumentHighlightProvider('remix-solidity', {
provideDocumentHighlights(model: any, position: any, token: any) {
console.log('HIghlight', position)
const hightlights = [
{
range: new monacoRef.current.Range(position.lineNumber, position.column, position.lineNumber, position.column+5),
kind: monacoRef.current.languages.DocumentHighlightKind.Write
}
]
return hightlights
}
})
monacoRef.current.languages.registerReferenceProvider('remix-solidity', new RemixReferenceProvider(props, monaco)) monacoRef.current.languages.registerReferenceProvider('remix-solidity', new RemixReferenceProvider(props, monaco))
monacoRef.current.languages.registerHoverProvider('remix-solidity', new RemixHoverProvider(props, monaco)) monacoRef.current.languages.registerHoverProvider('remix-solidity', new RemixHoverProvider(props, monaco))
monacoRef.current.languages.registerCompletionItemProvider('remix-solidity', new RemixCompletionProvider(props, monaco)) monacoRef.current.languages.registerCompletionItemProvider('remix-solidity', new RemixCompletionProvider(props, monaco))

@ -13,6 +13,7 @@ export enum fileDecorationType {
New = 'NEW', New = 'NEW',
Compiled = 'COMPILED', Compiled = 'COMPILED',
Custom = 'CUSTOM', Custom = 'CUSTOM',
None = 'NONE'
} }
export type fileDecoration = { export type fileDecoration = {

Loading…
Cancel
Save