changes to plugin

pull/3321/head^2
Joseph Izang 2 years ago committed by Aniket
parent 59fc2952a1
commit 76792659e9
  1. 2
      apps/remix-ide/src/app.js
  2. 69
      apps/remix-ide/src/app/plugins/solidity-umlgen.tsx
  3. 57
      libs/remix-ui/solidity-uml-gen/src/lib/solidity-uml-gen.tsx
  4. 3
      libs/remix-ui/solidity-uml-gen/src/types/index.ts
  5. 61
      libs/remix-ui/workspace/src/lib/components/file-explorer.tsx
  6. 2
      libs/remix-ui/workspace/src/lib/types/index.ts

@ -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()

@ -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<any> = () => {}
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<any>) {
this.dispatch = dispatch
this.renderComponent()
}
render() {
return <div id="sol-uml-gen"><RemixUiSolidityUmlGen plugin={this} /></div>
return <div id='sol-uml-gen'>
<PluginViewWrapper plugin={this} />
</div>
}
}
renderComponent () {
this.dispatch(this)
}
updateComponent(state: any) {
return <div id="sol-uml-gen"><RemixUiSolidityUmlGen plugin={state} updatedSvg={this.updatedSvg} /></div>
}
}

@ -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 => (
<button key={btn.buttonText} className="btn btn-primary btn-lg ml-4 mt-4" disabled={!btn.action}>{btn.buttonText}</button>
))}
</>
)
export function RemixUiSolidityUmlGen ({ plugin, updatedSvg }: RemixUiSolidityUmlGenProps) {
const [showViewer, setShowViewer] = useState(false)
const [svgPayload, setSVGPayload] = useState<string>(plugin.svgPayload)
const [svgPayload, setSVGPayload] = useState<string>('')
const validSvg = () => {
return updatedSvg.startsWith('<?xml') && updatedSvg.includes('<svg')
}
useEffect(() => {
if (plugin.updatedSvg.startsWith('<?xml') && plugin.updatedSvg.includes('<svg')) {
setSVGPayload(plugin.updatedSvg)
if (validSvg()) {
setSVGPayload(updatedSvg)
console.log({ svgPayload })
}
})
const buttons: ButtonAction[] = [
{
buttonText: 'Download as PDF',
svgValid: validSvg,
action: () => console.log('generated!!')
},
{
buttonText: 'Download as PNG',
svgValid: validSvg,
action: () => console.log('generated!!')
}
]
return (
<div>
<h1>Solidity 2 UML Generator View!</h1>
<Viewer
<div className="d-flex flex-column">
<div className="d-flex justify-center align-content-center">
<ActionButtons buttons={buttons}/>
</div>
<div>
<Viewer
visible={showViewer}
rotatable={false}
loop={false}
@ -30,8 +66,9 @@ export function RemixUiSolidityUmlGen ({ plugin }: RemixUiSolidityUmlGenProps) {
changeable={false}
zoomSpeed={0.2}
minScale={1}
images={[{src: `data:image/svg+xml;base64,${btoa(svgPayload)}`}]}
images={[{src: `data:image/svg+xml;base64,${btoa(updatedSvg ?? svgPayload)}`}]}
/>
</div>
</div>
)
}

@ -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<any>): void
render(): JSX.Element
}

@ -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 (
<Drag onFileMoved={handleFileMove} onFolderMoved={handleFolderMove}>
<div ref={treeRef} tabIndex={0} style={{ outline: "none" }}>

@ -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<void>
}
export interface FileExplorerState {

Loading…
Cancel
Save