Modify dependency resolver to exclude duplicate contents

pull/5370/head
ioedeveloper 1 year ago
parent 7409cebcc0
commit 4294fb9785
  1. 53
      apps/circuit-compiler/src/app/services/circomPluginClient.ts
  2. 7
      apps/circuit-compiler/src/app/types/index.ts

@ -4,7 +4,7 @@ import EventManager from 'events'
import pathModule from 'path' import pathModule from 'path'
import { parse, compile, generate_witness, generate_r1cs, compiler_list } from 'circom_wasm' import { parse, compile, generate_witness, generate_r1cs, compiler_list } from 'circom_wasm'
import { extractNameFromKey, extractParentFromKey } from '@remix-ui/helper' import { extractNameFromKey, extractParentFromKey } from '@remix-ui/helper'
import { CompilationConfig, CompilerReport } from '../types' import { CompilationConfig, CompilerReport, ResolverOutput } from '../types'
export class CircomPluginClient extends PluginClient { export class CircomPluginClient extends PluginClient {
public internalEvents: EventManager public internalEvents: EventManager
@ -37,10 +37,7 @@ export class CircomPluginClient extends PluginClient {
// @ts-ignore // @ts-ignore
fileContent = await this.call('fileManager', 'readFile', path) fileContent = await this.call('fileManager', 'readFile', path)
} }
this.lastParsedFiles = { this.lastParsedFiles = await this.resolveDependencies(path, fileContent, { [path]: { content: fileContent, parent: null } })
[path]: fileContent,
}
this.lastParsedFiles = await this.resolveDependencies(path, fileContent, this.lastParsedFiles)
const parsedOutput = parse(path, this.lastParsedFiles) const parsedOutput = parse(path, this.lastParsedFiles)
try { try {
@ -211,14 +208,13 @@ export class CircomPluginClient extends PluginClient {
this.internalEvents.emit('circuit_computing_witness_done') this.internalEvents.emit('circuit_computing_witness_done')
} }
async resolveDependencies(filePath: string, fileContent: string, output = {}, depPath: string = '', blackPath: string[] = []): Promise<Record<string, string>> { async resolveDependencies(filePath: string, fileContent: string, output: ResolverOutput = {}, depPath: string = '', parent: string = ''): Promise<Record<string, string>> {
// extract all includes // extract all includes
const includes = (fileContent.match(/include ['"].*['"]/g) || []).map((include) => include.replace(/include ['"]/g, '').replace(/['"]/g, '')) const includes = (fileContent.match(/include ['"].*['"]/g) || []).map((include) => include.replace(/include ['"]/g, '').replace(/['"]/g, ''))
await Promise.all( await Promise.all(
includes.map(async (include) => { includes.map(async (include) => {
// fix for endless recursive includes // fix for endless recursive includes
if (blackPath.includes(include)) return
let dependencyContent = '' let dependencyContent = ''
let path = include let path = include
// @ts-ignore // @ts-ignore
@ -268,20 +264,43 @@ export class CircomPluginClient extends PluginClient {
} }
} }
} }
// extract all includes from the dependency content const fileNameToInclude = extractNameFromKey(include)
const dependencyIncludes = (dependencyContent.match(/include ['"].*['"]/g) || []).map((include) => include.replace(/include ['"]/g, '').replace(/['"]/g, '')) const similarFile = Object.keys(output).find(path => {
return path.indexOf(fileNameToInclude) > -1
blackPath.push(include) })
// recursively resolve all dependencies of the dependency const isDuplicateContent = similarFile && output[similarFile] ? output[similarFile].content === dependencyContent : false
if (dependencyIncludes.length > 0) {
await this.resolveDependencies(filePath, dependencyContent, output, path, blackPath) if (output[include] && output[include].parent) {
output[include] = dependencyContent // if include import already exists, remove the include import from the parent file
const regexPattern = new RegExp(`include ['"]${include}['"];`, 'g')
output[output[include].parent].content = output[output[include].parent].content.replace(regexPattern, "")
} else if (isDuplicateContent) {
// if include import has the same content as another file, replace the include import with the file name of the other file (similarFile)
if (output[similarFile].parent) output[output[similarFile].parent].content = output[output[similarFile].parent].content.replace(similarFile, include)
if (include !== similarFile) {
output[include] = output[similarFile]
delete output[similarFile]
}
} else { } else {
output[include] = dependencyContent // extract all includes from the dependency content
const dependencyIncludes = (dependencyContent.match(/include ['"].*['"]/g) || []).map((include) => include.replace(/include ['"]/g, '').replace(/['"]/g, ''))
output[include] = {
content: dependencyContent,
parent
}
// recursively resolve all dependencies of the dependency
if (dependencyIncludes.length > 0) await this.resolveDependencies(filePath, dependencyContent, output, path, include)
} }
}) })
) )
return output const result: Record<string, string> = {}
Object.keys(output).forEach((key) => {
result[key] = output[key].content
})
return result
} }
async resolveReportPath (path: string): Promise<string> { async resolveReportPath (path: string): Promise<string> {

@ -84,4 +84,11 @@ export type CompileOptionsProps = {
setCircuitHideWarnings: (value: boolean) => void, setCircuitHideWarnings: (value: boolean) => void,
autoCompile: boolean, autoCompile: boolean,
hideWarnings: boolean hideWarnings: boolean
}
export type ResolverOutput = {
[name: string]: {
content: string,
parent: string
}
} }
Loading…
Cancel
Save