From 02a056fcd6aaa9f8a9893fd84fe2212550da8df3 Mon Sep 17 00:00:00 2001 From: Joseph Izang Date: Mon, 23 Jan 2023 23:19:00 +0100 Subject: [PATCH] changes to plugin --- apps/remix-ide/src/app.js | 2 +- .../src/app/plugins/solidity-umlgen.tsx | 69 +++++++++++++++++-- .../src/lib/solidity-uml-gen.tsx | 57 ++++++++++++--- .../solidity-uml-gen/src/types/index.ts | 3 + .../src/lib/components/file-explorer.tsx | 61 +++++++--------- .../remix-ui/workspace/src/lib/types/index.ts | 2 +- 6 files changed, 138 insertions(+), 56 deletions(-) diff --git a/apps/remix-ide/src/app.js b/apps/remix-ide/src/app.js index 8b316b5ae0..a90e94683b 100644 --- a/apps/remix-ide/src/app.js +++ b/apps/remix-ide/src/app.js @@ -175,7 +175,7 @@ class AppComponent { const search = new SearchPlugin() //---------------- Solidity UML Generator ------------------------- - const solidityumlgen = new SolidityUmlGen() + const solidityumlgen = new SolidityUmlGen(appManager) // ----------------- import content service ------------------------ const contentImport = new CompilerImports() diff --git a/apps/remix-ide/src/app/plugins/solidity-umlgen.tsx b/apps/remix-ide/src/app/plugins/solidity-umlgen.tsx index 7c0ee71454..52800fe90a 100644 --- a/apps/remix-ide/src/app/plugins/solidity-umlgen.tsx +++ b/apps/remix-ide/src/app/plugins/solidity-umlgen.tsx @@ -4,13 +4,19 @@ import React from 'react' // eslint-disable-next-line @nrwl/nx/enforce-module-boundaries import { RemixUiSolidityUmlGen } from '@remix-ui/solidity-uml-gen' import { ISolidityUmlGen } from 'libs/remix-ui/solidity-uml-gen/src/types' +import { RemixAppManager } from 'libs/remix-ui/plugin-manager/src/types' +import { concatSourceFiles, getDependencyGraph } from 'libs/remix-ui/solidity-compiler/src/lib/logic/flattenerUtilities' +import { convertUmlClasses2Dot } from 'sol2uml/lib/converterClasses2Dot' +import { convertAST2UmlClasses } from 'sol2uml/lib/converterAST2Classes' +import vizRenderStringSync from '@aduh95/viz.js/sync' +import { PluginViewWrapper } from '@remix-ui/helper' const profile = { name: 'solidityumlgen', displayName: 'Solidity UML Generator', description: 'Generate UML diagram in svg format from last compiled contract', location: 'mainPanel', - methods: ['showUmlDiagram'], + methods: ['showUmlDiagram', 'generateUml'], events: [], } @@ -20,23 +26,58 @@ export class SolidityUmlGen extends ViewPlugin implements ISolidityUmlGen { svgPayload: string updatedSvg: string amIActivated: boolean - constructor() { + appManager: RemixAppManager + result: any + dispatch: React.Dispatch = () => {} + constructor(appManager: RemixAppManager) { super(profile) this.currentFile = '' this.svgPayload = '' this.updatedSvg = '' + this.appManager = appManager this.element = document.createElement('div') this.element.setAttribute('id', 'sol-uml-gen') } onActivation(): void { this.amIActivated = true - console.log('amIActivated is set to true') } onDeactivation(): void { this.amIActivated = false - console.log('amIActivated is set to false') + } + + generateUml(currentFile: string) { + this.updatedSvg = currentFile + this.on('solidity', 'compilationFinished', async (file, source, languageVersion, data, input, version) => { + console.log({ file, languageVersion, input, version }) + if (data.sources && Object.keys(data.sources).length > 1) { // we should flatten first as there are multiple asts + this.flattenContract(source, currentFile, data) + } + const ast = this.result.length > 1 ? parser.parse(this.result) : parser.parse(source.sources[currentFile].content) + const payload = vizRenderStringSync(convertUmlClasses2Dot(convertAST2UmlClasses(ast, currentFile))) + const fileName = `${currentFile.split('/')[0]}/resources/${currentFile.split('/')[1].split('.')[0]}.svg` + await this.call('fileManager', 'writeFile', fileName, payload) + this.showUmlDiagram(fileName, payload) + }) + } + + /** + * Takes currently compiled contract that has a bunch of imports at the top + * and flattens them ready for UML creation. Takes the flattened result + * and assigns to a local property + * @returns void + */ + flattenContract (source: any, filePath: string, data: any) { + const ast = data.sources + const dependencyGraph = getDependencyGraph(ast, filePath) + const sorted = dependencyGraph.isEmpty() + ? [filePath] + : dependencyGraph.sort().reverse() + const sources = source.sources + const result = concatSourceFiles(sorted, sources) + this.call('fileManager', 'writeFile', `${filePath}_flattened.sol`, result) + this.result = result } showUmlDiagram(path: string, svgPayload: string) { @@ -55,7 +96,23 @@ export class SolidityUmlGen extends ViewPlugin implements ISolidityUmlGen { } + setDispatch (dispatch: React.Dispatch) { + this.dispatch = dispatch + this.renderComponent() + } + render() { - return
+ return
+ +
} -} \ No newline at end of file + + renderComponent () { + this.dispatch(this) + } + + updateComponent(state: any) { + return
+ } +} + diff --git a/libs/remix-ui/solidity-uml-gen/src/lib/solidity-uml-gen.tsx b/libs/remix-ui/solidity-uml-gen/src/lib/solidity-uml-gen.tsx index b1b5761588..e2aa734620 100644 --- a/libs/remix-ui/solidity-uml-gen/src/lib/solidity-uml-gen.tsx +++ b/libs/remix-ui/solidity-uml-gen/src/lib/solidity-uml-gen.tsx @@ -2,24 +2,60 @@ import React, { useEffect, useState } from 'react' import Viewer from 'react-viewer' import { ISolidityUmlGen } from '../types' export interface RemixUiSolidityUmlGenProps { - plugin: ISolidityUmlGen + plugin?: ISolidityUmlGen + updatedSvg?: string } -export function RemixUiSolidityUmlGen ({ plugin }: RemixUiSolidityUmlGenProps) { +type ButtonAction = { + svgValid: () => boolean + action: () => void + buttonText: string +} + +interface ActionButtonsProps { + buttons: ButtonAction[] +} + +const ActionButtons = ({ buttons }: ActionButtonsProps) => ( + <> + {buttons.map(btn => ( + + ))} + +) + +export function RemixUiSolidityUmlGen ({ plugin, updatedSvg }: RemixUiSolidityUmlGenProps) { const [showViewer, setShowViewer] = useState(false) - const [svgPayload, setSVGPayload] = useState(plugin.svgPayload) + const [svgPayload, setSVGPayload] = useState('') + const validSvg = () => { + return updatedSvg.startsWith(' { - if (plugin.updatedSvg.startsWith(' console.log('generated!!') + }, + { + buttonText: 'Download as PNG', + svgValid: validSvg, + action: () => console.log('generated!!') + } + ] return ( -
-

Solidity 2 UML Generator View!

- +
+ +
+
+ +
) } diff --git a/libs/remix-ui/solidity-uml-gen/src/types/index.ts b/libs/remix-ui/solidity-uml-gen/src/types/index.ts index 706dd56538..6423075344 100644 --- a/libs/remix-ui/solidity-uml-gen/src/types/index.ts +++ b/libs/remix-ui/solidity-uml-gen/src/types/index.ts @@ -7,5 +7,8 @@ export interface ISolidityUmlGen extends ViewPlugin { svgPayload: string updatedSvg: string showUmlDiagram(path: string, svgPayload: string): void + updateComponent(state: any): JSX.Element + setDispatch(dispatch: React.Dispatch): void + render(): JSX.Element } \ No newline at end of file diff --git a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx index 2624305b2c..d3eb40c40e 100644 --- a/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx +++ b/libs/remix-ui/workspace/src/lib/components/file-explorer.tsx @@ -6,10 +6,10 @@ import { FileExplorerProps, MenuItems, FileExplorerState } from '../types' import { customAction } from '@remixproject/plugin-api/lib/file-system/file-panel' import { contextMenuActions } from '../utils' const parser = (window as any).SolidityParser -import { convertUmlClasses2Dot } from 'sol2uml/lib/converterClasses2Dot' -import vizRenderStringSync from '@aduh95/viz.js/sync' import domToPdf from 'dom-to-pdf' import { jsPDF } from 'jspdf' +import vizRenderStringSync from '@aduh95/viz.js/sync' +import { convertUmlClasses2Dot } from 'sol2uml/lib/converterClasses2Dot' import { convertAST2UmlClasses } from 'sol2uml/lib/converterAST2Classes' @@ -451,44 +451,29 @@ export const FileExplorer = (props: FileExplorerProps) => { * Take AST and generates a UML diagram of compiled contract as svg * @returns void */ - const generateUml = (path: string) => { - try { - const currentFile = path - let ast: any - plugin.call('solidity', 'compile', path) - plugin.on('solidity', 'compilationFinished', async (file, source, languageVersion, data, input, version) => { - if (data.sources && Object.keys(data.sources).length > 1) { // we should flatten first as there are multiple asts - flattenContract(source, currentFile, data) - } - ast = contentForAST.length > 1 ? parser.parse(contentForAST) : parser.parse(source.sources[currentFile].content) - const payload = vizRenderStringSync(convertUmlClasses2Dot(convertAST2UmlClasses(ast, currentFile))) - const fileName = `${currentFile.split('/')[0]}/resources/${currentFile.split('/')[1].split('.')[0]}.svg` - plugin.call('fileManager', 'writeFile', fileName, payload) - if (!await plugin.appManager.isActive('solidityumlgen')) await plugin.appManager.activatePlugin('solidityumlgen') - plugin.call('solidityumlgen', 'showUmlDiagram', fileName, payload) - }) - } catch (error) { - console.log({ error }) - } + const generateUml = async (path: string) => { + // try { + // const currentFile = path + // let ast: any + // plugin.call('solidity', 'compile', path) + // plugin.on('solidity', 'compilationFinished', async (file, source, languageVersion, data, input, version) => { + // if (data.sources && Object.keys(data.sources).length > 1) { // we should flatten first as there are multiple asts + // flattenContract(source, currentFile, data) + // } + // ast = contentForAST.length > 1 ? parser.parse(contentForAST) : parser.parse(source.sources[currentFile].content) + // const payload = vizRenderStringSync(convertUmlClasses2Dot(convertAST2UmlClasses(ast, currentFile))) + // const fileName = `${currentFile.split('/')[0]}/resources/${currentFile.split('/')[1].split('.')[0]}.svg` + // plugin.call('fileManager', 'writeFile', fileName, payload) + // if (!await plugin.appManager.isActive('solidityumlgen')) await plugin.appManager.activatePlugin('solidityumlgen') + // plugin.call('solidityumlgen', 'showUmlDiagram', fileName, payload) + // }) + // } catch (error) { + // console.log({ error }) + // } + if (!await plugin.appManager.isActive('solidityumlgen')) await plugin.appManager.activatePlugin('solidityumlgen') + await plugin.call('solidityumlgen', 'generateUml', path) } - /** - * Takes currently compiled contract that has a bunch of imports at the top - * and flattens them ready for UML creation. Takes the flattened result - * and assigns to a local property - * @returns void - */ - const flattenContract = (source: any, filePath: string, data: any) => { - const ast = data.sources - const dependencyGraph = getDependencyGraph(ast, filePath) - const sorted = dependencyGraph.isEmpty() - ? [filePath] - : dependencyGraph.sort().reverse() - const sources = source.sources - const result = concatSourceFiles(sorted, sources) - plugin.call('fileManager', 'writeFile', `${filePath}_flattened.sol`, result) - setContentForAST(result) - } return (
diff --git a/libs/remix-ui/workspace/src/lib/types/index.ts b/libs/remix-ui/workspace/src/lib/types/index.ts index 95456141c5..88a000e655 100644 --- a/libs/remix-ui/workspace/src/lib/types/index.ts +++ b/libs/remix-ui/workspace/src/lib/types/index.ts @@ -145,7 +145,7 @@ export interface FileExplorerContextMenuProps { paste?: (destination: string, type: string) => void copyFileName?: (path: string, type: string) => void copyPath?: (path: string, type: string) => void - generateUml?: (path: string) => void + generateUml?: (path: string) => Promise } export interface FileExplorerState {