Fix resolving duplicate includes

pull/5370/head
ioedeveloper 12 months ago committed by Aniket
parent eeb93b0fca
commit 82e337c62f
  1. 64
      apps/circuit-compiler/src/app/services/circomPluginClient.ts

@ -220,13 +220,15 @@ export class CircomPluginClient extends PluginClient {
this.internalEvents.emit('circuit_computing_witness_done')
}
async resolveDependencies(filePath: string, fileContent: string, output: ResolverOutput = {}, depPath: string = '', parent: string = ''): Promise<Record<string, string>> {
async resolveDependencies(filePath: string, fileContent: string, output?: Record<string, string>, depPath: string = '', blackPath: string[] = []): Promise<Record<string, string>> {
if (!output) output = { [filePath]: fileContent }
// extract all includes
const includes = (fileContent.match(/include ['"].*['"]/g) || []).map((include) => include.replace(/include ['"]/g, '').replace(/['"]/g, ''))
await Promise.all(
includes.map(async (include) => {
// fix for endless recursive includes
if (blackPath.includes(include)) return
let dependencyContent = ''
let path = include.replace(/(\.\.\/)+/g, '')
// @ts-ignore
@ -248,6 +250,7 @@ export class CircomPluginClient extends PluginClient {
if (relativePathExists) {
// fetch file content if include import exists as a relative path
path = relativePath
dependencyContent = await this.call('fileManager', 'readFile', relativePath)
} else {
if (include.startsWith('circomlib')) {
@ -264,7 +267,7 @@ export class CircomPluginClient extends PluginClient {
}
} else {
if (depPath) {
// if depPath is provided, try to resolve include import from './deps' folder in remix
// resolves relative dependecies for .deps folder
path = pathModule.resolve(depPath.slice(0, depPath.lastIndexOf('/')), include)
path = path.replace('https:/', 'https://')
if (path.indexOf('/') === 0) path = path.slice(1)
@ -276,43 +279,36 @@ export class CircomPluginClient extends PluginClient {
}
}
}
const fileNameToInclude = extractNameFromKey(include)
const similarFile = Object.keys(output).find(path => {
return path.indexOf(fileNameToInclude) > -1
})
const isDuplicateContent = similarFile && output[similarFile] ? output[similarFile].content === dependencyContent : false
if (output[include] && output[include].parent) {
// 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 {
// extract all includes from the dependency content
const dependencyIncludes = (dependencyContent.match(/include ['"].*['"]/g) || []).map((include) => include.replace(/include ['"]/g, '').replace(/['"]/g, ''))
if (path.indexOf('https://') === 0) {
// Regular expression to match include statements and make deps imports uniform
const includeRegex = /include "(.+?)";/g;
const replacement = 'include "circomlib/circuits/$1";';
dependencyContent = dependencyContent.replace(includeRegex, replacement);
}
output[include] = {
content: dependencyContent,
parent
// extract all includes from the dependency content
const dependencyIncludes = (dependencyContent.match(/include ['"].*['"]/g) || []).map((include) => {
const includeName = include.replace(/include ['"]/g, '').replace(/['"]/g, '')
if (!blackPath.includes(includeName)) return includeName
else {
// if include already exists in output, remove it from the dependency content
dependencyContent = dependencyContent.replace(`${include};`, '')
return
}
// recursively resolve all dependencies of the dependency
if (dependencyIncludes.length > 0) await this.resolveDependencies(filePath, dependencyContent, output, path, include)
}).filter((include) => include)
blackPath.push(include)
// recursively resolve all dependencies of the dependency
if (dependencyIncludes.length > 0) {
await this.resolveDependencies(filePath, dependencyContent, output, path, blackPath)
output[include] = dependencyContent
} else {
output[include] = dependencyContent
}
})
)
const result: Record<string, string> = {}
Object.keys(output).forEach((key) => {
result[key] = output[key].content
})
return result
return output
}
async resolveReportPath (path: string): Promise<string> {

Loading…
Cancel
Save