From 360ce32f703c8b726fef25e24c7ca8b768a6e57b Mon Sep 17 00:00:00 2001 From: bunsenstraat Date: Sat, 14 May 2022 09:13:11 +0200 Subject: [PATCH] hovers --- apps/remix-ide/src/app/editor/editor.js | 7 +- .../src/lib/editor-context-listener.ts | 60 +++++----- .../remix-ui/editor/src/lib/actions/editor.ts | 9 +- .../editor/src/lib/remix-ui-editor.tsx | 113 +++++++++++------- .../src/lib/components/environment.tsx | 2 +- 5 files changed, 116 insertions(+), 75 deletions(-) diff --git a/apps/remix-ide/src/app/editor/editor.js b/apps/remix-ide/src/app/editor/editor.js index ffd0b64652..05b7feadcf 100644 --- a/apps/remix-ide/src/app/editor/editor.js +++ b/apps/remix-ide/src/app/editor/editor.js @@ -12,7 +12,7 @@ const profile = { name: 'editor', description: 'service - editor', version: packageJson.version, - methods: ['highlight', 'discardHighlight', 'clearAnnotations', 'addAnnotation', 'gotoLine', 'revealRange', 'getCursorPosition', 'open'] + methods: ['highlight', 'discardHighlight', 'clearAnnotations', 'addAnnotation', 'gotoLine', 'revealRange', 'getCursorPosition', 'open', 'addModel'] } class Editor extends Plugin { @@ -163,6 +163,7 @@ class Editor extends Plugin { } async _onChange (file) { + console.log(file) const currentFile = await this.call('fileManager', 'file') if (!currentFile) { return @@ -244,6 +245,10 @@ class Editor extends Plugin { return this.api.findMatches(this.currentFile, string) } + addModel(path, content) { + this.emit('addModel', content, this._getMode(path), path, false) + } + /** * Display an Empty read-only session */ diff --git a/libs/remix-core-plugin/src/lib/editor-context-listener.ts b/libs/remix-core-plugin/src/lib/editor-context-listener.ts index e2445e28d9..47373dd745 100644 --- a/libs/remix-core-plugin/src/lib/editor-context-listener.ts +++ b/libs/remix-core-plugin/src/lib/editor-context-listener.ts @@ -6,7 +6,7 @@ import { AstNode } from '@remix-project/remix-solidity-ts' const profile = { name: 'contextualListener', - methods: ['jumpToDefinition', 'referrencesAtPosition', 'nodesAtEditorPosition', 'referencesOf', 'getActiveHighlights', 'gasEstimation', 'declarationOf', 'jumpToPosition'], + methods: ['definitionAtPosition', 'jumpToDefinition', 'referrencesAtPosition', 'nodesAtEditorPosition', 'referencesOf', 'getActiveHighlights', 'gasEstimation', 'declarationOf', 'jumpToPosition'], events: [], version: '0.0.1' } @@ -95,14 +95,13 @@ export class EditorContextListener extends Plugin { return null } - referencesOf(node) { + referencesOf(node: AstNode) { const results = [] const highlights = (id) => { if (this._index.Declarations && this._index.Declarations[id]) { const refs = this._index.Declarations[id] for (const ref in refs) { const node = refs[ref] - //console.log('reference', node) results.push(node) } } @@ -114,8 +113,7 @@ export class EditorContextListener extends Plugin { } else { highlights(node.id) } - - //console.log(results) + return results } async nodesAtEditorPosition(position: any) { @@ -131,43 +129,49 @@ export class EditorContextListener extends Plugin { const nodes = await this.nodesAtEditorPosition(position) if (nodes && nodes.length) { const node = nodes[nodes.length - 1] - if (node) { + if (node) { return this.referencesOf(node) } } } - async jumpToDefinition(position: any) { + async getNodeDefinition() { + + } + + async definitionAtPosition(position: any) { const nodes = await this.nodesAtEditorPosition(position) console.log(nodes) - let nodeDeclaration: AstNode + console.log(this._index.FlatReferences) + let nodeDefinition: AstNode let node: AstNode if (nodes && nodes.length) { node = nodes[nodes.length - 1] + nodeDefinition = node if (!isDefinition(node)) { - nodeDeclaration = await this.declarationOf(node) - } else { - nodeDeclaration = node + nodeDefinition = await this.declarationOf(node) || node } - } - // console.log(node, nodeDeclaration) - if (nodeDeclaration && nodeDeclaration.src) { - //console.log(nodeDeclaration) - const position = sourceMappingDecoder.decode(nodeDeclaration.src) - if (position) { - console.log('jump to', position) - await this.jumpToPosition(position) + if (node.nodeType === 'ImportDirective') { + for (const key in this._index.FlatReferences) { + if (this._index.FlatReferences[key].id === node.sourceUnit) { + nodeDefinition = this._index.FlatReferences[key] + } + } } + return nodeDefinition + }else{ + console.log('no node found') } - // jump to import - if (node && node.nodeType === 'ImportDirective') { - console.log(this._index.FlatReferences) - // loop over this._index.FlatReferences - for (const key in this._index.FlatReferences) { - if (this._index.FlatReferences[key].id === node.sourceUnit) { - console.log('jump to', this._index.FlatReferences[key]) - const position = sourceMappingDecoder.decode(this._index.FlatReferences[key].src) - this.jumpToPosition(position) + + } + + async jumpToDefinition(position: any) { + const node = await this.definitionAtPosition(position) + if (node) { + if (node.src) { + const position = sourceMappingDecoder.decode(node.src) + if (position) { + await this.jumpToPosition(position) } } } diff --git a/libs/remix-ui/editor/src/lib/actions/editor.ts b/libs/remix-ui/editor/src/lib/actions/editor.ts index 0c968e1f07..eb35640b00 100644 --- a/libs/remix-ui/editor/src/lib/actions/editor.ts +++ b/libs/remix-ui/editor/src/lib/actions/editor.ts @@ -21,9 +21,14 @@ export const reducerActions = (models = initialState, action: Action) => { const readOnly = action.payload.readOnly if (models[uri]) return models // already existing models[uri] = { language, uri, readOnly } - console.log(uri) - const model = monaco.editor.createModel(value, language, monaco.Uri.parse(uri)) + let model + try{ + model = monaco.editor.createModel(value, language, monaco.Uri.parse(uri)) + }catch(e){ + + } models[uri].model = model + console.log('ADD_MODEL', models[uri].model) model.onDidChangeContent(() => action.payload.events.onDidChangeContent(uri)) return models } diff --git a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx index 23e87a3259..04be099b1e 100644 --- a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx +++ b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx @@ -358,7 +358,7 @@ export const EditorUI = (props: EditorUIProps) => { const model = editorModelsState[currentFileRef.current]?.model if (model) { return model.getOffsetAt(position) - }else{ + } else { return 0 } } @@ -424,72 +424,99 @@ export const EditorUI = (props: EditorUIProps) => { monacoRef.current.languages.setMonarchTokensProvider('remix-cairo', cairoLang) monacoRef.current.languages.setLanguageConfiguration('remix-cairo', cairoConf) - + // register Definition Provider monacoRef.current.languages.registerDefinitionProvider('remix-solidity', { - provideDefinition(model: monaco.editor.ITextModel, position: monaco.Position, token: monaco.CancellationToken){ + provideDefinition(model: monaco.editor.ITextModel, position: monaco.Position, token: monaco.CancellationToken) { const cursorPosition = props.editorAPI.getCursorPosition() props.plugin.call('contextualListener', 'jumpToDefinition', cursorPosition) } }) monacoRef.current.languages.registerReferenceProvider('remix-solidity', { - provideReferences(model: monaco.editor.ITextModel, position: monaco.Position, context: any, token: monaco.CancellationToken){ + async provideReferences(model: monaco.editor.ITextModel, position: monaco.Position, context: any, token: monaco.CancellationToken) { const cursorPosition = props.editorAPI.getCursorPosition() - const references = props.plugin.call('contextualListener', 'referrencesAtPosition', cursorPosition) - console.log(references) - return [{ - range: new monaco.Range( - 0, - 0, - 0, - 4 - ), - uri: monaco.Uri.parse('test.sol'), - }, - { - range: new monaco.Range( - 0, - 0, - 0, - 4 - ), - uri: monaco.Uri.parse('test2.sol'), - }] + const nodes = await props.plugin.call('contextualListener', 'referrencesAtPosition', cursorPosition) + const references = [] + if (nodes && nodes.length) { + const compilationResult = await props.plugin.call('compilerArtefacts', 'getLastCompilationResult') + const file = await props.plugin.call('fileManager', 'file') + if (compilationResult && compilationResult.data && compilationResult.data.sources[file]) { + for (const node of nodes) { + const position = sourceMappingDecoder.decode(node.src) + const fileInNode = compilationResult.getSourceName(position.file) + let fileTarget = await props.plugin.call('fileManager', 'getPathFromUrl', fileInNode) + fileTarget = fileTarget.file + const fileContent = await props.plugin.call('fileManager', 'readFile', fileInNode) + const lineColumn = await props.plugin.call('offsetToLineColumnConverter', 'offsetToLineColumn', + position, + position.file, + compilationResult.getSourceCode().sources, + compilationResult.getAsts()) + console.log(position, fileTarget, lineColumn) + try { + props.plugin.call('editor', 'addModel', fileTarget, fileContent) + } catch (e) { + + } + const range = new monaco.Range(lineColumn.start.line + 1, lineColumn.start.column + 1, lineColumn.end.line + 1, lineColumn.end.column + 1) + references.push({ + range, + uri: monaco.Uri.parse(fileTarget) + }) + } + } + } + return references } }) - + monacoRef.current.languages.registerHoverProvider('remix-solidity', { provideHover: async function (model: any, position: monaco.Position) { - //console.log(position) + console.log('--------------------') const cursorPosition = props.editorAPI.getHoverPosition(position) - //console.log(cursorPosition) - const compilationResult = await props.plugin.call('compilerArtefacts', 'getLastCompilationResult') - const file = await props.plugin.call('fileManager', 'file') - if (compilationResult && compilationResult.data && compilationResult.data.sources[file]) { - const nodes = sourceMappingDecoder.nodesAtPosition(null, cursorPosition, compilationResult.data.sources[file]) - // console.log(cursorPosition, nodes) - // loop over nodes - if (nodes && nodes.length) { - nodes.forEach((node) => { - const position = sourceMappingDecoder.decode(node.src) - const fileTarget = compilationResult.getSourceName(position.file) - // console.log(position, fileTarget) + const nodeDefinition = await props.plugin.call('contextualListener', 'definitionAtPosition', cursorPosition) + console.log(nodeDefinition) + const contents = [] + if (!nodeDefinition) return null + if (nodeDefinition.absolutePath) { + const target = await props.plugin.call('fileManager', 'getPathFromUrl', nodeDefinition.absolutePath) + if (target.file !== nodeDefinition.absolutePath) { + contents.push({ + value: `${target.file}` }) } + contents.push({ + value: `${nodeDefinition.absolutePath}` + }) + } + if (nodeDefinition.typeDescriptions && nodeDefinition.nodeType === 'VariableDeclaration') { + contents.push({ + value: `${nodeDefinition.typeDescriptions.typeString} ${nodeDefinition.name}` + }) + } + else if (nodeDefinition.typeDescriptions && nodeDefinition.nodeType === 'ElementaryTypeName') { + contents.push({ + value: `${nodeDefinition.typeDescriptions.typeString}` + }) + } else { + contents.push({ + value: `${nodeDefinition.nodeType}` + }) + } + for (const key in contents) { + contents[key].value = '```remix-solidity\n' + contents[key].value + '\n```' } return { range: new monaco.Range( - position.lineNumber, + position.lineNumber, position.column, - position.lineNumber, + position.lineNumber, model.getLineMaxColumn(position.lineNumber) ), - contents: [ - - ] + contents: contents }; } }) diff --git a/libs/remix-ui/run-tab/src/lib/components/environment.tsx b/libs/remix-ui/run-tab/src/lib/components/environment.tsx index 23d04f6d20..db8ab29650 100644 --- a/libs/remix-ui/run-tab/src/lib/components/environment.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/environment.tsx @@ -19,7 +19,7 @@ export function EnvironmentUI (props: EnvironmentProps) { Environment
- { handleChangeExEnv(e.target.value) }}> { props.providers.providerList.map((provider, index) =>