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

@ -35,6 +35,7 @@ export class EditorContextListener extends Plugin {
}
async onActivation() {
return
this.on('editor', 'contentChanged', async () => {
console.log('contentChanged')
this._stopHighlighting()
@ -45,6 +46,7 @@ export class EditorContextListener extends Plugin {
})
setInterval(async () => {
console.log('interval')
const compilationResult = await this.call('codeParser', 'getLastCompilationResult')
if (compilationResult && compilationResult.languageversion.indexOf('soljson') === 0) {
@ -163,7 +165,7 @@ export class EditorContextListener extends Plugin {
}
async _highlightExpressions(node, compilationResult) {
const highlights = async (id) => {
const refs = await this.call('codeParser', 'getDeclaration', id)
if (refs) {
@ -183,7 +185,7 @@ export class EditorContextListener extends Plugin {
}
this.results = compilationResult
}
_stopHighlighting() {
@ -221,11 +223,13 @@ export class EditorContextListener extends Plugin {
for (const i in this.nodes) {
if (this.nodes[i].id === node.scope) {
const contract = this.nodes[i]
this.contract = this.results.data.contracts[path][contract.name]
if (contract) {
this.estimationObj = this.contract.evm.gasEstimates
this.creationCost = this.estimationObj === null ? '-' : this.estimationObj.creation.totalCost
this.codeDepositCost = this.estimationObj === null ? '-' : this.estimationObj.creation.codeDepositCost
this.contract = this.results.data.contracts && this.results.data.contracts[path] && this.results.data.contracts[path][contract.name]
if (this.contract) {
this.estimationObj = this.contract.evm && this.contract.evm.gasEstimates
if (this.estimationObj) {
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
addDecoration: (marker: sourceMarker, filePath: string, typeOfDecoration: string) => DecorationsReturn
addErrorMarker: (errors: []) => void
clearErrorMarkers: (sources: {}) => void
clearErrorMarkers: (sources: any) => void
clearDecorationsByPlugin: (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: []) => {
let allMarkersPerfile: Record<string, Array<monaco.editor.IMarkerData>> = {}
const allMarkersPerfile: Record<string, Array<monaco.editor.IMarkerData>> = {}
for (const error of errors) {
const marker = (error as any).error
const lineColumn = (error as any).lineColumn
@ -378,10 +378,10 @@ export const EditorUI = (props: EditorUIProps) => {
if (model) {
const markerData: monaco.editor.IMarkerData = {
severity: errorServerityMap[marker.severity],
startLineNumber: lineColumn.start.line + 1,
startColumn: lineColumn.start.column + 1,
endLineNumber: lineColumn.end.line + 1,
endColumn: lineColumn.end.column + 1,
startLineNumber: (lineColumn.start && lineColumn.start.line) || 0 + 1,
startColumn: (lineColumn.start && lineColumn.start.column) || 0 + 1,
endLineNumber: (lineColumn.end && lineColumn.end.line) || 0 + 1,
endColumn: (lineColumn.end && lineColumn.end.column) || 0 + 1,
message: marker.message,
}
console.log(markerData)
@ -399,13 +399,15 @@ export const EditorUI = (props: EditorUIProps) => {
}
}
props.editorAPI.clearErrorMarkers = async (sources: {}) => {
console.log('clear', sources)
for (const source of Object.keys(sources)) {
const filePath = source
const model = editorModelsState[filePath]?.model
if (model) {
monacoRef.current.editor.setModelMarkers(model, 'remix-solidity', [])
props.editorAPI.clearErrorMarkers = async (sources: any) => {
if (sources) {
console.log('clear', sources)
for (const source of (Array.isArray(sources) ? sources : Object.keys(sources))) {
const filePath = source
const model = editorModelsState[filePath]?.model
if (model) {
monacoRef.current.editor.setModelMarkers(model, 'remix-solidity', [])
}
}
}
}
@ -519,6 +521,19 @@ export const EditorUI = (props: EditorUIProps) => {
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.registerHoverProvider('remix-solidity', new RemixHoverProvider(props, monaco))
monacoRef.current.languages.registerCompletionItemProvider('remix-solidity', new RemixCompletionProvider(props, monaco))

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

Loading…
Cancel
Save