From cf5f455638bf4aa7633236ea8a0dfc3e99c27eb5 Mon Sep 17 00:00:00 2001 From: Sergey Tselovalnikov Date: Mon, 25 Jul 2022 21:19:33 +1000 Subject: [PATCH 1/6] [Intellij-Solidity Release] - '2.3.11-SNAPSHOT'. --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index f27c51cc..6d900f23 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version=2.3.10 +version=2.3.11-SNAPSHOT group=me.serce kotlin_version=1.6.21 sentry_version=1.6.4 From 98e2e72c72d60ca109fc3051c74a4c102fee719d Mon Sep 17 00:00:00 2001 From: Andrew Potter Date: Sat, 3 Sep 2022 02:19:04 -0400 Subject: [PATCH 2/6] Resolve top-level Enums, Structs, Errors, and user-defined types from imports w/ various fixes (#324) --- .../solidity/ide/annotation/annotator.kt | 9 ++++- .../me/serce/solidity/lang/resolve/engine.kt | 33 ++++++++++--------- .../serce/solidity/lang/resolve/ref/refs.kt | 9 +++++ .../me/serce/solidity/lang/types/inference.kt | 1 + 4 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/main/kotlin/me/serce/solidity/ide/annotation/annotator.kt b/src/main/kotlin/me/serce/solidity/ide/annotation/annotator.kt index c592a46b..68729a9a 100644 --- a/src/main/kotlin/me/serce/solidity/ide/annotation/annotator.kt +++ b/src/main/kotlin/me/serce/solidity/ide/annotation/annotator.kt @@ -49,6 +49,7 @@ class SolidityAnnotator : Annotator { is SolStructDefinition -> element.identifier?.let { applyColor(holder, it, SolColor.STRUCT_NAME) } is SolEnumDefinition -> element.identifier?.let { applyColor(holder, it, SolColor.ENUM_NAME) } is SolEventDefinition -> element.identifier?.let { applyColor(holder, it, SolColor.EVENT_NAME) } + is SolUserDefinedValueTypeDefinition -> element.identifier?.let { applyColor(holder, it, SolColor.USER_DEFINED_VALUE_TYPE) } is SolConstantVariableDeclaration -> applyColor(holder, element.identifier, SolColor.CONSTANT) is SolStateVariableDeclaration -> { if (element.mutationModifier?.textMatches("constant") == true) { @@ -74,7 +75,13 @@ class SolidityAnnotator : Annotator { else -> when(SolResolver.resolveTypeNameUsingImports(element).firstOrNull()) { is SolErrorDefinition -> applyColor(holder, element.referenceNameElement, SolColor.ERROR_NAME) is SolEventDefinition -> applyColor(holder, element.referenceNameElement, SolColor.EVENT_NAME) - else -> applyColor(holder, element.referenceNameElement, SolColor.FUNCTION_CALL) + else -> element.firstChild.let { + if (it is SolPrimaryExpression && SolResolver.resolveTypeNameUsingImports(element.firstChild).filterIsInstance().isNotEmpty()) { + applyColor(holder, element.referenceNameElement, SolColor.STRUCT_NAME) + } else { + applyColor(holder, element.referenceNameElement, SolColor.FUNCTION_CALL) + } + } } } } diff --git a/src/main/kotlin/me/serce/solidity/lang/resolve/engine.kt b/src/main/kotlin/me/serce/solidity/lang/resolve/engine.kt index 3fa47ab4..3c154038 100644 --- a/src/main/kotlin/me/serce/solidity/lang/resolve/engine.kt +++ b/src/main/kotlin/me/serce/solidity/lang/resolve/engine.kt @@ -24,11 +24,11 @@ object SolResolver { val result = if (element is SolFunctionCallElement) { resolveError(element) + resolveEvent(element) + - resolveContractUsingImports(element, element.containingFile, true) + + resolveContract(element) + resolveEnum(element) + resolveUserDefinedValueType(element) } else { - resolveContractUsingImports(element, element.containingFile, true) + + resolveContract(element) + resolveEnum(element) + resolveStruct(element) + resolveUserDefinedValueType(element) @@ -39,17 +39,18 @@ object SolResolver { /** * @param withAliases aliases are not recursive, so count them only at the first level of recursion */ - private fun resolveContractUsingImports( + private fun resolveUsingImports( + target: Class, element: PsiElement, file: PsiFile, - withAliases: Boolean - ): Set = - RecursionManager.doPreventingRecursion(ResolveContractKey(element.nameOrText, file), true) { + withAliases: Boolean, + ): Set = + RecursionManager.doPreventingRecursion(ResolveUsingImportsKey(element.nameOrText, file), true) { if (element is SolUserDefinedTypeName && element.findIdentifiers().size > 1) { emptySet() } else { val inFile = file.children - .filterIsInstance() + .filterIsInstance(target) .filter { it.name == element.nameOrText } val resolvedViaAlias = when (withAliases) { @@ -64,7 +65,7 @@ object SolResolver { } } }.flatMap { (alias, resolvedFile) -> - resolveContractUsingImports(alias, resolvedFile.containingFile, false) + resolveUsingImports(target, alias, resolvedFile.containingFile, false) } else -> emptyList() } @@ -72,28 +73,30 @@ object SolResolver { val imported = file.children .filterIsInstance() .mapNotNull { nullIfError { it.importPath?.reference?.resolve()?.containingFile } } - .flatMap { resolveContractUsingImports(element, it, false) } + .flatMap { resolveUsingImports(target, element, it, false) } (inFile + resolvedViaAlias + imported).toSet() } } ?: emptySet() + private fun resolveContract(element: PsiElement): Set = + resolveUsingImports(SolContractDefinition::class.java, element, element.containingFile, true) private fun resolveEnum(element: PsiElement): Set = - resolveInFile(element) + resolveInnerType(element) { it.enumDefinitionList } + resolveInnerType(element) { it.enumDefinitionList } + resolveUsingImports(SolEnumDefinition::class.java, element, element.containingFile, true) private fun resolveStruct(element: PsiElement): Set = - resolveInFile(element) + resolveInnerType(element) { it.structDefinitionList } + resolveInnerType(element) { it.structDefinitionList } + resolveUsingImports(SolStructDefinition::class.java, element, element.containingFile, true) private fun resolveUserDefinedValueType(element: PsiElement): Set = - resolveInFile(element) + resolveInnerType( + resolveInnerType( element, - { it.userDefinedValueTypeDefinitionList }) + { it.userDefinedValueTypeDefinitionList }) + resolveUsingImports(SolUserDefinedValueTypeDefinition::class.java, element, element.containingFile, true) private fun resolveEvent(element: PsiElement): Set = resolveInnerType(element) { it.eventDefinitionList } private fun resolveError(element: PsiElement): Set = - resolveInnerType(element) { it.errorDefinitionList } + resolveInnerType(element) { it.errorDefinitionList } + resolveUsingImports(SolErrorDefinition::class.java, element, element.containingFile, true) private inline fun resolveInFile(element: PsiElement) : Set { return element.parentOfType() @@ -343,7 +346,7 @@ object SolResolver { } } -data class ResolveContractKey(val name: String?, val file: PsiFile) +data class ResolveUsingImportsKey(val name: String?, val file: PsiFile) private fun Sequence.takeWhileInclusive(pred: (T) -> Boolean): Sequence { var shouldContinue = true diff --git a/src/main/kotlin/me/serce/solidity/lang/resolve/ref/refs.kt b/src/main/kotlin/me/serce/solidity/lang/resolve/ref/refs.kt index 8ef36b74..f7067588 100644 --- a/src/main/kotlin/me/serce/solidity/lang/resolve/ref/refs.kt +++ b/src/main/kotlin/me/serce/solidity/lang/resolve/ref/refs.kt @@ -93,6 +93,15 @@ class SolFunctionCallReference(element: SolFunctionCallExpression) : SolReferenc } fun resolveFunctionCall(): Collection { + if (element.parent is SolRevertStatement) { + return SolResolver.resolveTypeNameUsingImports(element).filterIsInstance() + } + if (element.firstChild is SolPrimaryExpression) { + val structs = SolResolver.resolveTypeNameUsingImports(element.firstChild).filterIsInstance() + if (structs.isNotEmpty()) { + return structs + } + } val resolved: Collection = when (val expr = element.expression) { is SolPrimaryExpression -> { val regular = expr.varLiteral?.let { SolResolver.resolveVarLiteral(it) } diff --git a/src/main/kotlin/me/serce/solidity/lang/types/inference.kt b/src/main/kotlin/me/serce/solidity/lang/types/inference.kt index fa739e19..524b21a0 100644 --- a/src/main/kotlin/me/serce/solidity/lang/types/inference.kt +++ b/src/main/kotlin/me/serce/solidity/lang/types/inference.kt @@ -73,6 +73,7 @@ private fun getSolTypeFromUserDefinedTypeName(type: SolUserDefinedTypeName): Sol is SolContractDefinition -> SolContract(it) is SolStructDefinition -> SolStruct(it) is SolEnumDefinition -> SolEnum(it) + is SolUserDefinedValueTypeDefinition -> getSolType(it.elementaryTypeName) else -> null } } From 236035a1f4501f092cc4c85760839a8f4580e02f Mon Sep 17 00:00:00 2001 From: Sergey Tselovalnikov Date: Sat, 3 Sep 2022 16:41:00 +1000 Subject: [PATCH 3/6] add tests for #324 (#327) --- .../core/resolve/SolFunctionResolveTest.kt | 21 ++++++++++++++++ .../lang/core/resolve/SolStructResolveTest.kt | 24 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/src/test/kotlin/me/serce/solidity/lang/core/resolve/SolFunctionResolveTest.kt b/src/test/kotlin/me/serce/solidity/lang/core/resolve/SolFunctionResolveTest.kt index a492cddb..9b4b3923 100644 --- a/src/test/kotlin/me/serce/solidity/lang/core/resolve/SolFunctionResolveTest.kt +++ b/src/test/kotlin/me/serce/solidity/lang/core/resolve/SolFunctionResolveTest.kt @@ -393,6 +393,27 @@ class SolFunctionResolveTest : SolResolveTestBase() { """) } + fun testResolveImportedError() { + val file1 = InlineFile(""" + error XyzError(uint x); + //x + """, + name = "Xyz.sol" + ) + + val file2 = InlineFile(""" + import "./Xyz.sol"; + contract B { + function doit(uint256[] storage array) { + revert XyzError(1); + //^ + } + } + """) + + testResolveBetweenFiles(file1, file2) + } + fun checkIsResolved(@Language("Solidity") code: String) { val (refElement, _) = resolveInCode(code) assertNotNull(refElement.reference?.resolve()) diff --git a/src/test/kotlin/me/serce/solidity/lang/core/resolve/SolStructResolveTest.kt b/src/test/kotlin/me/serce/solidity/lang/core/resolve/SolStructResolveTest.kt index 144c13ec..9594c1a5 100644 --- a/src/test/kotlin/me/serce/solidity/lang/core/resolve/SolStructResolveTest.kt +++ b/src/test/kotlin/me/serce/solidity/lang/core/resolve/SolStructResolveTest.kt @@ -78,4 +78,28 @@ class SolStructResolveTest : SolResolveTestBase() { //^ } """) + + fun testResolveImportedStruct() { + val file1 = InlineFile( + code = """ + struct Proposal { + //x + uint256 id; + } + """.trimIndent(), + name = "Abc.sol" + ) + + val file2 = InlineFile(""" + import "./Abc.sol"; + contract B { + function doit(uint256[] storage array) { + Proposal prop = Proposal(1); + //^ + } + } + """) + + testResolveBetweenFiles(file1, file2) + } } From cd84374c00ab06527d0501fb221b1f89ce11b015 Mon Sep 17 00:00:00 2001 From: Andrew Potter Date: Sat, 3 Sep 2022 02:42:02 -0400 Subject: [PATCH 4/6] Fix highlighting for payable, immutable, receive, fallback, and enum values (#325) --- .../serce/solidity/ide/annotation/annotator.kt | 17 ++++++++++++++++- .../me/serce/solidity/ide/colors/SolColor.kt | 2 ++ .../kotlin/me/serce/solidity/ide/highlighter.kt | 2 +- .../solidity/ide/colors/highlighter_example.sol | 10 ++++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/me/serce/solidity/ide/annotation/annotator.kt b/src/main/kotlin/me/serce/solidity/ide/annotation/annotator.kt index 68729a9a..c2b4870f 100644 --- a/src/main/kotlin/me/serce/solidity/ide/annotation/annotator.kt +++ b/src/main/kotlin/me/serce/solidity/ide/annotation/annotator.kt @@ -23,6 +23,10 @@ class SolidityAnnotator : Annotator { when (element) { is SolNumberType -> applyColor(holder, element, SolColor.TYPE) is SolElementaryTypeName -> applyColor(holder, element, SolColor.TYPE) + is SolStateMutability -> if (element.text == "payable") { + applyColor(holder, element, SolColor.KEYWORD) + } + is SolEnumValue -> applyColor(holder, element, SolColor.ENUM_VALUE) is SolMemberAccessExpression -> when(element.expression.firstChild.text) { "super" -> applyColor(holder, element.expression.firstChild, SolColor.KEYWORD) "msg", "block", "abi" -> applyColor(holder, element.expression.firstChild, SolColor.GLOBAL) @@ -58,7 +62,17 @@ class SolidityAnnotator : Annotator { applyColor(holder, element.identifier, SolColor.STATE_VARIABLE) } } - is SolFunctionDefinition -> element.identifier?.let { applyColor(holder, it, SolColor.FUNCTION_DECLARATION) } + is SolFunctionDefinition -> { + val identifier = element.identifier + if (identifier !== null) { + applyColor(holder, identifier, SolColor.FUNCTION_DECLARATION) + } else { + val firstChildNode = element.node.firstChildNode + if (firstChildNode.text == "receive" || firstChildNode.text == "fallback") { + applyColor(holder, firstChildNode.textRange, SolColor.RECEIVE_FALLBACK_DECLARATION) + } + } + } is SolModifierDefinition -> element.identifier?.let { applyColor(holder, it, SolColor.FUNCTION_DECLARATION) } is SolModifierInvocation -> applyColor(holder, element.varLiteral.identifier, SolColor.FUNCTION_CALL) is SolUserDefinedTypeName -> { @@ -72,6 +86,7 @@ class SolidityAnnotator : Annotator { is SolFunctionCallElement -> when(element.firstChild.text) { "keccak256" -> applyColor(holder, element.firstChild, SolColor.GLOBAL_FUNCTION_CALL) "require" -> applyColor(holder, element.firstChild, SolColor.KEYWORD) + "assert" -> applyColor(holder, element.firstChild, SolColor.KEYWORD) else -> when(SolResolver.resolveTypeNameUsingImports(element).firstOrNull()) { is SolErrorDefinition -> applyColor(holder, element.referenceNameElement, SolColor.ERROR_NAME) is SolEventDefinition -> applyColor(holder, element.referenceNameElement, SolColor.EVENT_NAME) diff --git a/src/main/kotlin/me/serce/solidity/ide/colors/SolColor.kt b/src/main/kotlin/me/serce/solidity/ide/colors/SolColor.kt index 957fc47d..c07cf4fb 100644 --- a/src/main/kotlin/me/serce/solidity/ide/colors/SolColor.kt +++ b/src/main/kotlin/me/serce/solidity/ide/colors/SolColor.kt @@ -13,6 +13,7 @@ enum class SolColor(humanName: String, default: TextAttributesKey) { ERROR_NAME("Types//Error name", Defaults.CLASS_NAME), EVENT_NAME("Types//Event name", Defaults.CLASS_NAME), ENUM_NAME("Types//Enum name", Defaults.CLASS_NAME), + ENUM_VALUE("Types//Enum value", Defaults.STATIC_FIELD), TYPE("Types//Value type", Defaults.KEYWORD), USER_DEFINED_VALUE_TYPE("Types//User-defined value type", Defaults.CLASS_NAME), @@ -21,6 +22,7 @@ enum class SolColor(humanName: String, default: TextAttributesKey) { STATE_VARIABLE("Identifiers//State variable", Defaults.INSTANCE_FIELD), FUNCTION_DECLARATION("Functions//Function declaration", Defaults.FUNCTION_DECLARATION), + RECEIVE_FALLBACK_DECLARATION("Functions//Receive/Fallback declaration", Defaults.STATIC_METHOD), FUNCTION_CALL("Functions//Function call", Defaults.FUNCTION_CALL), GLOBAL_FUNCTION_CALL("Functions//Global function call", Defaults.GLOBAL_VARIABLE), diff --git a/src/main/kotlin/me/serce/solidity/ide/highlighter.kt b/src/main/kotlin/me/serce/solidity/ide/highlighter.kt index 1bb559fd..adf836b8 100644 --- a/src/main/kotlin/me/serce/solidity/ide/highlighter.kt +++ b/src/main/kotlin/me/serce/solidity/ide/highlighter.kt @@ -56,7 +56,7 @@ object SolHighlighter : SyntaxHighlighterBase() { IF, ELSE, FOR, WHILE, DO, BREAK, CONTINUE, THROW, USING, RETURN, RETURNS, MAPPING, EVENT, /*ERROR,*/ ANONYMOUS, MODIFIER, ASSEMBLY, VAR, STORAGE, MEMORY, WEI, ETHER, GWEI, SZABO, FINNEY, SECONDS, MINUTES, HOURS, - DAYS, WEEKS, YEARS, TYPE, VIRTUAL, OVERRIDE + DAYS, WEEKS, YEARS, TYPE, VIRTUAL, OVERRIDE, IMMUTABLE, INDEXED ) private fun types() = setOf( diff --git a/src/main/resources/me/serce/solidity/ide/colors/highlighter_example.sol b/src/main/resources/me/serce/solidity/ide/colors/highlighter_example.sol index 47479a3d..75599bc6 100644 --- a/src/main/resources/me/serce/solidity/ide/colors/highlighter_example.sol +++ b/src/main/resources/me/serce/solidity/ide/colors/highlighter_example.sol @@ -4,6 +4,13 @@ uint8 constant MASK = 0x01; +enum Types { + Type1, + Type2 +} + +type Arg is uint256; + /** * @title Claimable * @dev Extension for the Ownable contract, where the ownership needs to be claimed. @@ -28,6 +35,9 @@ _; } + receive() external payable {} + fallback() external {} + function transferOwnership(address newOwner) onlyOwner { pendingOwner = newOwner; } From 4b2bb602bd68f3fa4830b562a62b95463af3f556 Mon Sep 17 00:00:00 2001 From: Jason Zong Date: Wed, 9 Nov 2022 19:05:42 +0800 Subject: [PATCH 5/6] add remappings.txt support for foundry (#331) --- .gitignore | 2 +- .../resolve/ref/SolImportPathReference.kt | 45 ++++++++++++++++--- .../resolve/SolImportResolveFoundryTest.kt | 26 +++++++++++ .../ImportUsageFoundryOpenzeppelin.sol | 4 ++ .../contracts/ImportUsageFoundrySolmate.sol | 4 ++ .../contracts/ImportUsageFoundryStd.sol | 4 ++ .../lib/forge-std/src/Test.sol | 1 + .../contracts/token/ERC20/ERC20.sol | 1 + .../lib/solmate/src/tokens/ERC721.sol | 1 + .../fixtures/importRemappings/remappings.txt | 3 ++ 10 files changed, 84 insertions(+), 7 deletions(-) create mode 100644 src/test/kotlin/me/serce/solidity/lang/core/resolve/SolImportResolveFoundryTest.kt create mode 100644 src/test/resources/fixtures/importRemappings/contracts/ImportUsageFoundryOpenzeppelin.sol create mode 100644 src/test/resources/fixtures/importRemappings/contracts/ImportUsageFoundrySolmate.sol create mode 100644 src/test/resources/fixtures/importRemappings/contracts/ImportUsageFoundryStd.sol create mode 100644 src/test/resources/fixtures/importRemappings/lib/forge-std/src/Test.sol create mode 100644 src/test/resources/fixtures/importRemappings/lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol create mode 100644 src/test/resources/fixtures/importRemappings/lib/solmate/src/tokens/ERC721.sol create mode 100644 src/test/resources/fixtures/importRemappings/remappings.txt diff --git a/.gitignore b/.gitignore index e188607e..7295c835 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ *.ipr *.iws gen -lib +/lib .sandbox .DS_Store /out/ diff --git a/src/main/kotlin/me/serce/solidity/lang/resolve/ref/SolImportPathReference.kt b/src/main/kotlin/me/serce/solidity/lang/resolve/ref/SolImportPathReference.kt index d7920ce3..935a1759 100644 --- a/src/main/kotlin/me/serce/solidity/lang/resolve/ref/SolImportPathReference.kt +++ b/src/main/kotlin/me/serce/solidity/lang/resolve/ref/SolImportPathReference.kt @@ -45,17 +45,50 @@ class SolImportPathReference(element: SolImportPathElement) : SolReferenceBase lib/forge-std/src/Test.sol - private fun findFoundryImportFile(file: VirtualFile, path: String): VirtualFile? { + // apply foundry remappings to import path + private fun applyRemappings(remappings: ArrayList>, path: String):String { + var output = path; + remappings.forEach { (prefix, target) -> + if (path.contains(prefix)) { + output = path.replace(prefix, target) + return output + } + } + return output; + } + + private fun foundryDefaultFallback(file: VirtualFile, path: String): VirtualFile? { val count = Paths.get(path).nameCount; - if (count < 2) { + if (count<2) { return null; } - val libName = Paths.get(path).subpath(0, 1).toString(); - val libFile = Paths.get(path).subpath(1, count).toString(); + val libName = Paths.get(path).subpath(0,1).toString(); + val libFile = Paths.get(path).subpath(1,count).toString(); val test = file.findFileByRelativePath("lib/$libName/src/$libFile"); + return test; + } + + // default lib located at: forge-std/Test.sol => lib/forge-std/src/Test.sol + private fun findFoundryImportFile(file: VirtualFile, path: String): VirtualFile? { + val testRemappingFile = file.findFileByRelativePath("remappings.txt"); + val remappings = arrayListOf>(); + if (testRemappingFile != null) { + val mappingsContents = testRemappingFile.contentsToByteArray().toString(Charsets.UTF_8).split("[\r\n]+".toRegex()); + mappingsContents.forEach { mapping -> + val splitMapping = mapping.split("=") + if (splitMapping.size == 2) { + remappings.add(Pair(splitMapping[0].trim(),splitMapping[1].trim())) + } + } + } + + val remappedPath = applyRemappings(remappings, path); + val testRemappedPath = file.findFileByRelativePath(remappedPath); + val testFoundryFallback = foundryDefaultFallback(file, path); + return when { - test != null -> test + testRemappedPath != null -> testRemappedPath + testFoundryFallback != null -> testFoundryFallback file.parent != null -> findFoundryImportFile(file.parent, path) else -> null } diff --git a/src/test/kotlin/me/serce/solidity/lang/core/resolve/SolImportResolveFoundryTest.kt b/src/test/kotlin/me/serce/solidity/lang/core/resolve/SolImportResolveFoundryTest.kt new file mode 100644 index 00000000..b72f2b3f --- /dev/null +++ b/src/test/kotlin/me/serce/solidity/lang/core/resolve/SolImportResolveFoundryTest.kt @@ -0,0 +1,26 @@ +package me.serce.solidity.lang.core.resolve + +import me.serce.solidity.lang.psi.SolNamedElement + +class SolImportResolveFoundryTest : SolResolveTestBase() { + + fun testImportPathResolveFoundryRemappings() { + val testcases = arrayListOf>( + Pair("lib/forge-std/src/Test.sol","contracts/ImportUsageFoundryStd.sol"), + Pair("lib/solmate/src/tokens/ERC721.sol","contracts/ImportUsageFoundrySolmate.sol"), + Pair("lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol","contracts/ImportUsageFoundryOpenzeppelin.sol"), + ); + testcases.forEach { (targetFile, contractFile) -> + val file1 = myFixture.configureByFile(targetFile) + myFixture.configureByFile("remappings.txt") + myFixture.configureByFile(contractFile) + val (refElement) = findElementAndDataInEditor("^") + val resolved = checkNotNull(refElement.reference?.resolve()) { + "Failed to resolve ${refElement.text}" + } + assertEquals(file1.name, resolved.containingFile.name) + } + } + + override fun getTestDataPath() = "src/test/resources/fixtures/importRemappings/" +} diff --git a/src/test/resources/fixtures/importRemappings/contracts/ImportUsageFoundryOpenzeppelin.sol b/src/test/resources/fixtures/importRemappings/contracts/ImportUsageFoundryOpenzeppelin.sol new file mode 100644 index 00000000..565b507c --- /dev/null +++ b/src/test/resources/fixtures/importRemappings/contracts/ImportUsageFoundryOpenzeppelin.sol @@ -0,0 +1,4 @@ +import "@openzeppelin/token/ERC20/ERC20.sol"; + //^ + +contract ImportUsage {} diff --git a/src/test/resources/fixtures/importRemappings/contracts/ImportUsageFoundrySolmate.sol b/src/test/resources/fixtures/importRemappings/contracts/ImportUsageFoundrySolmate.sol new file mode 100644 index 00000000..67557299 --- /dev/null +++ b/src/test/resources/fixtures/importRemappings/contracts/ImportUsageFoundrySolmate.sol @@ -0,0 +1,4 @@ +import "@solmate/tokens/ERC721.sol"; + //^ + +contract ImportUsage {} diff --git a/src/test/resources/fixtures/importRemappings/contracts/ImportUsageFoundryStd.sol b/src/test/resources/fixtures/importRemappings/contracts/ImportUsageFoundryStd.sol new file mode 100644 index 00000000..c85830d1 --- /dev/null +++ b/src/test/resources/fixtures/importRemappings/contracts/ImportUsageFoundryStd.sol @@ -0,0 +1,4 @@ +import "forge-std/Test.sol"; + //^ + +contract ImportUsage {} diff --git a/src/test/resources/fixtures/importRemappings/lib/forge-std/src/Test.sol b/src/test/resources/fixtures/importRemappings/lib/forge-std/src/Test.sol new file mode 100644 index 00000000..445bc713 --- /dev/null +++ b/src/test/resources/fixtures/importRemappings/lib/forge-std/src/Test.sol @@ -0,0 +1 @@ +contract Test {} diff --git a/src/test/resources/fixtures/importRemappings/lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol b/src/test/resources/fixtures/importRemappings/lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol new file mode 100644 index 00000000..bd44a6a9 --- /dev/null +++ b/src/test/resources/fixtures/importRemappings/lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol @@ -0,0 +1 @@ +contract ERC20 {} diff --git a/src/test/resources/fixtures/importRemappings/lib/solmate/src/tokens/ERC721.sol b/src/test/resources/fixtures/importRemappings/lib/solmate/src/tokens/ERC721.sol new file mode 100644 index 00000000..ab2bbc60 --- /dev/null +++ b/src/test/resources/fixtures/importRemappings/lib/solmate/src/tokens/ERC721.sol @@ -0,0 +1 @@ +contract ERC721 {} diff --git a/src/test/resources/fixtures/importRemappings/remappings.txt b/src/test/resources/fixtures/importRemappings/remappings.txt new file mode 100644 index 00000000..c8dfcebd --- /dev/null +++ b/src/test/resources/fixtures/importRemappings/remappings.txt @@ -0,0 +1,3 @@ +@solmate/=lib/solmate/src/ +@openzeppelin/=lib/openzeppelin-contracts/contracts/ + From b2cf6a4e45b96767314db59ba8ed599792b91d51 Mon Sep 17 00:00:00 2001 From: carter-ya Date: Wed, 9 Nov 2022 20:54:52 +0800 Subject: [PATCH 6/6] support create smart contract interface (#332) --- src/main/kotlin/me/serce/solidity/ide/actions/createFile.kt | 1 + .../internal/Solidity Contract Interface.sol.ft | 6 ++++++ .../internal/Solidity Contract Interface.sol.html | 5 +++++ .../fileTemplates/internal/Solidity Contract.sol.ft | 3 ++- .../fileTemplates/internal/Solidity Library.sol.ft | 1 + 5 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/fileTemplates/internal/Solidity Contract Interface.sol.ft create mode 100644 src/main/resources/fileTemplates/internal/Solidity Contract Interface.sol.html diff --git a/src/main/kotlin/me/serce/solidity/ide/actions/createFile.kt b/src/main/kotlin/me/serce/solidity/ide/actions/createFile.kt index 5846450c..73206ce6 100644 --- a/src/main/kotlin/me/serce/solidity/ide/actions/createFile.kt +++ b/src/main/kotlin/me/serce/solidity/ide/actions/createFile.kt @@ -25,6 +25,7 @@ class SolCreateFileAction : CreateFileFromTemplateAction(CAPTION, "", SolidityIc ) { builder.setTitle(CAPTION) .addKind("Smart contract", SolidityIcons.FILE_ICON, SMART_CONTRACT_TEMPLATE) + .addKind("Smart contract interface", SolidityIcons.FILE_ICON, "Solidity Contract Interface") .addKind("Solidity library", SolidityIcons.FILE_ICON, "Solidity Library") .setValidator(object : InputValidatorEx { override fun checkInput(inputString: String): Boolean { diff --git a/src/main/resources/fileTemplates/internal/Solidity Contract Interface.sol.ft b/src/main/resources/fileTemplates/internal/Solidity Contract Interface.sol.ft new file mode 100644 index 00000000..d76a0a31 --- /dev/null +++ b/src/main/resources/fileTemplates/internal/Solidity Contract Interface.sol.ft @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.0; + +interface ${NAME} { + +} diff --git a/src/main/resources/fileTemplates/internal/Solidity Contract Interface.sol.html b/src/main/resources/fileTemplates/internal/Solidity Contract Interface.sol.html new file mode 100644 index 00000000..743160c5 --- /dev/null +++ b/src/main/resources/fileTemplates/internal/Solidity Contract Interface.sol.html @@ -0,0 +1,5 @@ + + +Empty Solidity smart contract interface. + + diff --git a/src/main/resources/fileTemplates/internal/Solidity Contract.sol.ft b/src/main/resources/fileTemplates/internal/Solidity Contract.sol.ft index 0d35906a..819cba3b 100644 --- a/src/main/resources/fileTemplates/internal/Solidity Contract.sol.ft +++ b/src/main/resources/fileTemplates/internal/Solidity Contract.sol.ft @@ -1,7 +1,8 @@ +// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; contract ${NAME} { - function ${NAME}(){ + constructor(){ } } diff --git a/src/main/resources/fileTemplates/internal/Solidity Library.sol.ft b/src/main/resources/fileTemplates/internal/Solidity Library.sol.ft index 2162c4c9..393005fd 100644 --- a/src/main/resources/fileTemplates/internal/Solidity Library.sol.ft +++ b/src/main/resources/fileTemplates/internal/Solidity Library.sol.ft @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; library ${NAME} {