Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unqualified match enum variant #181

Merged
merged 12 commits into from
Aug 15, 2024
5 changes: 5 additions & 0 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ jobs:
gradle-version: wrapper
cache-read-only: false
arguments: ":resolveDependencies -Pkotlin.incremental=false --no-daemon"
gradle-home-cache-cleanup: true
gradle-home-cache-excludes: |
caches/modules-2/files-2.1/com.jetbrains.intellij.pycharm
caches/modules-2/files-2.1/com.jetbrains.intellij.idea
Expand All @@ -41,6 +42,7 @@ jobs:
with:
gradle-version: wrapper
arguments: "assemble testClasses -Pkotlin.incremental=false --no-daemon --stacktrace"
gradle-home-cache-cleanup: true
gradle-home-cache-excludes: |
caches/modules-2/files-2.1/com.jetbrains.intellij.pycharm
caches/modules-2/files-2.1/com.jetbrains.intellij.idea
Expand All @@ -51,6 +53,7 @@ jobs:
with:
gradle-version: wrapper
arguments: ":test -Pkotlin.incremental=false --no-daemon --stacktrace"
gradle-home-cache-cleanup: true
gradle-home-cache-excludes: |
caches/modules-2/files-2.1/com.jetbrains.intellij.pycharm
caches/modules-2/files-2.1/com.jetbrains.intellij.idea
Expand All @@ -61,6 +64,7 @@ jobs:
with:
gradle-version: wrapper
arguments: ":verifyPluginConfiguration -Pkotlin.incremental=false --no-daemon"
gradle-home-cache-cleanup: true
gradle-home-cache-excludes: |
caches/modules-2/files-2.1/com.jetbrains.intellij.pycharm
caches/modules-2/files-2.1/com.jetbrains.intellij.idea
Expand All @@ -71,6 +75,7 @@ jobs:
with:
gradle-version: wrapper
arguments: ":verifyPlugin -Pkotlin.incremental=false --no-daemon"
gradle-home-cache-cleanup: true
gradle-home-cache-excludes: |
caches/modules-2/files-2.1/com.jetbrains.intellij.pycharm
caches/modules-2/files-2.1/com.jetbrains.intellij.idea
Expand Down
42 changes: 28 additions & 14 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ version = pluginVersion
plugins {
id("java")
kotlin("jvm") version "1.9.25"
id("org.jetbrains.intellij.platform") version "2.0.0"
id("org.jetbrains.intellij.platform") version "2.0.1"
id("org.jetbrains.grammarkit") version "2022.3.2.2"
id("net.saliman.properties") version "1.5.2"
id("org.gradle.idea")
Expand Down Expand Up @@ -185,7 +185,7 @@ allprojects {
}

tasks {
withType<KotlinCompile> {
compileKotlin {
kotlinOptions {
jvmTarget = "17"
languageVersion = "1.9"
Expand All @@ -194,7 +194,7 @@ allprojects {
}
}

withType<Jar> {
jar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

Expand Down Expand Up @@ -238,34 +238,41 @@ allprojects {
generateLexer {
sourceFile.set(file("src/main/grammars/MoveLexer.flex"))
targetOutputDir.set(file("src/main/gen/org/move/lang"))
purgeOldFiles.set(true)
// purgeOldFiles.set(true)
}
generateParser {
sourceFile.set(file("src/main/grammars/MoveParser.bnf"))
targetRootOutputDir.set(file("src/main/gen"))
// not used if purgeOldFiles set to false
pathToParser.set("/org/move/lang/MoveParser.java")
pathToPsiRoot.set("/org/move/lang/psi")
purgeOldFiles.set(true)
pathToPsiRoot.set("/org/move/lang/core/psi")
// purgeOldFiles.set(true)
}
withType<KotlinCompile> {
dependsOn(generateLexer, generateParser)
}

runIde {
prepareSandbox {
dependsOn("downloadAptosBinaries")
copyDownloadedAptosBinaries(this)
}
}

val runIdeWithPlugins by intellijPlatformTesting.runIde.registering {
plugins {
plugin("com.google.ide-perf:1.3.1")
// plugin("PsiViewer:PsiViewer 241.14494.158-EAP-SNAPSHOT")
}
task {
systemProperty("org.move.debug.enabled", true)
// systemProperty("org.move.external.linter.max.duration", 30) // 30 ms
// systemProperty("org.move.aptos.bundled.force.unsupported", true)
// systemProperty("idea.log.debug.categories", "org.move.cli")
}

prepareSandbox {
// enabled = true
prepareSandboxTask {
dependsOn("downloadAptosBinaries")
// copy bin/ directory inside the plugin zip file
from("$rootDir/bin") {
into("$pluginName/bin")
include("**")
}
copyDownloadedAptosBinaries(this)
}
}

Expand Down Expand Up @@ -328,6 +335,13 @@ allprojects {

//}

fun copyDownloadedAptosBinaries(copyTask: AbstractCopyTask) {
copyTask.from("$rootDir/bin") {
into("$pluginName/bin")
include("**")
}
}

val Project.dependencyCachePath
get(): String {
val cachePath = file("${rootProject.projectDir}/deps")
Expand Down
54 changes: 39 additions & 15 deletions src/main/grammars/MoveParser.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ private ScriptItem_with_recover ::= !('}' | <<eof>>) ScriptItem
recoverWhile = ScriptItem_recover
}
// top-level recovery
private ScriptItem_recover ::= !('}' | ScriptItem_first)
private ScriptItem_recover ::= !('}' | ScriptItem_first | TopLevel_first)
private ScriptItem_first ::= use | CONST_KW | fun

private ScriptItem ::= UseStmt | Const | FunctionInner
Expand Down Expand Up @@ -261,10 +261,11 @@ private ModuleItem_with_recover ::= !('}' | <<eof>>) ModuleItem
pin = 1
recoverWhile = ModuleItem_recover
}
private ModuleItem_recover ::= !('}' | ModuleItem_first)
private ModuleItem_recover ::= !('}' | ModuleItem_first | TopLevel_first)
// top-level recovery
private ModuleItem_first ::= use | public | native | fun | CONST_KW | STRUCT_KW | spec
| Attr_first | "friend" | "entry" | "inline" | "enum"
private TopLevel_first ::= MODULE_KW | SCRIPT_KW

private ModuleItem ::= UseStmt
| FriendDecl
Expand Down Expand Up @@ -676,17 +677,31 @@ Pat ::= TuplePat
| WildPat
| BindingPat

MatchPat ::= Pat | EnumVariantPat
EnumVariantPat ::= PathImpl !('{')
MatchPat ::= Pat | PathPat
PathPat ::= PathImpl

WildPat ::= '_'
EnumVariantPat ::= PathImpl

BindingPat ::= IDENTIFIER !'::' {

// XXX(matklad): it is impossible to distinguish between nullary enum variants
// and identifiers during parsing.
//
// match x {
// None => { } // match enum variant
// Name => { } // bind Name to x
// }
BindingPat ::= IDENTIFIER !ForbiddenBindingPatLast {
implements = [
"org.move.lang.core.psi.MvMandatoryNameIdentifierOwner"
"org.move.lang.core.resolve.ref.MvMandatoryReferenceElement"
]
mixin = "org.move.lang.core.psi.ext.MvBindingPatMixin"
}
//private ForbiddenBindingPatLast ::= '...' | '::' | '..=' | '..' | '<' | '(' | '{' | '!' {
private ForbiddenBindingPatLast ::= '::' | '<' | '(' | '{' | '!' {
consumeTokenMethod = "consumeTokenFast"
}

TuplePat ::= '(' ParenListElemPat_with_recover* ')'
private ParenListElemPat_with_recover ::= !')' Pat (',' | &')') {
Expand All @@ -706,14 +721,24 @@ private FieldPat_with_recover ::= !'}' FieldPat (',' | &'}')
}
private FieldPat_recover ::= !('}' | IDENTIFIER)

FieldPat ::= (BindingPat !':') | (IDENTIFIER FieldPatBinding)
FieldPatFull ::= IDENTIFIER ':' Pat
{
implements = [
"org.move.lang.core.resolve.ref.MvStructPatFieldReferenceElement"
"org.move.lang.core.psi.ext.MvFieldRef"
// "org.move.lang.core.resolve.ref.MvStructPatFieldReferenceElement"
"org.move.lang.core.resolve.ref.MvMandatoryReferenceElement"
]
mixin = "org.move.lang.core.psi.ext.MvFieldPatMixin"
mixin = "org.move.lang.core.psi.ext.MvFieldPatFullMixin"
}
FieldPat ::= FieldPatFull | BindingPat

//FieldPat ::= (BindingPat !':') | (IDENTIFIER FieldPatBinding)
//{
// implements = [
//// "org.move.lang.core.resolve.ref.MvStructPatFieldReferenceElement"
// "org.move.lang.core.psi.ext.MvFieldReferenceElement"
// ]
// mixin = "org.move.lang.core.psi.ext.MvFieldPatMixin"
//}
FieldPatBinding ::= ':' Pat

private Pat_first ::= '_' | '(' | Path_first | AnyLitToken_first
Expand Down Expand Up @@ -959,8 +984,8 @@ private StructLitField_recover ::= !('}' | IDENTIFIER)
StructLitField ::= IDENTIFIER StructLitFieldInit?
{
implements = [
"org.move.lang.core.resolve.ref.MvStructFieldLitReferenceElement"
"org.move.lang.core.psi.ext.MvFieldRef"
"org.move.lang.core.resolve.ref.MvMandatoryReferenceElement"
// "org.move.lang.core.psi.ext.MvFieldReferenceElement"
]
mixin = "org.move.lang.core.psi.ext.MvStructLitFieldMixin"
}
Expand Down Expand Up @@ -1028,17 +1053,16 @@ MatchExpr ::= Attr* <<remapContextualKwOnRollback (match MatchArgument MatchBody
{
implements = [ "org.move.lang.core.psi.ext.MvDocAndAttributeOwner" ]
}
// argument is fake, provided just to satisfy usage checker
//private MatchExprImpl ::= <<remapMatchOnRollback (match '(' Expr ')' MatchBody)>>
//private MatchExprImplInner ::= match '(' Expr ')' MatchBody
MatchArgument ::= '(' Expr ')'

MatchBody ::= '{' MatchArm_with_recover* '}' { pin = 1 }
MatchArm ::= Attr* MatchPat '=>' Expr ','?
MatchArm ::= Attr* (Pat | EnumVariantPat) MatchArmGuard? '=>' Expr ','?
{
pin = 2
implements = [ "org.move.lang.core.psi.ext.MvDocAndAttributeOwner" ]
}
MatchArmGuard ::= if Expr

private MatchArm_with_recover ::= !'}' MatchArm
{
pin = 1
Expand Down
6 changes: 2 additions & 4 deletions src/main/kotlin/org/move/cli/LibraryRootsProvider.kt
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,8 @@ private val MoveProject.ideaLibraries: Collection<SyntheticLibrary>
}
.map {
val sourceRoots = it.layoutPaths().mapNotNull { p -> p.toVirtualFile() }.toMutableSet()
val tomlFile = it.moveToml.tomlFile.virtualFile
sourceRoots.add(tomlFile)
// it.moveToml.tomlFile
// .virtualFile.let { f -> sourceRoots.add(f) }
// val tomlFile = it.manifestFile
sourceRoots.add(it.manifestFile)
MoveLangLibrary(it.packageName, sourceRoots, emptySet(), MoveIcons.MOVE_LOGO, null)
}

Expand Down
40 changes: 27 additions & 13 deletions src/main/kotlin/org/move/cli/MovePackage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,27 @@ import org.move.cli.manifest.MoveToml
import org.move.lang.core.psi.MvElement
import org.move.lang.moveProject
import org.move.lang.toNioPathOrNull
import org.move.openapiext.common.isLightTestFile
import org.move.openapiext.common.isUnitTestMode
import org.move.openapiext.pathAsPath
import org.move.openapiext.resolveExisting
import org.move.openapiext.toPsiFile
import org.toml.lang.psi.TomlFile
import java.nio.file.Path
import kotlin.io.path.relativeToOrNull

data class MovePackage(
val project: Project,
val contentRoot: VirtualFile,
val moveToml: MoveToml,
) {
val packageName = this.moveToml.packageName ?: ""
val packageName: String,
val tomlMainAddresses: PackageAddresses,
) {
val manifestFile: VirtualFile get() = contentRoot.findChild(Consts.MANIFEST_FILE)!!

val manifestTomlFile: TomlFile get() = manifestFile.toPsiFile(project) as TomlFile
val moveToml: MoveToml get() = MoveToml.fromTomlFile(this.manifestTomlFile)

// val packageName = this.moveToml.packageName ?: ""

val sourcesFolder: VirtualFile? get() = contentRoot.takeIf { it.isValid }?.findChild("sources")
val testsFolder: VirtualFile? get() = contentRoot.takeIf { it.isValid }?.findChild("tests")
Expand Down Expand Up @@ -53,40 +63,44 @@ data class MovePackage(
}

fun addresses(): PackageAddresses {
val tomlMainAddresses = moveToml.declaredAddresses()
val tomlDevAddresses = moveToml.declaredAddresses()
// val tomlMainAddresses = tomlMainAddresses
// val tomlDevAddresses = moveToml.declaredAddresses()

val addresses = mutableAddressMap()
addresses.putAll(tomlMainAddresses.values)
// add placeholders defined in this package as address values
addresses.putAll(tomlMainAddresses.placeholdersAsValues())
// devs on top
addresses.putAll(tomlDevAddresses.values)
// addresses.putAll(tomlDevAddresses.values)

return PackageAddresses(addresses, tomlMainAddresses.placeholders)
}

override fun hashCode(): Int {
return this.moveToml.tomlFile.toNioPathOrNull()?.hashCode() ?: this.hashCode()
}
override fun hashCode(): Int = this.contentRoot.hashCode()

override fun equals(other: Any?): Boolean {
if (other !is MovePackage) return false
val leftPath = this.moveToml.tomlFile.toNioPathOrNull() ?: return false
val rightPath = other.moveToml.tomlFile.toNioPathOrNull() ?: return false
return leftPath == rightPath
if (this === other) return true
return this.contentRoot == other.contentRoot
}

companion object {
fun fromMoveToml(moveToml: MoveToml): MovePackage {
val contentRoot = moveToml.tomlFile.virtualFile.parent
return MovePackage(moveToml.project, contentRoot, moveToml)
return MovePackage(moveToml.project, contentRoot,
packageName = moveToml.packageName ?: "",
tomlMainAddresses = moveToml.declaredAddresses())
}
}
}

val MvElement.containingMovePackage: MovePackage?
get() {
val elementFile = this.containingFile.virtualFile
if (isUnitTestMode && elementFile.isLightTestFile) {
// temp file for light unit tests
return project.testMoveProject.currentPackage
}
val elementPath = this.containingFile?.toNioPathOrNull() ?: return null
val allPackages = this.moveProject?.movePackages().orEmpty()
return allPackages.find {
Expand Down
Loading
Loading