From fded39bb6650f76b6d8f9716089ff718621050b2 Mon Sep 17 00:00:00 2001 From: Patricio Palladino Date: Fri, 20 Sep 2024 21:33:30 +0000 Subject: [PATCH] Remove the v-next/resolver package --- v-next/resolver/.eslintrc.cjs | 3 - v-next/resolver/.gitignore | 5 - v-next/resolver/.prettierignore | 3 - v-next/resolver/LICENSE | 9 - v-next/resolver/README.md | 11 - v-next/resolver/package.json | 67 - .../resolver/src/dependency-graph-builder.ts | 263 ---- v-next/resolver/src/dependency-resolver.ts | 1182 ----------------- v-next/resolver/src/remappings.ts | 88 -- v-next/resolver/src/types.ts | 40 - v-next/resolver/test/dependency-resolver.ts | 906 ------------- v-next/resolver/test/remappings.ts | 214 --- v-next/resolver/test/test-fixtures/.gitignore | 1 - .../@scope/dependency/contracts/File.sol | 1 - .../@scope/dependency/package.json | 4 - .../node_modules/exports/package.json | 7 - .../monorepo/node_modules/hardhat-project | 1 - .../monorepo/node_modules/hardhat/console.sol | 1 - .../node_modules/hardhat/package.json | 4 - .../monorepo/node_modules/hoisted/File.sol | 1 - .../node_modules/hoisted/package.json | 4 - .../monorepo/node_modules/local-dependency | 1 - .../packages/hardhat-project/File.sol | 1 - .../hardhat-project/contracts/File.sol | 1 - .../hardhat-project/contracts/File2.sol | 1 - .../packages/hardhat-project/hardhat/File.sol | 1 - .../node_modules/dependency/File.sol | 1 - .../dependency/contracts/File.sol | 1 - .../dependencydependency/File.sol | 1 - .../dependencydependency/package.json | 4 - .../node_modules/dependency/npm/File.sol | 1 - .../node_modules/dependency/package.json | 4 - .../other-name/contracts/File.sol | 1 - .../node_modules/other-name/package.json | 4 - .../packages/hardhat-project/npm/File.sol | 1 - .../packages/hardhat-project/package.json | 4 - .../local-dependency/contracts/File.sol | 1 - .../dependency/contracts/File.sol | 1 - .../node_modules/dependency/package.json | 4 - .../packages/local-dependency/package.json | 4 - v-next/resolver/tsconfig.json | 27 - 41 files changed, 2879 deletions(-) delete mode 100644 v-next/resolver/.eslintrc.cjs delete mode 100644 v-next/resolver/.gitignore delete mode 100644 v-next/resolver/.prettierignore delete mode 100644 v-next/resolver/LICENSE delete mode 100644 v-next/resolver/README.md delete mode 100644 v-next/resolver/package.json delete mode 100644 v-next/resolver/src/dependency-graph-builder.ts delete mode 100644 v-next/resolver/src/dependency-resolver.ts delete mode 100644 v-next/resolver/src/remappings.ts delete mode 100644 v-next/resolver/src/types.ts delete mode 100644 v-next/resolver/test/dependency-resolver.ts delete mode 100644 v-next/resolver/test/remappings.ts delete mode 100644 v-next/resolver/test/test-fixtures/.gitignore delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/node_modules/@scope/dependency/contracts/File.sol delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/node_modules/@scope/dependency/package.json delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/node_modules/exports/package.json delete mode 120000 v-next/resolver/test/test-fixtures/monorepo/node_modules/hardhat-project delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/node_modules/hardhat/console.sol delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/node_modules/hardhat/package.json delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/node_modules/hoisted/File.sol delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/node_modules/hoisted/package.json delete mode 120000 v-next/resolver/test/test-fixtures/monorepo/node_modules/local-dependency delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/File.sol delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/contracts/File.sol delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/contracts/File2.sol delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/hardhat/File.sol delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/File.sol delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/contracts/File.sol delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/node_modules/dependencydependency/File.sol delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/node_modules/dependencydependency/package.json delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/npm/File.sol delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/package.json delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/other-name/contracts/File.sol delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/other-name/package.json delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/npm/File.sol delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/package.json delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/packages/local-dependency/contracts/File.sol delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/packages/local-dependency/node_modules/dependency/contracts/File.sol delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/packages/local-dependency/node_modules/dependency/package.json delete mode 100644 v-next/resolver/test/test-fixtures/monorepo/packages/local-dependency/package.json delete mode 100644 v-next/resolver/tsconfig.json diff --git a/v-next/resolver/.eslintrc.cjs b/v-next/resolver/.eslintrc.cjs deleted file mode 100644 index acf97c3303c..00000000000 --- a/v-next/resolver/.eslintrc.cjs +++ /dev/null @@ -1,3 +0,0 @@ -const { createConfig } = require("../../config-v-next/eslint.cjs"); - -module.exports = createConfig(__filename, ["src/index.ts"]); diff --git a/v-next/resolver/.gitignore b/v-next/resolver/.gitignore deleted file mode 100644 index 6aa5402c625..00000000000 --- a/v-next/resolver/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Node modules -/node_modules - -# Compilation output -/dist diff --git a/v-next/resolver/.prettierignore b/v-next/resolver/.prettierignore deleted file mode 100644 index 3760c88cd5d..00000000000 --- a/v-next/resolver/.prettierignore +++ /dev/null @@ -1,3 +0,0 @@ -/node_modules -/dist -CHANGELOG.md diff --git a/v-next/resolver/LICENSE b/v-next/resolver/LICENSE deleted file mode 100644 index 0781b4a8191..00000000000 --- a/v-next/resolver/LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -MIT License - -Copyright (c) 2024 Nomic Foundation - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/v-next/resolver/README.md b/v-next/resolver/README.md deleted file mode 100644 index 7fd7ac4e488..00000000000 --- a/v-next/resolver/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Template package - -This is a template package with a base configuration that should be shared by other packages. - -It sets up the following things: - -- Typescript -- eslint -- prettier -- npm scripts -- package.json' export field diff --git a/v-next/resolver/package.json b/v-next/resolver/package.json deleted file mode 100644 index bed79d37d41..00000000000 --- a/v-next/resolver/package.json +++ /dev/null @@ -1,67 +0,0 @@ -{ - "name": "@nomicfoundation/resolver", - "version": "3.0.0", - "description": "Hardhat's v3 resolver", - "homepage": "https://github.com/nomicfoundation/hardhat/tree/v-next/v-next/template-package", - "repository": "github:nomicfoundation/hardhat", - "author": "Nomic Foundation", - "license": "MIT", - "type": "module", - "types": "dist/src/index.d.ts", - "exports": { - ".": "./dist/src/index.js" - }, - "keywords": [ - "ethereum", - "smart-contracts", - "hardhat" - ], - "scripts": { - "lint": "pnpm prettier --check && pnpm eslint", - "lint:fix": "pnpm prettier --write && pnpm eslint --fix", - "eslint": "eslint \"src/**/*.ts\" \"test/**/*.ts\"", - "prettier": "prettier \"**/*.{ts,js,md,json}\"", - "test": "node --import tsx/esm --test --test-reporter=@ignored/hardhat-vnext-node-test-reporter \"test/*.ts\" \"test/!(fixture-projects|helpers)/**/*.ts\"", - "test:only": "node --import tsx/esm --test --test-only --test-reporter=@ignored/hardhat-vnext-node-test-reporter \"test/*.ts\" \"test/!(fixture-projects|helpers)/**/*.ts\"", - "pretest": "pnpm build", - "build": "tsc --build .", - "prepublishOnly": "pnpm build", - "clean": "rimraf dist" - }, - "files": [ - "dist/src/", - "src/", - "CHANGELOG.md", - "LICENSE", - "README.md" - ], - "devDependencies": { - "@eslint-community/eslint-plugin-eslint-comments": "^4.3.0", - "@ignored/hardhat-vnext-node-test-reporter": "workspace:^3.0.0-next.2", - "@nomicfoundation/eslint-plugin-hardhat-internal-rules": "workspace:^", - "@nomicfoundation/eslint-plugin-slow-imports": "workspace:^", - "@nomicfoundation/hardhat-test-utils": "workspace:^", - "@types/node": "^20.14.9", - "@typescript-eslint/eslint-plugin": "^7.7.1", - "@typescript-eslint/parser": "^7.7.1", - "c8": "^9.1.0", - "eslint": "8.57.0", - "eslint-config-prettier": "9.1.0", - "eslint-import-resolver-typescript": "^3.6.1", - "eslint-plugin-import": "2.29.1", - "eslint-plugin-no-only-tests": "3.1.0", - "expect-type": "^0.19.0", - "nyc": "^15.1.0", - "prettier": "3.2.5", - "rimraf": "^5.0.5", - "tsx": "^4.11.0", - "typescript": "~5.5.0", - "typescript-eslint": "7.7.1" - }, - "dependencies": { - "@ignored/hardhat-vnext-errors": "workspace:^3.0.0-next.2", - "@ignored/hardhat-vnext-utils": "workspace:^3.0.0-next.2", - "@marsraptor/bitset": "^1.0.0", - "@nomicfoundation/slang": "0.17.0" - } -} diff --git a/v-next/resolver/src/dependency-graph-builder.ts b/v-next/resolver/src/dependency-graph-builder.ts deleted file mode 100644 index fe4870935be..00000000000 --- a/v-next/resolver/src/dependency-graph-builder.ts +++ /dev/null @@ -1,263 +0,0 @@ -import type { Remapping } from "./types.js"; -import type { Cursor } from "@nomicfoundation/slang/cursor/index.js"; -import type { cursor } from "@nomicfoundation/slang/napi-bindings/generated/index.js"; - -import { assertHardhatInvariant } from "@ignored/hardhat-vnext-errors"; -import BitSet from "@marsraptor/bitset"; -import { NodeType } from "@nomicfoundation/slang/cst/index.js"; -import { - NonterminalKind, - TerminalKind, -} from "@nomicfoundation/slang/kinds/index.js"; -import { Language } from "@nomicfoundation/slang/language/index.js"; -import { Query } from "@nomicfoundation/slang/query/index.js"; - -// Maybe all these top level elements should be in the Project instance, to avoid startup cost? - -const supportedVersions = Language.supportedVersions(); -const mostRecentVersion = supportedVersions[supportedVersions.length - 1]; -const language = new Language(mostRecentVersion); - -const importQuery = `( - [PathImport @path path: [_]] - | [NamedImport @path path: [_]] - | [ImportDeconstruction @path path: [_]] - )`; -const pragmaQuery = `[VersionPragma [VersionExpressionSets (@versionExpression [VersionExpression])+]]`; -const queries = [importQuery, pragmaQuery].map(Query.parse); - -type SourceName = string; -type Version = string; // TODO: find something better, from semver most likely - -export class ProjectDefinition { - constructor( - public readonly roots: SourceName[], - public readonly remappings: Remapping[], - public readonly allowableVersions: Version[] = supportedVersions, // ... but if this is lazy then we can't use it in the constructor - ) {} -} - -export interface Root { - dependencies: Set; - // undefined if we couldn't determine the best version - bestVersion?: Version; -} - -interface Source { - dependencies: Set; - dependents: Set; - compatibleVersions: BitSet.default; -} - -export abstract class ProjectModel { - #definition: ProjectDefinition; - - readonly #roots = new Map(); - readonly #sources = new Map(); - - constructor(definition: ProjectDefinition) { - this.#definition = definition; - } - - public updateDefinition(definition: ProjectDefinition): void { - this.#definition = definition; - // TODO: do minimum invalidation - this.#roots.clear(); - this.#sources.clear(); - } - - public sourceDidChange(_sourceName: SourceName): void { - // TODO: do minimum invalidation - this.#roots.clear(); - this.#sources.clear(); - } - - public getRoot(rootSourceName: SourceName): Root { - if (!this.#roots.has(rootSourceName)) { - const unvisitedSourceNames = new Array(); - - const ensureSourceNameIsProcessed = (sourceName: SourceName) => { - if (!this.#sources.has(sourceName)) { - this.#sources.set(sourceName, { - dependencies: new Set(), - dependents: new Set(), - compatibleVersions: new BitSet.default().flip(), - }); - unvisitedSourceNames.push(sourceName); - } - }; - - { - // Add the root and it's dependencies to the graph of sources - - ensureSourceNameIsProcessed(rootSourceName); - - let sourceName; - while ((sourceName = unvisitedSourceNames.pop()) !== undefined) { - const source = this.#sources.get(sourceName); - assertHardhatInvariant( - source !== undefined, - "We have already added this source to the graph", - ); - - const contents = this.getSourceContent(sourceName); - const parseOutput = language.parse( - NonterminalKind.SourceUnit, - contents, - ); - const matches = parseOutput.createTreeCursor().query(queries); - - let match; - while ((match = matches.next()) !== null) { - if (match.queryNumber === 0) { - const importSourceName = this.resolveImport( - sourceName, - match.captures.path[0].node.toString(), - ); - // TODO: what if the import doesn't exist? - source.dependencies.add(importSourceName); - ensureSourceNameIsProcessed(importSourceName); - } else { - // VersionExpressionSets are the disjunction of VersionExpression(s) - - // Filter out any parse errors - const compatibleVersions = match.captures.versionExpression - .map(bitsetFromVersionExpression) - .filter((v) => v !== undefined); - - // No point adding a constraint that was nothing but parse errors - if (compatibleVersions.length !== 0) { - source.compatibleVersions = source.compatibleVersions.and( - compatibleVersions.reduce((a, b) => a.or(b)), - ); - } - } - } - } - } - - { - // Compute the transitive dependencies and version constraints of the root - - const dependencies = new Set(); - const compatibleVersions = new BitSet.default( - supportedVersions.length, - ).flip(); - - const visit = (sourceName: SourceName) => { - const source = this.#sources.get(sourceName); - assertHardhatInvariant( - source !== undefined, - "We have already added this source to the graph", - ); - for (const dependency of source.dependencies) { - if (!dependencies.has(dependency)) { - dependencies.add(dependency); - visit(dependency); - } - compatibleVersions.and(source.compatibleVersions); - } - }; - - visit(rootSourceName); - - // Determine the best version from the allowable versions that satisfies the transitive constraints - - let bestVersion; - for (let i = supportedVersions.length - 1; i >= 0; i--) { - if (compatibleVersions.get(i) === 1) { - const candidateVersion = supportedVersions[i]; - if (this.#definition.allowableVersions.includes(candidateVersion)) { - bestVersion = candidateVersion; - break; - } - } - } - - // if bestVersion is undefined, the versions constraints are unsatisfiable - - this.#roots.set(rootSourceName, { dependencies, bestVersion }); - } - } - - const root = this.#roots.get(rootSourceName); - assertHardhatInvariant( - root !== undefined, - "We have already added this root to the set of roots", - ); - return root; - } - - public abstract getSourceContent(_sourceName: SourceName): string; - public abstract resolveImport( - _context: SourceName, - _importPath: string, - ): SourceName; -} - -const versionRangeQuery = `[VersionRange [@start start: [VersionLiteral] @end end: [VersionLiteral]]]`; -const versionTermQuery = `[VersionTerm [operator: [VersionOperator @operator [_]] @literal literal: [VersionLiteral]]]`; -const versionExpressionQueries = [versionRangeQuery, versionTermQuery].map( - Query.parse, -); - -// Parse error => undefined -function bitsetFromVersionExpression(expr: Cursor): BitSet.default | undefined { - const matches = expr.spawn().query(versionExpressionQueries); - const match = matches.next(); - if (match === null) return undefined; - - if (match.queryNumber === 0) { - // VersionRange - - const start = versionIndexFromLiteral(match.captures.start[0]); - if (start === undefined) return undefined; - - const end = versionIndexFromLiteral(match.captures.end[0]); - if (end === undefined) return undefined; - - // TODO: compute bitset - } else { - // VersionTerm - - const literal = versionIndexFromLiteral(match.captures.literal[0]); - if (literal === undefined) return undefined; - - const operator = match.captures.operator[0].node(); - // TODO: use assertion functions from v1 api - assertHardhatInvariant( - operator.type === NodeType.Terminal, - "Expected operator to be a terminal", - ); - - // TODO: compute bitset - // TODO: Invalid operator applications i.e. "< 0.4.11" should be caught by the parser - switch (operator.kind) { - case TerminalKind.Caret: - break; - case TerminalKind.Tilde: - break; - case TerminalKind.Equal: - break; - case TerminalKind.LessThan: - break; - case TerminalKind.GreaterThan: - break; - case TerminalKind.LessThanEqual: - break; - case TerminalKind.GreaterThanEqual: - break; - default: - assertHardhatInvariant( - false, - `Unexpected operator ${operator.toJSON()}`, - ); - } - } -} - -// Parse error, or invalid version => undefined -// TODO: Invalid versions should be caught by the parser -function versionIndexFromLiteral(_literal: cursor.Cursor): number | undefined { - throw new Error("Function not implemented."); -} diff --git a/v-next/resolver/src/dependency-resolver.ts b/v-next/resolver/src/dependency-resolver.ts deleted file mode 100644 index 25521a8ba5b..00000000000 --- a/v-next/resolver/src/dependency-resolver.ts +++ /dev/null @@ -1,1182 +0,0 @@ -import type { - NpmPackageResolvedFile, - ProjectResolvedFile, - Remapping, - ResolvedFile, - ResolvedNpmPackage, - Resolver, -} from "./types.js"; - -import path from "node:path"; - -import { - HardhatError, - assertHardhatInvariant, -} from "@ignored/hardhat-vnext-errors"; -import { ensureError } from "@ignored/hardhat-vnext-utils/error"; -import { - FileNotFoundError, - exists, - getFileTrueCase, - getRealPath, - readJsonFile, - readUtf8File, -} from "@ignored/hardhat-vnext-utils/fs"; -import { ResolutionError, resolve } from "@ignored/hardhat-vnext-utils/resolve"; - -import { - applyValidRemapping, - parseRemappingString, - selectBestRemapping, -} from "./remappings.js"; -import { ResolvedFileType } from "./types.js"; - -// Things to note: -// - This resolver assumes that the root of the project is the folder with the -// closest package.json to the config file. -// - Each file system file is resolved to a single ResolvedFile, with a unique -// source name. -// - Files within the project have their relative path as their source name. -// - Files within npm packages have source names that start with `npm/` and -// contain the package name and version. e.g. `npm/package@1.2.3/path.sol`. -// - Files within npm packages that are part of a monorepo are resolved like -// npm pacakges, but with the version `local`. -// - This resolver does not support `package.json#exports`. -// - This resolver fails if an import has a casing different from that of the -// file system. -// - We do not allow users to remap the imports present in files within npm -// packages, by forbidding user remappings with context and starting with -// `npm/`. -// - We do allow users to remap imports of non-npm files, including remmapping -// them into file within npm packages. -// - Every import in an npm file is either relative or remapped by a remapping -// generated by the resolver. -// - A direct import (i.e. not relative) is considered to be local within the -// the project/package if it is a bare file name (not in a directory), or if -// the first directory exists in the project/package. -// - The direct import "hardhat/console.sol" is a special case and it is never -// considered to be local. And we only remap `hardhat/console.sol`. -// - Local imports within the project may be remapped by user remappings, but -// not by the resolver. -// - Imports into npm packages are always remapped, if not by the user, by the -// resolver. -// - Direct local improts within npm package are always remapped by the -// resolver. - -// TODO: Windows and source names with \ instead of / -// TODO: Forbid local direct imports to `npm/...`, and local fiels in `npm/` - -interface UserRemapping { - rawFormat: string; - context: string; - prefix: string; - target: string; - targetNpmPackage?: ResolvedNpmPackage; -} - -const PROJECT_ROOT_SOURCE_NAME_SENTINEL: unique symbol = Symbol(); - -export class ResolverImplementation implements Resolver { - readonly #projectRoot: string; - readonly #workingDirectory: string; - readonly #userRemappings: UserRemapping[]; - - // A map of all the npm dependencies used in the project and its dependencies - readonly #dependencyMaps: Map< - string | typeof PROJECT_ROOT_SOURCE_NAME_SENTINEL, // The package's root sourceName - Map< - string, // The package that is being imported, as the package name in the import - ResolvedNpmPackage | typeof PROJECT_ROOT_SOURCE_NAME_SENTINEL - > - > = new Map(); - - // A map of all the prefixes that a package may need to avoid being affected - // by user remappings. - readonly #localPrefixesByPackage: Map> = new Map(); - - // A cache from absolute path to resolved file - readonly #cacheBySourceName: Map = new Map(); - - public static async create( - projectRoot: string, - userRemappingStrings: string[], - workingDirectory?: string, - ): Promise { - const userRemappings = await Promise.all( - userRemappingStrings.map((remappingString) => - validateAndResolveUserRemapping(projectRoot, remappingString), - ), - ); - - return new ResolverImplementation( - workingDirectory !== undefined - ? await getRealPath(workingDirectory) - : process.cwd(), - projectRoot, - userRemappings, - ); - } - - private constructor( - workingDirectory: string, - projectRoot: string, - userRemappings: UserRemapping[], - ) { - this.#projectRoot = projectRoot; - this.#workingDirectory = workingDirectory; - this.#userRemappings = userRemappings; - this.#dependencyMaps.set(PROJECT_ROOT_SOURCE_NAME_SENTINEL, new Map()); - } - - public async resolveProjectFile( - absoluteFilePath: string, - ): Promise { - if (!absoluteFilePath.startsWith(this.#projectRoot)) { - throw new HardhatError( - HardhatError.ERRORS.SOLIDITY.RESOLVING_INCORRECT_FILE_AS_PROJECT_FILE, - { - file: this.#userFriendlyPath(absoluteFilePath), - }, - ); - } - - const relativeFilePath = path.relative(this.#projectRoot, absoluteFilePath); - - // Contrary to imports, it's fine if we don't have the right casing here. - // - // The cache may be less effetive if the casing was wrong, but as most of - // the time these absolute paths are read from the file system, they'd have - // the right casing in general. - let sourceName = relativeFilePath; - const cached = this.#cacheBySourceName.get(sourceName); - if (cached !== undefined) { - /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- - The cache is type-unsafe, but we are sure this is a ProjectResolvedFile */ - return cached as ProjectResolvedFile; - } - - let trueCasePath: string; - try { - trueCasePath = await getFileTrueCase(this.#projectRoot, relativeFilePath); - } catch (error) { - ensureError(error, FileNotFoundError); - - throw new HardhatError( - HardhatError.ERRORS.SOLIDITY.RESOLVING_NONEXISTENT_PROJECT_FILE, - { file: this.#userFriendlyPath(absoluteFilePath) }, - error, - ); - } - - sourceName = trueCasePath; - - // Maybe it was cached with the right casing - const cachedWithTheRightCasing = this.#cacheBySourceName.get(sourceName); - if (cachedWithTheRightCasing !== undefined) { - /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions - -- If it was, it's a ProjectResolvedFile */ - return cachedWithTheRightCasing as ProjectResolvedFile; - } - - const pathWithTheRightCasing = path.join(this.#projectRoot, trueCasePath); - - const resolvedFile: ProjectResolvedFile = { - type: ResolvedFileType.PROJECT_FILE, - sourceName, - path: pathWithTheRightCasing, - content: await readUtf8File(pathWithTheRightCasing), - }; - - this.#cacheBySourceName.set(sourceName, resolvedFile); - - return resolvedFile; - } - - public async resolveImport( - from: ResolvedFile, - importPath: string, - ): Promise { - let directImport = importPath; - - if (importPath.startsWith("./") || importPath.startsWith("../")) { - directImport = path.join(path.dirname(from.sourceName), importPath); - - if (from.type === ResolvedFileType.NPM_PACKGE_FILE) { - if (!directImport.startsWith(from.package.rootSourceName)) { - throw new Error( - `Invalid import ${importPath} from ${this.#userFriendlyPath(from.path)}, trying to import outside of the package`, - ); - } - } else { - if (directImport.startsWith("../")) { - throw new Error( - `Invalid import ${importPath} from ${this.#userFriendlyPath(from.path)}, trying to import outside of the project`, - ); - } - } - } - - switch (from.type) { - case ResolvedFileType.PROJECT_FILE: - return this.#resolveImportFromProjectFile({ - from, - importPath, - directImport, - }); - - case ResolvedFileType.NPM_PACKGE_FILE: - return this.#resolveImportFromNpmPackageFile({ - from, - importPath, - directImport, - }); - } - } - - public getRemappings(): Remapping[] { - const userRemappings = this.#userRemappings.map((remapping) => ({ - context: remapping.context, - prefix: remapping.prefix, - target: remapping.target, - })); - - const remappings: Remapping[] = []; - - for (const [ - fromPackageSourceName, - dependenciesMap, - ] of this.#dependencyMaps.entries()) { - let context: string; - - if (fromPackageSourceName === PROJECT_ROOT_SOURCE_NAME_SENTINEL) { - context = ""; - } else { - context = fromPackageSourceName; - } - - for (const [importedPackage, dependency] of dependenciesMap.entries()) { - // As `hardhat/console.sol` is resolved through npm, even if the - // `hardhat/` folder exists in the root of the package/project, we - // only remap that file. - // We should revisit this if we exported more solidity files in the - // hardhat package in the future. - if ( - dependency !== PROJECT_ROOT_SOURCE_NAME_SENTINEL && - dependency.name === "hardhat" - ) { - const prefix = importedPackage + "/console.sol"; - const target = dependency.rootSourceName + "console.sol"; - - remappings.push({ context, prefix, target }); - } else { - const prefix = importedPackage + "/"; - - const target = - dependency === PROJECT_ROOT_SOURCE_NAME_SENTINEL - ? "" - : dependency.rootSourceName; - - remappings.push({ context, prefix, target }); - } - } - } - - // TODO: Always order this in a consistent way - for (const [packageSourceName, prefixes] of this.#localPrefixesByPackage) { - for (const prefix of prefixes) { - remappings.push({ - context: packageSourceName, - prefix, - target: packageSourceName + prefix, - }); - } - } - - // We sort the remappings acording to the remappings selection rules, plus - // the targets, which shouldn't be needed. - remappings - .sort((a, b) => a.target.localeCompare(b.target)) - .sort((a, b) => a.target.length - b.target.length) - .sort((a, b) => a.prefix.localeCompare(b.prefix)) - .sort((a, b) => a.prefix.length - b.prefix.length) - .sort((a, b) => a.context.localeCompare(b.context)) - .sort((a, b) => a.context.length - b.context.length); - - return [...userRemappings, ...remappings]; - } - - // >>>>>>>>>> BEGIN SECTION: Import resolution selection - // - // The private methods in this section are in charge of selecting which import - // resolution technique to use, but they don't create any ResolvedFile. - // - // These techniques are: - // 1. Resolving an import to a project file - // 2. Resolving an import to an npm package remapped by the user - // 3. Resolving an import from an npm package to one of its own files with a - // relative import - // 4. Resolving an import from an npm package to one of its own files with a - // direct import — This case is different from 3, as without especial care - // it could be affected by one of the user remappings. - // 5. Resolving an import to a different npm package using our own remmapings - - /** - * Resolves an import from a project file. - * - * This method applies the user remappings, if necessary, and uses the - * appropriate resolution technique. - * - * @param from The file from which the import is being resolved. - * @param importPath The import path, as written in the source code. - * @param directImport The direct import path, after resolving relative paths, - * but before applying any remapping. - */ - async #resolveImportFromProjectFile({ - from, - importPath, - directImport, - }: { - from: ProjectResolvedFile; - directImport: string; - importPath: string; - }): Promise { - const bestUserRemapping = selectBestRemapping( - from.sourceName, - directImport, - this.#userRemappings, - ); - - if (bestUserRemapping !== undefined) { - const remappedDirectImport = applyValidRemapping( - directImport, - bestUserRemapping, - ); - - // Special case, where a user remapping's target is an npm pacakge - if (bestUserRemapping.targetNpmPackage !== undefined) { - // This weird syntax is because TS doesn't realize that - // bestUserRemapping is Required here - const remapping: Required = { - ...bestUserRemapping, - targetNpmPackage: bestUserRemapping.targetNpmPackage, - }; - - return this.#resolveImportToNpmPackageRemappedByUser({ - from, - importPath, - directImport: remappedDirectImport, - remapping, - }); - } - - if ( - !(await this.#isDirectImportLocal( - this.#projectRoot, - remappedDirectImport, - )) - ) { - throw new Error( - `Applying the remapping "${bestUserRemapping.rawFormat}" to the import ${importPath} from ${this.#userFriendlyPath(from.path)} results in an invalid import ${remappedDirectImport}, as it's not a local files. If you are trying to remap into an npm module use the npm/ syntax instead.`, - ); - } - - return this.#resolveImportToProjectFile({ - from, - importPath, - pathWithinTheProject: remappedDirectImport, - }); - } - - if (await this.#isDirectImportLocal(this.#projectRoot, directImport)) { - return this.#resolveImportToProjectFile({ - from, - importPath, - pathWithinTheProject: directImport, - }); - } - - return this.#resolveImportThroughNpm({ from, importPath, directImport }); - } - - /** - * Resolves an import from an npm file. - * - * This method does not apply any remapping that may be present in the npm - * package. - * - * @param from The file from which the import is being resolved. - * @param importPath The import path, as written in the source code. - * @param directImport The direct import path, after resolving relative paths, - * but without applying any remapping. - */ - async #resolveImportFromNpmPackageFile({ - from, - importPath, - directImport, - }: { - from: NpmPackageResolvedFile; - directImport: string; - importPath: string; - }): Promise { - // If we wanted to apply its own remappings, this would be the place. - // Initially we won't support it. - - // - if (directImport.startsWith(from.package.rootSourceName)) { - return this.#resolveRelativeImportFromNpmPackage({ - from, - importPath, - directImport, - }); - } - - // This was already a direct import, and may be to the same package. - // As we allow this imports in the local project files, we should also allow - // them on npm packages. If we don't projects won't be easily distributable - // through npm, even if they don't use remappings. - if (await this.#isDirectImportLocal(from.package.rootPath, directImport)) { - const resolvedFile = await this.#resolveLocalImportFromNpmPackage({ - from, - importPath, - directImport, - }); - - if (!this.#localPrefixesByPackage.has(from.package.rootSourceName)) { - this.#localPrefixesByPackage.set( - from.package.rootSourceName, - new Set(), - ); - } - - const prefixesNeededByPackage = this.#localPrefixesByPackage.get( - from.package.rootSourceName, - ); - - assertHardhatInvariant( - prefixesNeededByPackage !== undefined, - "We just set this value to a new Set", - ); - - prefixesNeededByPackage.add( - this.#getDirectImportLocalPrefix(directImport), - ); - - return resolvedFile; - } - - return this.#resolveImportThroughNpm({ from, importPath, directImport }); - } - - /** - * This method resolves an import that has to go through the npm resolution - * process and selects the appropriate technique to resolve it. - * - * This method does not apply nor define any remapping, but it populates the - * `#dependencyMaps` with dependencies that each package uses, so that we can - * create all the necessary remappings at the end of the resolution process. - * - * @param from The file from which the import is being resolved. - * @param importPath The import path, as written in the source code. - * @param directImport The direct import path, after resolving relative paths, - * but without applying any remapping. - */ - async #resolveImportThroughNpm({ - from, - importPath, - directImport, - }: { - from: ResolvedFile; - importPath: string; - directImport: string; - }): Promise { - const parsedDirectImport = this.#parseNpmDirectImport(directImport); - - if (parsedDirectImport === undefined) { - throw new Error(`Invalid npm import ${directImport}`); - } - - const dependencyMapsKey = - from.type === ResolvedFileType.PROJECT_FILE - ? PROJECT_ROOT_SOURCE_NAME_SENTINEL - : from.package.rootSourceName; - - if (!this.#dependencyMaps.has(dependencyMapsKey)) { - this.#dependencyMaps.set(dependencyMapsKey, new Map()); - } - - const dependenciesMap = this.#dependencyMaps.get(dependencyMapsKey); - - assertHardhatInvariant( - dependenciesMap !== undefined, - "We set the dependency map right above", - ); - - if (!dependenciesMap.has(parsedDirectImport.package)) { - let newDependency: - | ResolvedNpmPackage - | typeof PROJECT_ROOT_SOURCE_NAME_SENTINEL; - - const baseResolutionDirectory = - from.type === ResolvedFileType.PROJECT_FILE - ? this.#projectRoot - : from.package.rootPath; - - const packageJsonResolution = resolve( - parsedDirectImport.package + "/package.json", - baseResolutionDirectory, - ); - - if (packageJsonResolution.success === false) { - if (packageJsonResolution.error === ResolutionError.MODULE_NOT_FOUND) { - throw new HardhatError( - HardhatError.ERRORS.SOLIDITY.IMPORTED_NPM_DEPENDENCY_NOT_INSTALLED, - { - from: this.#userFriendlyPath(from.path), - importPath, - }, - ); - } - - throw new HardhatError( - HardhatError.ERRORS.SOLIDITY.IMPORTED_NPM_DEPENDENCY_THAT_USES_EXPORTS, - { from: this.#userFriendlyPath(from.path), importPath }, - ); - } - - const packageJsonPath = packageJsonResolution.absolutePath; - - const packageJson = await readJsonFile<{ name: string; version: string }>( - packageJsonPath, - ); - - if (isPackageJsonFromProject(packageJsonPath, this.#projectRoot)) { - newDependency = PROJECT_ROOT_SOURCE_NAME_SENTINEL; - } else { - const name = packageJson.name; - const version = isPackageJsonFromMonorepo( - packageJsonPath, - this.#projectRoot, - ) - ? "local" - : packageJson.version; - - const npmPackage: ResolvedNpmPackage = { - name, - version, - rootPath: path.dirname(packageJsonPath), - rootSourceName: npmPackageToRootSourceName(name, version), - }; - - newDependency = npmPackage; - } - - dependenciesMap.set(parsedDirectImport.package, newDependency); - } - - const dependency = dependenciesMap.get(parsedDirectImport.package); - assertHardhatInvariant( - dependency !== undefined, - "We set the dependency right above", - ); - - if (dependency === PROJECT_ROOT_SOURCE_NAME_SENTINEL) { - return this.#resolveImportToProjectFile({ - from, - importPath, - // If we import a file through npm and end up in the Hardhat project, - // we are going to remap the package name to "", so that the path - // section of the parsed direct is in fact the directImport in the - // context of the package. - pathWithinTheProject: parsedDirectImport.path, - }); - } - - return this.#resolveImportToNpmPackage({ - from, - importPath, - importedPackage: dependency, - pathWithinThePackage: parsedDirectImport.path, - }); - } - - // >>>>>>>>>> END SECTION: Import resolution selection - - // >>>>>>>>>> BEGIN SECTION: Import resolution techniques - // - // The private methods in this section implement the different import - // import resolution techniques, which have been explained in the previous - // section. - - /** - * This method implements the import resolution technique number 1: Importing - * a file that is within the project. Note that this method applies both to - * imports from project files as well as imports from npm packages that may - * have the project as a dependency. - * - * @param from The file from which the import is being resolved. - * @param importPath The import path, as written in the source code. - * @param pathWithinTheProject The path within the project to import, after - * normalizing relative paths, applying user remappings and/or stripping the - * npm package name. - */ - async #resolveImportToProjectFile({ - from, - importPath, - pathWithinTheProject, - }: { - from: ResolvedFile; - importPath: string; - pathWithinTheProject: string; - }): Promise { - const sourceName = pathWithinTheProject; - const cached = this.#cacheBySourceName.get(sourceName); - if (cached !== undefined) { - /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- - The cache is type-unsafe, but we are sure this is a ProjectResolvedFile */ - return cached as ProjectResolvedFile; - } - - // This is a project file, so if it was imported from a local file, this - // is the direct import, without any remapping or necessary consideration. - // If this was imported from an npm package, we are remapping the package - // name to "", so that the direct import is the same as the relative path. - const relativePath = pathWithinTheProject; - await this.#validateExistanceAndCasingOfImport({ - from, - importPath, - relativePathToValidate: relativePath, - absolutePathToValidateFrom: this.#projectRoot, - }); - - const filePath = path.join(this.#projectRoot, relativePath); - - const resolvedFile: ProjectResolvedFile = { - type: ResolvedFileType.PROJECT_FILE, - sourceName, - path: filePath, - content: await readUtf8File(filePath), - }; - - this.#cacheBySourceName.set(sourceName, resolvedFile); - - return resolvedFile; - } - - /** - * This method implements the import resolution technique number 2: A project - * file has an import that should be resolved to a file in an npm package due - * to a user remapping. - * - * @param from The file from which the import is being resolved. - * @param importPath The import path, as written in the source code. - * @param directImport The direct import path, after resolving relative paths, - * and applying the user remapping. - * @param remapping The remapping that was applied. - */ - async #resolveImportToNpmPackageRemappedByUser({ - from, - importPath, - directImport, - remapping, - }: { - from: ProjectResolvedFile; - importPath: string; - directImport: string; - remapping: Required; - }): Promise { - const sourceName = directImport; - const cached = this.#cacheBySourceName.get(sourceName); - if (cached !== undefined) { - /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- - The cache is type-unsafe, but we are sure this is a NpmPackageResolvedFile */ - return cached as NpmPackageResolvedFile; - } - - const relativeFilePath = path.relative( - npmPackageToRootSourceName( - remapping.targetNpmPackage.name, - remapping.targetNpmPackage.version, - ), - directImport, - ); - - // We don't add the dependency to `this.#dependencyMaps` because we - // don't need a new remapping for this package, as it's already - // remapped by the user. - - await this.#validateExistanceAndCasingOfImport({ - from, - importPath, - relativePathToValidate: relativeFilePath, - absolutePathToValidateFrom: remapping.targetNpmPackage.rootPath, - }); - - const filePath = path.join( - remapping.targetNpmPackage.rootPath, - relativeFilePath, - ); - - const resolvedFile: NpmPackageResolvedFile = { - type: ResolvedFileType.NPM_PACKGE_FILE, - sourceName, - path: filePath, - content: await readUtf8File(filePath), - package: remapping.targetNpmPackage, - }; - - this.#cacheBySourceName.set(sourceName, resolvedFile); - - return resolvedFile; - } - - /** - * This method implements the import resolution technique number 3: A file - * from an npm package is importing another file from the same package with a - * relative import. - * - * @param from The file from which the import is being resolved. - * @param importPath The import path, as written in the source code. - * @param directImport The direct import path, after resolving relative paths. - * It must start with the package's root source name. - */ - async #resolveRelativeImportFromNpmPackage({ - from, - importPath, - directImport, - }: { - from: NpmPackageResolvedFile; - directImport: string; - importPath: string; - }): Promise { - const sourceName = directImport; - const cached = this.#cacheBySourceName.get(sourceName); - if (cached !== undefined) { - /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- - The cache is type-unsafe, but we are sure this is a NpmPackageResolvedFile */ - return cached as NpmPackageResolvedFile; - } - - const relativePath = path.relative( - from.package.rootSourceName, - directImport, - ); - - await this.#validateExistanceAndCasingOfImport({ - from, - importPath, - relativePathToValidate: relativePath, - absolutePathToValidateFrom: from.package.rootPath, - }); - - const filePath = path.join(from.package.rootPath, relativePath); - - const resolvedFile: NpmPackageResolvedFile = { - type: ResolvedFileType.NPM_PACKGE_FILE, - sourceName, - path: filePath, - content: await readUtf8File(filePath), - package: from.package, - }; - - this.#cacheBySourceName.set(sourceName, resolvedFile); - return resolvedFile; - } - - /** - * This method implements the import resolution technique number 4: A file - * from an npm package is importing another file from the same package with a - * direct import. - * - * @param from The file from which the import is being resolved. - * @param importPath The import path, as written in the source code. - * @param directImport The direct import path, after resolving relative paths. - * The direct import must be considered local within the package, according to - * the rules of the `#isDirectImportLocal` method. - */ - async #resolveLocalImportFromNpmPackage({ - from, - importPath, - directImport, - }: { - from: NpmPackageResolvedFile; - directImport: string; - importPath: string; - }): Promise { - const sourceName = from.package.rootSourceName + directImport; - const cached = this.#cacheBySourceName.get(sourceName); - if (cached !== undefined) { - /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- - The cache is type-unsafe, but we are sure this is a NpmPackageResolvedFile */ - return cached as NpmPackageResolvedFile; - } - - await this.#validateExistanceAndCasingOfImport({ - from, - importPath, - relativePathToValidate: directImport, - absolutePathToValidateFrom: from.package.rootPath, - }); - - const filePath = path.join(from.package.rootPath, directImport); - - const resolvedFile: NpmPackageResolvedFile = { - type: ResolvedFileType.NPM_PACKGE_FILE, - sourceName, - path: filePath, - content: await readUtf8File(filePath), - package: from.package, - }; - - this.#cacheBySourceName.set(sourceName, resolvedFile); - return resolvedFile; - } - - /** - * This method implements the import resolution technique number 5: A file, - * within the project or from an npm pacakge, is importing a file from a - * different npm package. - * - * @param from The file from which the import is being resolved. - * @param importPath The import path, as written in the source code. - * @param importedPackage The NpmPackage that is being imported. - * @param pathWithinThePackage The path to the file to import, within the - * package. That means, after parsing the direct import, and stripping the - * package part. - */ - async #resolveImportToNpmPackage({ - from, - importPath, - importedPackage, - pathWithinThePackage, - }: { - from: ResolvedFile; - importPath: string; - importedPackage: ResolvedNpmPackage; - pathWithinThePackage: string; - }): Promise { - const sourceName = importedPackage.rootSourceName + pathWithinThePackage; - const cached = this.#cacheBySourceName.get(sourceName); - if (cached !== undefined) { - /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- - The cache is type-unsafe, but we are sure this is a NpmPackageResolvedFile */ - return cached as NpmPackageResolvedFile; - } - - await this.#validateExistanceAndCasingOfImport({ - from, - importPath, - relativePathToValidate: pathWithinThePackage, - absolutePathToValidateFrom: importedPackage.rootPath, - }); - - const filePath = path.join(importedPackage.rootPath, pathWithinThePackage); - - const resolvedFile: NpmPackageResolvedFile = { - type: ResolvedFileType.NPM_PACKGE_FILE, - sourceName, - path: filePath, - content: await readUtf8File(filePath), - package: importedPackage, - }; - - this.#cacheBySourceName.set(sourceName, resolvedFile); - - return resolvedFile; - } - - // >>>>>>>>>> END SECTION: Import resolution techniques - - /** - * This method returns true if a direct import should be considered an import - * to a local file when evaluated in the context of the Hardhat project. - */ - async #isDirectImportLocal( - projectOrPackageRoot: string, - directImport: string, - ): Promise { - if (directImport === "hardhat/console.sol") { - return false; - } - - const slash = directImport.indexOf("/"); - - // If it's a file in the root directory - if (slash === -1) { - return true; - } - - const firstDirectory = directImport.substring(0, slash); - - // TODO: Cache this - return exists(path.join(projectOrPackageRoot, firstDirectory)); - } - - /** - * Returns the prefix that is used by #isDirectImportLocal to determine if a - * direct import is local. - * - * NOTE: This method does not support `hardhat/console.sol`. - */ - #getDirectImportLocalPrefix(directImport: string): string { - const slash = directImport.indexOf("/"); - - // If it's a file in the root directory - if (slash === -1) { - return directImport; - } - - const firstDirectory = directImport.substring(0, slash + 1); - - return firstDirectory; - } - - /** - * This is an utility method that validates the existance and casing of an - * imported file as part of the different resolution techniques. - * - * `from` and `importPath` are used to provide a user-friendly error message, - * but the actual validation is done using `relativePathToValidate` and - * `absolutePathToValidateFrom`. - * - * @param from The file with the import. - * @param importPath The import path, as written in the source code. - * @param relativePathToValidate The relative path to validate its existance. - * @param absolutePathToValidateFrom The absolute path from in which the - * relative path is. - */ - async #validateExistanceAndCasingOfImport({ - from, - importPath, - relativePathToValidate, - absolutePathToValidateFrom, - }: { - from: ResolvedFile; - importPath: string; - relativePathToValidate: string; - absolutePathToValidateFrom: string; - }) { - let trueCasePath: string; - try { - trueCasePath = await getFileTrueCase( - absolutePathToValidateFrom, - relativePathToValidate, - ); - } catch (error) { - ensureError(error, FileNotFoundError); - - throw new HardhatError( - HardhatError.ERRORS.SOLIDITY.IMPORTED_FILE_DOESNT_EXIST, - { importPath, from: this.#userFriendlyPath(from.path) }, - error, - ); - } - - if (relativePathToValidate !== trueCasePath) { - throw new HardhatError( - HardhatError.ERRORS.SOLIDITY.IMPORTED_FILE_WITH_ICORRECT_CASING, - { - importPath, - from: this.#userFriendlyPath(from.path), - correctCasing: trueCasePath, - }, - ); - } - } - - /** - * Normalizes a path to be user-friendly, by making it relative to the working - * directory if it's within it. - */ - #userFriendlyPath(from: string): string { - if (from.startsWith(this.#workingDirectory)) { - return path.relative(this.#workingDirectory, from); - } - - return from; - } - - /** - * Parses a direct import as if it were an npm import, returning `undefined` - * if the format is invalid. - */ - #parseNpmDirectImport(directImport: string): - | { - package: string; - path: string; - } - | undefined { - const directImportPattern = - /^(?(?:@[a-z0-9-~._]+\/)?[a-z0-9-~][a-z0-9-~._]*)\/(?.*)$/; - - const match = directImportPattern.exec(directImport); - - if (match === null) { - return undefined; - } - - assertHardhatInvariant( - match.groups !== undefined, - "Groups should be defined because they are part of the pattern", - ); - - return { package: match.groups.package, path: match.groups.path }; - } -} - -async function validateAndResolveUserRemapping( - projectRoot: string, - remappingString: string, -): Promise { - const remapping = parseRemappingString(remappingString); - - if (remapping.context.startsWith("npm/")) { - throw new HardhatError( - HardhatError.ERRORS.SOLIDITY.USER_REMAPPING_WITH_NPM_CONTEXT, - { remapping: remappingString }, - ); - } - - if (!remapping.target.startsWith("npm/")) { - return { ...remapping, rawFormat: remappingString }; - } - - const parsed = parseNpmRemappingTarget(remapping.target); - - if (parsed === undefined) { - throw new HardhatError( - HardhatError.ERRORS.SOLIDITY.REMAPPING_WITH_INVALID_SYNTAX, - { remapping: remappingString }, - ); - } - - const { packageName, packageVersion } = parsed; - - const dependencyPackageJsonResolution = resolve( - `${packageName}/package.json`, - projectRoot, - ); - - if (dependencyPackageJsonResolution.success === false) { - if ( - dependencyPackageJsonResolution.error === ResolutionError.MODULE_NOT_FOUND - ) { - throw new HardhatError( - HardhatError.ERRORS.SOLIDITY.REMAPPING_TO_UNINSTALLED_PACKAGE, - { remapping: remappingString, package: packageName }, - ); - } - - throw new HardhatError( - HardhatError.ERRORS.SOLIDITY.REMAPPING_TO_PACKAGE_USING_EXPORTS, - { remapping: remappingString, package: packageName }, - ); - } - - const dependencyPackageJsonPath = - dependencyPackageJsonResolution.absolutePath; - - if (isPackageJsonFromMonorepo(dependencyPackageJsonPath, projectRoot)) { - if (packageVersion !== "local") { - throw new HardhatError( - HardhatError.ERRORS.SOLIDITY.REMAPPING_NPM_PACKAGE_AS_MONOREPO, - { - remapping: remappingString, - pacakge: packageName, - version: packageVersion, - }, - ); - } - } - - if (isPackageJsonFromProject(dependencyPackageJsonPath, projectRoot)) { - throw new HardhatError( - HardhatError.ERRORS.SOLIDITY.REMAPPING_HARDHAT_PROJECT_AS_MONOREPO_PACKAGE, - { remapping: remappingString, package: packageName }, - ); - } - - if (isPackageJsonFromNpmPackage(dependencyPackageJsonPath)) { - const dependencyPackageJson = await readJsonFile<{ version: string }>( - dependencyPackageJsonPath, - ); - - if (dependencyPackageJson.version !== packageVersion) { - throw new HardhatError( - HardhatError.ERRORS.SOLIDITY.REMAPPING_INCORRECT_VERSION, - { - remapping: remappingString, - package: packageName, - expectedVersion: packageVersion, - actualVersion: dependencyPackageJson.version, - }, - ); - } - } - - const npmPackage: ResolvedNpmPackage = { - name: packageName, - version: packageVersion, - rootPath: path.dirname(dependencyPackageJsonPath), - rootSourceName: npmPackageToRootSourceName(packageName, packageVersion), - }; - - return { - ...remapping, - targetNpmPackage: npmPackage, - rawFormat: remappingString, - }; -} - -function parseNpmRemappingTarget(remappingTarget: string): - | { - packageName: string; - packageVersion: string; - } - | undefined { - const npmTargetPattern = - /^npm\/(?(?:@[a-z0-9-~._]+\/)?[a-z0-9-~][a-z0-9-~._]*)@(?local|\d+\.\d+\.\d+)\//; - - const match = npmTargetPattern.exec(remappingTarget); - - if (match === null) { - return undefined; - } - - assertHardhatInvariant( - match.groups !== undefined, - "Groups should be defined because they are part of the pattern", - ); - - return { - packageName: match.groups.package, - packageVersion: match.groups.version, - }; -} - -function npmPackageToRootSourceName(name: string, version: string): string { - return `npm/${name}@${version}/`; -} - -function isPackageJsonFromMonorepo( - packageJsonPath: string, - projectRoot: string, -): boolean { - return ( - !packageJsonPath.includes("node_modules") && - !packageJsonPath.startsWith(projectRoot) - ); -} - -function isPackageJsonFromProject( - packageJsonPath: string, - projectRoot: string, -): boolean { - return ( - !packageJsonPath.includes("node_modules") && - packageJsonPath.startsWith(projectRoot) - ); -} - -function isPackageJsonFromNpmPackage(packageJsonPath: string): boolean { - return packageJsonPath.includes("node_modules"); -} diff --git a/v-next/resolver/src/remappings.ts b/v-next/resolver/src/remappings.ts deleted file mode 100644 index 0599f8fc93d..00000000000 --- a/v-next/resolver/src/remappings.ts +++ /dev/null @@ -1,88 +0,0 @@ -import type { Remapping } from "./types.js"; - -export function parseRemappingString(remapping: string): Remapping { - let rest = remapping; - const colon = rest.indexOf(":"); - - let context: string; - - if (colon !== -1) { - context = rest.substring(0, colon); - rest = rest.substring(colon + 1); - } else { - context = ""; - } - - const equal = rest.indexOf("="); - if (equal === -1) { - throw new Error(`Invalid remapping: ${remapping}`); - } - - const prefix = rest.substring(0, equal); - - if (prefix === "") { - throw new Error(`Invalid remapping: ${remapping}`); - } - - const target = rest.substring(equal + 1); - - return { context, prefix, target }; -} - -export function selectBestRemapping( - fromSouceName: string, - directImport: string, - remappings: RemappingT[], -): RemappingT | undefined { - let bestRemapping: RemappingT | undefined; - - let longestContext = 0; - let longestPrefix = 0; - - for (const remapping of remappings) { - const contextLength = remapping.context.length; - - if (contextLength < longestContext) { - continue; - } - - if (!fromSouceName.startsWith(remapping.context)) { - continue; - } - - if ( - remapping.prefix.length < longestPrefix && - contextLength === longestContext - ) { - continue; - } - - if (!directImport.startsWith(remapping.prefix)) { - continue; - } - - longestContext = contextLength; - longestPrefix = remapping.prefix.length; - bestRemapping = remapping; - } - - return bestRemapping; -} - -/** - * Applies a remapping assuming that it's valid for this importPath. - */ -export function applyValidRemapping( - importPath: string, - remapping: Remapping, -): string { - return remapping.target + importPath.substring(remapping.prefix.length); -} - -export function formatRemapping(remapping: Remapping): string { - if (remapping.context === "") { - return `${remapping.prefix}=${remapping.target}`; - } - - return `${remapping.context}:${remapping.prefix}=${remapping.target}`; -} diff --git a/v-next/resolver/src/types.ts b/v-next/resolver/src/types.ts deleted file mode 100644 index f5fd48bd637..00000000000 --- a/v-next/resolver/src/types.ts +++ /dev/null @@ -1,40 +0,0 @@ -export interface Remapping { - context: string; - prefix: string; - target: string; -} - -export enum ResolvedFileType { - PROJECT_FILE = "PROJECT_FILE", - NPM_PACKGE_FILE = "NPM_PACKAGE_FILE", -} - -export interface ProjectResolvedFile { - type: ResolvedFileType.PROJECT_FILE; - sourceName: string; - path: string; - content: string; -} - -export interface ResolvedNpmPackage { - name: string; - version: string; - rootPath: string; - rootSourceName: string; -} - -export interface NpmPackageResolvedFile { - type: ResolvedFileType.NPM_PACKGE_FILE; - sourceName: string; - path: string; - content: string; - package: ResolvedNpmPackage; -} - -export type ResolvedFile = ProjectResolvedFile | NpmPackageResolvedFile; - -export interface Resolver { - resolveProjectFile(absoluteFilePath: string): Promise; - resolveImport(from: ResolvedFile, importPath: string): Promise; - getRemappings(): Remapping[]; -} diff --git a/v-next/resolver/test/dependency-resolver.ts b/v-next/resolver/test/dependency-resolver.ts deleted file mode 100644 index d6c5b009cb2..00000000000 --- a/v-next/resolver/test/dependency-resolver.ts +++ /dev/null @@ -1,906 +0,0 @@ -import assert from "node:assert/strict"; -import path from "node:path"; -import { after, before, beforeEach, describe, it } from "node:test"; - -import { HardhatError } from "@ignored/hardhat-vnext-errors"; -import { assertRejectsWithHardhatError } from "@nomicfoundation/hardhat-test-utils"; - -import { ResolverImplementation } from "../src/dependency-resolver.js"; -import { - ResolvedFileType, - type NpmPackageResolvedFile, - type ProjectResolvedFile, - type ResolvedFile, - type ResolvedNpmPackage, - type Resolver, -} from "../src/types.js"; - -const TEST_FIXTURES_ROOT = path.resolve(import.meta.dirname, "test-fixtures"); - -const FIXTURE_HARDHAT_PROJECT_ROOT = path.resolve( - TEST_FIXTURES_ROOT, - "monorepo/packages/hardhat-project", -); - -function assertResolvedProjectFile( - resolvedFile: ResolvedFile, - pathFromProjectRoot: string, -): asserts resolvedFile is ProjectResolvedFile { - assert.ok( - resolvedFile.type === ResolvedFileType.PROJECT_FILE, - `Resolved file ${resolvedFile.path} is not a project file`, - ); - assert.equal(resolvedFile.sourceName, pathFromProjectRoot); - assert.equal( - resolvedFile.path, - path.resolve(FIXTURE_HARDHAT_PROJECT_ROOT, pathFromProjectRoot), - ); - - const pathFromTestFixturesRoot = path.relative( - TEST_FIXTURES_ROOT, - resolvedFile.path, - ); - - assert.equal(resolvedFile.content, pathFromTestFixturesRoot + "\n"); -} - -function assertNpmPackageResolvedFile( - resolvedFile: ResolvedFile, - pacakge: Omit, - packagePathFromTestFixturesRoot: string, - filePathFromPackageRoot: string, -): asserts resolvedFile is NpmPackageResolvedFile { - assert.ok( - resolvedFile.type === ResolvedFileType.NPM_PACKGE_FILE, - `Resolved file ${resolvedFile.path} is not an npm file`, - ); - - const filePathFromTestFixturesRoot = path.join( - packagePathFromTestFixturesRoot, - filePathFromPackageRoot, - ); - - const packageRootPath = path.join( - TEST_FIXTURES_ROOT, - packagePathFromTestFixturesRoot, - ); - - assert.deepEqual(resolvedFile.package, { - ...pacakge, - rootPath: packageRootPath, - }); - assert.equal( - resolvedFile.sourceName, - pacakge.rootSourceName + filePathFromPackageRoot, - ); - assert.equal( - resolvedFile.path, - path.join(TEST_FIXTURES_ROOT, filePathFromTestFixturesRoot), - ); - - assert.equal(resolvedFile.content, filePathFromTestFixturesRoot + "\n"); -} - -describe("Resolver", () => { - // Some of the error messages in the resolver use a file path based on the - // CWD, so we set it for these tests - let originalCwd: string; - - before(() => { - originalCwd = process.cwd(); - process.chdir(FIXTURE_HARDHAT_PROJECT_ROOT); - }); - - after(() => { - process.chdir(originalCwd); - }); - - describe("Project files resolution", () => { - it("Should throw if the file isn't part of the project", async () => { - const resolver = await ResolverImplementation.create( - FIXTURE_HARDHAT_PROJECT_ROOT, - [], - ); - - let file = "foo.sol"; - await assertRejectsWithHardhatError( - () => resolver.resolveProjectFile(file), - HardhatError.ERRORS.SOLIDITY.RESOLVING_INCORRECT_FILE_AS_PROJECT_FILE, - { file }, - ); - - file = "/asd/asd/foo.sol"; - await assertRejectsWithHardhatError( - () => resolver.resolveProjectFile(file), - HardhatError.ERRORS.SOLIDITY.RESOLVING_INCORRECT_FILE_AS_PROJECT_FILE, - { file }, - ); - }); - - it("Should resolve them to project files with their path from the project root as sourceName", async () => { - const resolver = await ResolverImplementation.create( - FIXTURE_HARDHAT_PROJECT_ROOT, - [], - ); - - assertResolvedProjectFile( - await resolver.resolveProjectFile( - path.join(FIXTURE_HARDHAT_PROJECT_ROOT, "contracts/File.sol"), - ), - "contracts/File.sol", - ); - - assertResolvedProjectFile( - await resolver.resolveProjectFile( - path.join(FIXTURE_HARDHAT_PROJECT_ROOT, "File.sol"), - ), - "File.sol", - ); - - assertResolvedProjectFile( - await resolver.resolveProjectFile( - path.join(FIXTURE_HARDHAT_PROJECT_ROOT, "npm/File.sol"), - ), - "npm/File.sol", - ); - }); - - it("Should validate that the files exists", async () => { - const resolver = await ResolverImplementation.create( - FIXTURE_HARDHAT_PROJECT_ROOT, - [], - ); - - await assertRejectsWithHardhatError( - resolver.resolveProjectFile( - path.join(FIXTURE_HARDHAT_PROJECT_ROOT, "nope.sol"), - ), - HardhatError.ERRORS.SOLIDITY.RESOLVING_NONEXISTENT_PROJECT_FILE, - { - file: "nope.sol", - }, - ); - }); - }); - - describe("Imports resolution", () => { - describe("Without user remappings", () => { - let resolver: Resolver; - let contractsFileSol: ProjectResolvedFile; - - beforeEach(async () => { - resolver = await ResolverImplementation.create( - FIXTURE_HARDHAT_PROJECT_ROOT, - [], - ); - - contractsFileSol = await resolver.resolveProjectFile( - path.resolve(FIXTURE_HARDHAT_PROJECT_ROOT, "contracts/File.sol"), - ); - }); - - describe("Imports from the project", () => { - describe("Imports of project files", () => { - describe("Relative imports", () => { - it("Should resolve them to project files with their path from the project root as sourceName", async () => { - assertResolvedProjectFile( - await resolver.resolveImport(contractsFileSol, "./File2.sol"), - "contracts/File2.sol", - ); - - assertResolvedProjectFile( - await resolver.resolveImport(contractsFileSol, "../File.sol"), - "File.sol", - ); - - assert.deepEqual(resolver.getRemappings(), []); - }); - - it("Should validate that the files exists with the right casing", async () => { - await assertRejectsWithHardhatError( - resolver.resolveImport(contractsFileSol, "./nope.sol"), - HardhatError.ERRORS.SOLIDITY.IMPORTED_FILE_DOESNT_EXIST, - { importPath: "./nope.sol", from: "contracts/File.sol" }, - ); - - await assertRejectsWithHardhatError( - resolver.resolveImport(contractsFileSol, "../file.sol"), - HardhatError.ERRORS.SOLIDITY.IMPORTED_FILE_WITH_ICORRECT_CASING, - { - importPath: "../file.sol", - from: "contracts/File.sol", - correctCasing: "File.sol", - }, - ); - - assert.deepEqual(resolver.getRemappings(), []); - }); - }); - - describe("Direct imports", () => { - it("Should resolve them to project files with the direct import as sourceName", async () => { - assertResolvedProjectFile( - await resolver.resolveImport( - contractsFileSol, - "contracts/File.sol", - ), - "contracts/File.sol", - ); - - assertResolvedProjectFile( - await resolver.resolveImport( - contractsFileSol, - "contracts/File2.sol", - ), - "contracts/File2.sol", - ); - - assertResolvedProjectFile( - await resolver.resolveImport(contractsFileSol, "npm/File.sol"), - "npm/File.sol", - ); - - assertResolvedProjectFile( - await resolver.resolveImport(contractsFileSol, "File.sol"), - "File.sol", - ); - - assert.deepEqual(resolver.getRemappings(), []); - }); - - it("Should validate that the files exist with the right casing", async () => { - // Note that the imports here are considered local imports, - // otherwise they would be validated as npm imports - - await assertRejectsWithHardhatError( - resolver.resolveImport(contractsFileSol, "contracts/nope.sol"), - HardhatError.ERRORS.SOLIDITY.IMPORTED_FILE_DOESNT_EXIST, - { - importPath: "contracts/nope.sol", - from: "contracts/File.sol", - }, - ); - - await assertRejectsWithHardhatError( - resolver.resolveImport(contractsFileSol, "contracts/file2.sol"), - HardhatError.ERRORS.SOLIDITY.IMPORTED_FILE_WITH_ICORRECT_CASING, - { - importPath: "contracts/file2.sol", - from: "contracts/File.sol", - correctCasing: "contracts/File2.sol", - }, - ); - - assert.deepEqual(resolver.getRemappings(), []); - }); - - it("Should treat files in the project root as local imports, even if they don't exist", async () => { - assertResolvedProjectFile( - await resolver.resolveImport(contractsFileSol, "File.sol"), - "File.sol", - ); - - await assertRejectsWithHardhatError( - resolver.resolveImport(contractsFileSol, "nope.sol"), - HardhatError.ERRORS.SOLIDITY.IMPORTED_FILE_DOESNT_EXIST, - { - importPath: "nope.sol", - from: "contracts/File.sol", - }, - ); - - assert.deepEqual(resolver.getRemappings(), []); - }); - - it("Should treat files whose first directory exists in the project root as local imports, even if they don't exist", async () => { - assertResolvedProjectFile( - await resolver.resolveImport( - contractsFileSol, - "hardhat/File.sol", - ), - "hardhat/File.sol", - ); - - await assertRejectsWithHardhatError( - resolver.resolveImport(contractsFileSol, "npm/nope.sol"), - HardhatError.ERRORS.SOLIDITY.IMPORTED_FILE_DOESNT_EXIST, - { - importPath: "npm/nope.sol", - from: "contracts/File.sol", - }, - ); - - assert.deepEqual(resolver.getRemappings(), []); - }); - }); - }); - - describe("Imports of npm files", () => { - it("Should always treat hardhat/console.sol as an npm file even if other hardhat/ files are local", async () => { - const consoleSol = await resolver.resolveImport( - contractsFileSol, - "hardhat/console.sol", - ); - - assertNpmPackageResolvedFile( - consoleSol, - { - name: "hardhat", - version: "3.0.0", - rootSourceName: "npm/hardhat@3.0.0/", - }, - "monorepo/node_modules/hardhat", - "console.sol", - ); - - const hardhatFile = await resolver.resolveImport( - contractsFileSol, - "hardhat/File.sol", - ); - - assertResolvedProjectFile(hardhatFile, "hardhat/File.sol"); - - assert.deepEqual(resolver.getRemappings(), [ - { - context: "", - prefix: "hardhat/console.sol", - target: "npm/hardhat@3.0.0/console.sol", - }, - ]); - }); - - it("Should fail if the package is not installed", async () => { - await assertRejectsWithHardhatError( - resolver.resolveImport( - contractsFileSol, - "uninstalled-package/File.sol", - ), - HardhatError.ERRORS.SOLIDITY - .IMPORTED_NPM_DEPENDENCY_NOT_INSTALLED, - { - from: "contracts/File.sol", - importPath: "uninstalled-package/File.sol", - }, - ); - }); - - it("Should fail if the package uses package.json#exports", async () => { - await assertRejectsWithHardhatError( - resolver.resolveImport(contractsFileSol, "exports/File.sol"), - HardhatError.ERRORS.SOLIDITY - .IMPORTED_NPM_DEPENDENCY_THAT_USES_EXPORTS, - { - from: "contracts/File.sol", - importPath: "exports/File.sol", - }, - ); - }); - - it("Should validate that the files exist with the right casing", async () => { - await assertRejectsWithHardhatError( - resolver.resolveImport(contractsFileSol, "dependency/nope.sol"), - HardhatError.ERRORS.SOLIDITY.IMPORTED_FILE_DOESNT_EXIST, - { - from: "contracts/File.sol", - importPath: "dependency/nope.sol", - }, - ); - - await assertRejectsWithHardhatError( - resolver.resolveImport(contractsFileSol, "dependency/file.sol"), - HardhatError.ERRORS.SOLIDITY.IMPORTED_FILE_WITH_ICORRECT_CASING, - { - from: "contracts/File.sol", - importPath: "dependency/file.sol", - correctCasing: "File.sol", - }, - ); - }); - - describe("Of a monorepo file", () => { - it("Should be resolved with npm/package@local/path/from/root", async () => { - const localDependencyFile = await resolver.resolveImport( - contractsFileSol, - "local-dependency/contracts/File.sol", - ); - - assertNpmPackageResolvedFile( - localDependencyFile, - { - name: "local-dependency", - version: "local", - rootSourceName: "npm/local-dependency@local/", - }, - "monorepo/packages/local-dependency", - "contracts/File.sol", - ); - - assert.deepEqual(resolver.getRemappings(), [ - { - context: "", - prefix: "local-dependency/", - target: "npm/local-dependency@local/", - }, - ]); - }); - }); - - describe("Of a direct npm dependency file", () => { - it("Should be resolved with npm/package@version/path/from/root", async () => { - const directDependencyFile = await resolver.resolveImport( - contractsFileSol, - "dependency/contracts/File.sol", - ); - - assertNpmPackageResolvedFile( - directDependencyFile, - { - name: "dependency", - version: "2.0.0", - rootSourceName: "npm/dependency@2.0.0/", - }, - "monorepo/packages/hardhat-project/node_modules/dependency", - "contracts/File.sol", - ); - - assert.deepEqual(resolver.getRemappings(), [ - { - context: "", - prefix: "dependency/", - target: "npm/dependency@2.0.0/", - }, - ]); - }); - }); - - describe("Of a hoisted npm dependency file", () => { - it("Should be resolved with npm/package@version/path/from/root", async () => { - const hoistedDependencyFile = await resolver.resolveImport( - contractsFileSol, - "hoisted/File.sol", - ); - - assertNpmPackageResolvedFile( - hoistedDependencyFile, - { - name: "hoisted", - version: "8.0.0", - rootSourceName: "npm/hoisted@8.0.0/", - }, - "monorepo/node_modules/hoisted", - "File.sol", - ); - - assert.deepEqual(resolver.getRemappings(), [ - { - context: "", - prefix: "hoisted/", - target: "npm/hoisted@8.0.0/", - }, - ]); - }); - }); - - describe("Of a scoped dependency file", () => { - it("Should be resolved with npm/@scope/package@version/path/from/root", async () => { - const scopeDependencyFile = await resolver.resolveImport( - contractsFileSol, - "@scope/dependency/contracts/File.sol", - ); - - assertNpmPackageResolvedFile( - scopeDependencyFile, - { - name: "@scope/dependency", - version: "1.0.0", - rootSourceName: "npm/@scope/dependency@1.0.0/", - }, - "monorepo/node_modules/@scope/dependency", - "contracts/File.sol", - ); - - assert.deepEqual(resolver.getRemappings(), [ - { - context: "", - prefix: "@scope/dependency/", - target: "npm/@scope/dependency@1.0.0/", - }, - ]); - }); - }); - - describe("Of package that's installed with an alternative name", () => { - it("Should be resolved with npm/package@version/path/from/root using the package.json's name", async () => { - const otherNameDependencyFile = await resolver.resolveImport( - contractsFileSol, - "other-name/contracts/File.sol", - ); - - assertNpmPackageResolvedFile( - otherNameDependencyFile, - { - name: "real-name", - version: "6.0.0", - rootSourceName: "npm/real-name@6.0.0/", - }, - "monorepo/packages/hardhat-project/node_modules/other-name", - "contracts/File.sol", - ); - - assert.deepEqual(resolver.getRemappings(), [ - { - context: "", - prefix: "other-name/", - target: "npm/real-name@6.0.0/", - }, - ]); - }); - - it("Should not resolve imports to the real-name if not installed with that name", async () => { - await assertRejectsWithHardhatError( - resolver.resolveImport( - contractsFileSol, - "real-name/contracts/File.sol", - ), - HardhatError.ERRORS.SOLIDITY - .IMPORTED_NPM_DEPENDENCY_NOT_INSTALLED, - { - from: "contracts/File.sol", - importPath: "real-name/contracts/File.sol", - }, - ); - }); - }); - }); - }); - - describe("Imports from an npm package", () => { - describe("Imports of the own package files", () => { - describe("Relative imports", () => { - it("Should resolve it without needing a new remapping", async () => { - const dependencyFile = await resolver.resolveImport( - contractsFileSol, - "dependency/contracts/File.sol", - ); - - assert.deepEqual(resolver.getRemappings(), [ - { - context: "", - prefix: "dependency/", - target: "npm/dependency@2.0.0/", - }, - ]); - - const dependencyFileAgain = await resolver.resolveImport( - dependencyFile, - "./File.sol", - ); - - assert.equal(dependencyFile, dependencyFileAgain); - - const dependencyNpmFile = await resolver.resolveImport( - dependencyFile, - "../npm/File.sol", - ); - - assertNpmPackageResolvedFile( - dependencyNpmFile, - { - name: "dependency", - version: "2.0.0", - rootSourceName: "npm/dependency@2.0.0/", - }, - "monorepo/packages/hardhat-project/node_modules/dependency", - "npm/File.sol", - ); - - assert.deepEqual(resolver.getRemappings(), [ - { - context: "", - prefix: "dependency/", - target: "npm/dependency@2.0.0/", - }, - ]); - }); - }); - - describe("Direct imports", () => { - it("Should resolve it and create a new remapping to avoid clashes with the project's source names", async () => { - const dependencyFile = await resolver.resolveImport( - contractsFileSol, - "dependency/contracts/File.sol", - ); - - assert.deepEqual(resolver.getRemappings(), [ - { - context: "", - prefix: "dependency/", - target: "npm/dependency@2.0.0/", - }, - ]); - - const dependencyContractsFileSol = await resolver.resolveImport( - dependencyFile, - "contracts/File.sol", - ); - - assertNpmPackageResolvedFile( - dependencyContractsFileSol, - { - name: "dependency", - version: "2.0.0", - rootSourceName: "npm/dependency@2.0.0/", - }, - "monorepo/packages/hardhat-project/node_modules/dependency", - "contracts/File.sol", - ); - - const dependencyFileSol = await resolver.resolveImport( - dependencyFile, - "File.sol", - ); - - assertNpmPackageResolvedFile( - dependencyFileSol, - { - name: "dependency", - version: "2.0.0", - rootSourceName: "npm/dependency@2.0.0/", - }, - "monorepo/packages/hardhat-project/node_modules/dependency", - "File.sol", - ); - - assert.deepEqual(resolver.getRemappings(), [ - { - context: "", - prefix: "dependency/", - target: "npm/dependency@2.0.0/", - }, - { - context: "npm/dependency@2.0.0/", - prefix: "File.sol", - target: "npm/dependency@2.0.0/File.sol", - }, - { - context: "npm/dependency@2.0.0/", - prefix: "contracts/", - target: "npm/dependency@2.0.0/contracts/", - }, - ]); - }); - }); - }); - - describe("Imports of npm files", () => { - describe("Of a monorepo file", () => { - it("Should be resolved with npm/package@local/path/from/root", async () => { - const dependencyFile = await resolver.resolveImport( - contractsFileSol, - "dependency/contracts/File.sol", - ); - - assert.deepEqual(resolver.getRemappings(), [ - { - context: "", - prefix: "dependency/", - target: "npm/dependency@2.0.0/", - }, - ]); - - const monorepoFile = await resolver.resolveImport( - dependencyFile, - "local-dependency/contracts/File.sol", - ); - - assertNpmPackageResolvedFile( - monorepoFile, - { - name: "local-dependency", - version: "local", - rootSourceName: "npm/local-dependency@local/", - }, - "monorepo/packages/local-dependency", - "contracts/File.sol", - ); - - assert.deepEqual(resolver.getRemappings(), [ - { - context: "", - prefix: "dependency/", - target: "npm/dependency@2.0.0/", - }, - { - context: "npm/dependency@2.0.0/", - prefix: "local-dependency/", - target: "npm/local-dependency@local/", - }, - ]); - }); - }); - - describe("Of a direct npm dependency file", () => { - it("Should be resolved with npm/package@version/path/from/root", async () => { - const dependencyFile = await resolver.resolveImport( - contractsFileSol, - "dependency/contracts/File.sol", - ); - - const dependencyDependencyFile = await resolver.resolveImport( - dependencyFile, - "dependencydependency/File.sol", - ); - - assertNpmPackageResolvedFile( - dependencyDependencyFile, - { - name: "dependencydependency", - version: "7.8.9", - rootSourceName: "npm/dependencydependency@7.8.9/", - }, - "monorepo/packages/hardhat-project/node_modules/dependency/node_modules/dependencydependency", - "File.sol", - ); - - assert.deepEqual(resolver.getRemappings(), [ - { - context: "", - prefix: "dependency/", - target: "npm/dependency@2.0.0/", - }, - { - context: "npm/dependency@2.0.0/", - prefix: "dependencydependency/", - target: "npm/dependencydependency@7.8.9/", - }, - ]); - }); - }); - - describe("Of a file within the hardhat project", () => { - it("Should resolve them to project files with the direct import as sourceName", async () => { - const dependencyFile = await resolver.resolveImport( - contractsFileSol, - "dependency/contracts/File.sol", - ); - - const localFile = await resolver.resolveImport( - dependencyFile, - "hardhat-project/File.sol", - ); - - assertResolvedProjectFile(localFile, "File.sol"); - - assert.deepEqual(resolver.getRemappings(), [ - { - context: "", - prefix: "dependency/", - target: "npm/dependency@2.0.0/", - }, - { - context: "npm/dependency@2.0.0/", - prefix: "hardhat-project/", - target: "", - }, - ]); - }); - }); - - describe("Of the same dependency than the hardhat project but a different version", () => { - it("Should be resolved with npm/package@version/path/from/root using the package.json's name", async () => { - const dependencyFile = await resolver.resolveImport( - contractsFileSol, - "dependency/contracts/File.sol", - ); - - const localDependencyFile = await resolver.resolveImport( - contractsFileSol, - "local-dependency/contracts/File.sol", - ); - - const localDependencyDependencyFile = - await resolver.resolveImport( - localDependencyFile, - "dependency/contracts/File.sol", - ); - - assert.notEqual(dependencyFile, localDependencyDependencyFile); - - assertNpmPackageResolvedFile( - dependencyFile, - { - name: "dependency", - version: "2.0.0", - rootSourceName: "npm/dependency@2.0.0/", - }, - "monorepo/packages/hardhat-project/node_modules/dependency", - "contracts/File.sol", - ); - - assertNpmPackageResolvedFile( - localDependencyDependencyFile, - { - name: "dependency", - version: "4.0.0", - rootSourceName: "npm/dependency@4.0.0/", - }, - "monorepo/packages/local-dependency/node_modules/dependency", - "contracts/File.sol", - ); - - assert.deepEqual(resolver.getRemappings(), [ - { - context: "", - prefix: "dependency/", - target: "npm/dependency@2.0.0/", - }, - { - context: "", - prefix: "local-dependency/", - target: "npm/local-dependency@local/", - }, - { - context: "npm/local-dependency@local/", - prefix: "dependency/", - target: "npm/dependency@4.0.0/", - }, - ]); - }); - }); - }); - }); - }); - - describe("With user remappings", () => { - describe("Resolver initialization", () => { - it("Should validate forbid remappings with npm/... context", async () => {}); - - it.todo("Should allow remappings with npm/... targets"); - - it.todo( - "Should validate and resolve npm/... targets of npm dependencies", - ); - - it.todo( - "Should validate and resolve npm/... targets of monorepo dependencies", - ); - }); - - describe("Imports from the project", () => { - describe("Imports into project files", () => { - it.todo( - "Should throw if the resulting sourceName would be considered an npm import if used as a direct import", - ); - - it.todo( - "Should validate that the resulting sourceName exists and has the correct casing as a relative path from the project root", - ); - - it.todo("Should resolve it to the remapped sourceName"); - }); - - describe("Imports into npm files", () => { - describe("Using the npm/ prefix", () => { - it.todo( - "Should be equivalent to just importing that file through npm", - ); - }); - }); - }); - - describe("Imports from an npm package", () => { - describe("Direct imports", () => { - it.todo( - "It should not be affected by a user remapping, even if the prefix matches", - ); - }); - }); - }); - - describe("Edge cases", () => { - describe("Duplicated dependency in the monorepo", () => { - it.todo("Should always be resolved to whatever was resolved first"); - }); - }); - }); -}); diff --git a/v-next/resolver/test/remappings.ts b/v-next/resolver/test/remappings.ts deleted file mode 100644 index b734ed96f79..00000000000 --- a/v-next/resolver/test/remappings.ts +++ /dev/null @@ -1,214 +0,0 @@ -import assert from "node:assert/strict"; -import { describe, it } from "node:test"; - -import { - applyValidRemapping, - formatRemapping, - parseRemappingString, - selectBestRemapping, -} from "../src/remappings.js"; - -describe("Remappings", () => { - describe("parseRemappingString", () => { - it("Should parse valid remappings correctly", () => { - assert.deepEqual(parseRemappingString("a:b=c"), { - context: "a", - prefix: "b", - target: "c", - }); - - assert.deepEqual(parseRemappingString("a:b="), { - context: "a", - prefix: "b", - target: "", - }); - - assert.deepEqual(parseRemappingString("a:/="), { - context: "a", - prefix: "/", - target: "", - }); - - assert.deepEqual(parseRemappingString(":b=c"), { - context: "", - prefix: "b", - target: "c", - }); - - assert.deepEqual(parseRemappingString("b=c"), { - context: "", - prefix: "b", - target: "c", - }); - - assert.deepEqual(parseRemappingString("b="), { - context: "", - prefix: "b", - target: "", - }); - }); - - it("Should throw on invalid remappings", () => { - assert.throws(() => parseRemappingString("a:=c")); - - assert.throws(() => parseRemappingString("a:c")); - - assert.throws(() => parseRemappingString("ac")); - - assert.throws(() => parseRemappingString("a/c")); - }); - }); - - describe("selectBestRemapping", () => { - describe("Without context", () => { - it("Should select the remapping with the longest matching prefix", () => { - const best = selectBestRemapping("from.sol", "directImport.sol", [ - { context: "", prefix: "from", target: "1" }, - { context: "", prefix: "dir", target: "2" }, - { context: "", prefix: "direct", target: "3" }, - { context: "", prefix: "directImp", target: "4" }, - ]); - - assert.deepEqual(best, { - context: "", - prefix: "directImp", - target: "4", - }); - }); - - it("Should keep the last matching one if there are many", () => { - const best = selectBestRemapping("from.sol", "directImport.sol", [ - { context: "", prefix: "direct", target: "1" }, - { context: "", prefix: "directImp", target: "2" }, - { context: "", prefix: "directImp", target: "3" }, - ]); - - assert.deepEqual(best, { - context: "", - prefix: "directImp", - target: "3", - }); - }); - - it("Should return undefined if there are no matching remappings", () => { - const best = selectBestRemapping("from.sol", "directImport.sol", [ - { context: "", prefix: "a", target: "1" }, - { context: "", prefix: "foo/", target: "2" }, - { context: "", prefix: "/not", target: "3" }, - ]); - - assert.deepEqual(best, undefined); - }); - }); - - describe("With context", () => { - it("Should select the remapping with the longest context whose prefix also matches", () => { - const best = selectBestRemapping("from.sol", "directImport.sol", [ - { context: "", prefix: "d", target: "1" }, - { context: "f", prefix: "d", target: "2" }, - { context: "fr", prefix: "d", target: "3" }, - { context: "fr", prefix: "not", target: "4" }, - { context: "f", prefix: "d", target: "5" }, - ]); - - assert.deepEqual(best, { context: "fr", prefix: "d", target: "3" }); - }); - - it("If multiple match the context with equal length, select the remapping with the longest prefix that matches", () => { - const best = selectBestRemapping("from.sol", "directImport.sol", [ - { context: "fr", prefix: "d", target: "1" }, - { context: "fr", prefix: "di", target: "2" }, - { context: "fr", prefix: "d", target: "3" }, - ]); - - assert.deepEqual(best, { context: "fr", prefix: "di", target: "2" }); - }); - - it("Context should have more priority than prefix", () => { - const best = selectBestRemapping("from.sol", "directImport.sol", [ - { context: "f", prefix: "d", target: "1" }, - { context: "not", prefix: "directImport.sol", target: "2" }, - ]); - - assert.deepEqual(best, { context: "f", prefix: "d", target: "1" }); - }); - - it("If there are multiple candidates pick the lastest one", () => { - const best = selectBestRemapping("from.sol", "directImport.sol", [ - { context: "fr", prefix: "di", target: "1" }, - { context: "fr", prefix: "di", target: "2" }, - { context: "fr", prefix: "di", target: "3" }, - ]); - - assert.deepEqual(best, { context: "fr", prefix: "di", target: "3" }); - }); - - it("If no remapping matches the context, return undefined", () => { - const best = selectBestRemapping("from.sol", "directImport.sol", [ - { context: "no", prefix: "directImport.sol", target: "1" }, - { context: "/", prefix: "di", target: "2" }, - { context: "boo", prefix: "di", target: "3" }, - ]); - - assert.deepEqual(best, undefined); - }); - }); - }); - - describe("Remappings application", () => { - it("Should apply valid remappings (prefix matches) correctly", () => { - assert.equal( - applyValidRemapping("contracts/A.sol", { - context: "", - prefix: "contracts/", - target: "lib/contracts/", - }), - "lib/contracts/A.sol", - ); - - assert.equal( - applyValidRemapping("contracts/A.sol", { - context: "", - prefix: "con", - target: "CON", - }), - "CONtracts/A.sol", - ); - - assert.equal( - applyValidRemapping("contracts/A.sol", { - context: "it-doesnt-matter", - prefix: "contracts/", - target: "", - }), - "A.sol", - ); - }); - }); - - describe("formatRemapping", () => { - it("Should format remappings without context correctly", () => { - assert.equal( - formatRemapping({ context: "", prefix: "a", target: "b" }), - "a=b", - ); - - assert.equal( - formatRemapping({ context: "", prefix: "a", target: "" }), - "a=", - ); - }); - - it("Should format remappings with context correctly", () => { - assert.equal( - formatRemapping({ context: "c", prefix: "a", target: "b" }), - "c:a=b", - ); - - assert.equal( - formatRemapping({ context: "c", prefix: "a", target: "" }), - "c:a=", - ); - }); - }); -}); diff --git a/v-next/resolver/test/test-fixtures/.gitignore b/v-next/resolver/test/test-fixtures/.gitignore deleted file mode 100644 index cf4bab9ddde..00000000000 --- a/v-next/resolver/test/test-fixtures/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!node_modules diff --git a/v-next/resolver/test/test-fixtures/monorepo/node_modules/@scope/dependency/contracts/File.sol b/v-next/resolver/test/test-fixtures/monorepo/node_modules/@scope/dependency/contracts/File.sol deleted file mode 100644 index 9936eec1e45..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/node_modules/@scope/dependency/contracts/File.sol +++ /dev/null @@ -1 +0,0 @@ -monorepo/node_modules/@scope/dependency/contracts/File.sol diff --git a/v-next/resolver/test/test-fixtures/monorepo/node_modules/@scope/dependency/package.json b/v-next/resolver/test/test-fixtures/monorepo/node_modules/@scope/dependency/package.json deleted file mode 100644 index 3ddf20908cc..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/node_modules/@scope/dependency/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "@scope/dependency", - "version": "1.0.0" -} diff --git a/v-next/resolver/test/test-fixtures/monorepo/node_modules/exports/package.json b/v-next/resolver/test/test-fixtures/monorepo/node_modules/exports/package.json deleted file mode 100644 index 53a33a48a3f..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/node_modules/exports/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "hardhat", - "version": "3.0.0", - "exports": { - ".": "./fool.js" - } -} diff --git a/v-next/resolver/test/test-fixtures/monorepo/node_modules/hardhat-project b/v-next/resolver/test/test-fixtures/monorepo/node_modules/hardhat-project deleted file mode 120000 index c06af93c623..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/node_modules/hardhat-project +++ /dev/null @@ -1 +0,0 @@ -../packages/hardhat-project \ No newline at end of file diff --git a/v-next/resolver/test/test-fixtures/monorepo/node_modules/hardhat/console.sol b/v-next/resolver/test/test-fixtures/monorepo/node_modules/hardhat/console.sol deleted file mode 100644 index 5d75e6588ba..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/node_modules/hardhat/console.sol +++ /dev/null @@ -1 +0,0 @@ -monorepo/node_modules/hardhat/console.sol diff --git a/v-next/resolver/test/test-fixtures/monorepo/node_modules/hardhat/package.json b/v-next/resolver/test/test-fixtures/monorepo/node_modules/hardhat/package.json deleted file mode 100644 index d1dae395d33..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/node_modules/hardhat/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "hardhat", - "version": "3.0.0" -} diff --git a/v-next/resolver/test/test-fixtures/monorepo/node_modules/hoisted/File.sol b/v-next/resolver/test/test-fixtures/monorepo/node_modules/hoisted/File.sol deleted file mode 100644 index 10436a11832..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/node_modules/hoisted/File.sol +++ /dev/null @@ -1 +0,0 @@ -monorepo/node_modules/hoisted/File.sol diff --git a/v-next/resolver/test/test-fixtures/monorepo/node_modules/hoisted/package.json b/v-next/resolver/test/test-fixtures/monorepo/node_modules/hoisted/package.json deleted file mode 100644 index 165430e591c..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/node_modules/hoisted/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "hoisted", - "version": "8.0.0" -} diff --git a/v-next/resolver/test/test-fixtures/monorepo/node_modules/local-dependency b/v-next/resolver/test/test-fixtures/monorepo/node_modules/local-dependency deleted file mode 120000 index d4325fd94b5..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/node_modules/local-dependency +++ /dev/null @@ -1 +0,0 @@ -../packages/local-dependency \ No newline at end of file diff --git a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/File.sol b/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/File.sol deleted file mode 100644 index 14558054cfe..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/File.sol +++ /dev/null @@ -1 +0,0 @@ -monorepo/packages/hardhat-project/File.sol diff --git a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/contracts/File.sol b/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/contracts/File.sol deleted file mode 100644 index 02e27bb10f9..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/contracts/File.sol +++ /dev/null @@ -1 +0,0 @@ -monorepo/packages/hardhat-project/contracts/File.sol diff --git a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/contracts/File2.sol b/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/contracts/File2.sol deleted file mode 100644 index 8f6c2abf44f..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/contracts/File2.sol +++ /dev/null @@ -1 +0,0 @@ -monorepo/packages/hardhat-project/contracts/File2.sol diff --git a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/hardhat/File.sol b/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/hardhat/File.sol deleted file mode 100644 index ac6a04daa7a..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/hardhat/File.sol +++ /dev/null @@ -1 +0,0 @@ -monorepo/packages/hardhat-project/hardhat/File.sol diff --git a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/File.sol b/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/File.sol deleted file mode 100644 index ad6c353193c..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/File.sol +++ /dev/null @@ -1 +0,0 @@ -monorepo/packages/hardhat-project/node_modules/dependency/File.sol diff --git a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/contracts/File.sol b/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/contracts/File.sol deleted file mode 100644 index 04dbfd75ebb..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/contracts/File.sol +++ /dev/null @@ -1 +0,0 @@ -monorepo/packages/hardhat-project/node_modules/dependency/contracts/File.sol diff --git a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/node_modules/dependencydependency/File.sol b/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/node_modules/dependencydependency/File.sol deleted file mode 100644 index 3bc55386054..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/node_modules/dependencydependency/File.sol +++ /dev/null @@ -1 +0,0 @@ -monorepo/packages/hardhat-project/node_modules/dependency/node_modules/dependencydependency/File.sol diff --git a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/node_modules/dependencydependency/package.json b/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/node_modules/dependencydependency/package.json deleted file mode 100644 index 8ff330fb616..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/node_modules/dependencydependency/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "dependencydependency", - "version": "7.8.9" -} diff --git a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/npm/File.sol b/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/npm/File.sol deleted file mode 100644 index 8e69251fe17..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/npm/File.sol +++ /dev/null @@ -1 +0,0 @@ -monorepo/packages/hardhat-project/node_modules/dependency/npm/File.sol diff --git a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/package.json b/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/package.json deleted file mode 100644 index 5358b31ea75..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/dependency/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "dependency", - "version": "2.0.0" -} diff --git a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/other-name/contracts/File.sol b/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/other-name/contracts/File.sol deleted file mode 100644 index 17e36470284..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/other-name/contracts/File.sol +++ /dev/null @@ -1 +0,0 @@ -monorepo/packages/hardhat-project/node_modules/other-name/contracts/File.sol diff --git a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/other-name/package.json b/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/other-name/package.json deleted file mode 100644 index 82f52b1a68c..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/node_modules/other-name/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "real-name", - "version": "6.0.0" -} diff --git a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/npm/File.sol b/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/npm/File.sol deleted file mode 100644 index 57f6c67cb77..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/npm/File.sol +++ /dev/null @@ -1 +0,0 @@ -monorepo/packages/hardhat-project/npm/File.sol diff --git a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/package.json b/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/package.json deleted file mode 100644 index 07d0abbf429..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/packages/hardhat-project/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "hardhat-project", - "version": "3.0.0" -} diff --git a/v-next/resolver/test/test-fixtures/monorepo/packages/local-dependency/contracts/File.sol b/v-next/resolver/test/test-fixtures/monorepo/packages/local-dependency/contracts/File.sol deleted file mode 100644 index 31f07aac63e..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/packages/local-dependency/contracts/File.sol +++ /dev/null @@ -1 +0,0 @@ -monorepo/packages/local-dependency/contracts/File.sol diff --git a/v-next/resolver/test/test-fixtures/monorepo/packages/local-dependency/node_modules/dependency/contracts/File.sol b/v-next/resolver/test/test-fixtures/monorepo/packages/local-dependency/node_modules/dependency/contracts/File.sol deleted file mode 100644 index 2f2143539b9..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/packages/local-dependency/node_modules/dependency/contracts/File.sol +++ /dev/null @@ -1 +0,0 @@ -monorepo/packages/local-dependency/node_modules/dependency/contracts/File.sol diff --git a/v-next/resolver/test/test-fixtures/monorepo/packages/local-dependency/node_modules/dependency/package.json b/v-next/resolver/test/test-fixtures/monorepo/packages/local-dependency/node_modules/dependency/package.json deleted file mode 100644 index c18c69f3763..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/packages/local-dependency/node_modules/dependency/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "dependency", - "version": "4.0.0" -} diff --git a/v-next/resolver/test/test-fixtures/monorepo/packages/local-dependency/package.json b/v-next/resolver/test/test-fixtures/monorepo/packages/local-dependency/package.json deleted file mode 100644 index 46c87489d15..00000000000 --- a/v-next/resolver/test/test-fixtures/monorepo/packages/local-dependency/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "local-dependency", - "version": "5.0.0" -} diff --git a/v-next/resolver/tsconfig.json b/v-next/resolver/tsconfig.json deleted file mode 100644 index a49f5159bfb..00000000000 --- a/v-next/resolver/tsconfig.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "extends": "../../config-v-next/tsconfig.json", - "compilerOptions": { - "outDir": "./dist", - "composite": true, - "incremental": true - }, - "exclude": [ - "./dist", - "./node_modules", - "./test/fixture-projects/hardhat.config.ts" - ], - "references": [ - { - "path": "../hardhat-errors" - }, - { - "path": "../hardhat-node-test-reporter" - }, - { - "path": "../hardhat-utils" - }, - { - "path": "../hardhat-test-utils" - } - ] -}