Skip to content

Commit 822607e

Browse files
committed
Cleanup some styles and fix null issue in project roots map (Fixes #338)
1 parent 564cb52 commit 822607e

File tree

11 files changed

+63
-55
lines changed

11 files changed

+63
-55
lines changed

src/main/kotlin/com/demonwav/mcdev/creator/BuildSystemWizardStep.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,11 @@ class BuildSystemWizardStep(private val creator: MinecraftProjectCreator) : Modu
9393
throw EmptyFieldSetupException(versionField)
9494
}
9595

96-
if (!groupIdField.text.matches("\\S+".toRegex())) {
96+
if (!groupIdField.text.matches(NO_WHITESPACE)) {
9797
throw OtherSetupException("The GroupId field cannot contain any whitespace", groupIdField)
9898
}
9999

100-
if (!artifactIdField.text.matches("\\S+".toRegex())) {
100+
if (!artifactIdField.text.matches(NO_WHITESPACE)) {
101101
throw OtherSetupException("The ArtifactId field cannot contain any whitespace", artifactIdField)
102102
}
103103

@@ -114,4 +114,8 @@ class BuildSystemWizardStep(private val creator: MinecraftProjectCreator) : Modu
114114

115115
return true
116116
}
117+
118+
companion object {
119+
val NO_WHITESPACE = "\\S+".toRegex()
120+
}
117121
}

src/main/kotlin/com/demonwav/mcdev/facet/MinecraftFacet.kt

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import com.demonwav.mcdev.platform.PlatformType
1919
import com.demonwav.mcdev.platform.forge.ForgeModuleType
2020
import com.demonwav.mcdev.platform.sponge.SpongeModuleType
2121
import com.demonwav.mcdev.util.containsAllKeys
22+
import com.demonwav.mcdev.util.filterNotNull
2223
import com.demonwav.mcdev.util.mapFirstNotNull
2324
import com.demonwav.mcdev.util.runInlineReadAction
2425
import com.google.common.collect.HashMultimap
@@ -43,8 +44,8 @@ import javax.swing.Icon
4344
class MinecraftFacet(module: Module, name: String, configuration: MinecraftFacetConfiguration, underlyingFacet: Facet<*>?) :
4445
Facet<MinecraftFacetConfiguration>(facetType, module, name, configuration, underlyingFacet) {
4546

46-
private val modules = ConcurrentHashMap<AbstractModuleType<*>, AbstractModule>()
47-
private val roots: HashMultimap<SourceType, VirtualFile> = HashMultimap.create()
47+
private val moduleMap = ConcurrentHashMap<AbstractModuleType<*>, AbstractModule>()
48+
private val roots: HashMultimap<SourceType, VirtualFile?> = HashMultimap.create()
4849

4950
init {
5051
configuration.facet = this
@@ -55,10 +56,10 @@ class MinecraftFacet(module: Module, name: String, configuration: MinecraftFacet
5556
}
5657

5758
override fun disposeFacet() {
58-
modules.forEach { (_, m) ->
59+
moduleMap.forEach { (_, m) ->
5960
m.dispose()
6061
}
61-
modules.clear()
62+
moduleMap.clear()
6263
roots.clear()
6364
}
6465

@@ -78,20 +79,20 @@ class MinecraftFacet(module: Module, name: String, configuration: MinecraftFacet
7879
}
7980

8081
// Remove modules that aren't registered anymore
81-
val toBeRemoved = modules.entries.asSequence()
82+
val toBeRemoved = moduleMap.entries.asSequence()
8283
.filter { !allEnabled.contains(it.key.platformType) }
8384
.onEach { it.value.dispose() }
8485
.map { it.key }
8586
.toHashSet() // CME defense
86-
toBeRemoved.forEach { modules.remove(it) }
87+
toBeRemoved.forEach { moduleMap.remove(it) }
8788

8889
// Do this before we register the new modules
8990
updateRoots()
9091

9192
// Add modules which are new
9293
allEnabled
9394
.map { it.type }
94-
.filter { !modules.containsKey(it) }
95+
.filter { !moduleMap.containsKey(it) }
9596
.forEach(this::register)
9697

9798
ProjectView.getInstance(module.project).refresh()
@@ -103,7 +104,7 @@ class MinecraftFacet(module: Module, name: String, configuration: MinecraftFacet
103104

104105
rootManager.contentEntries.asSequence()
105106
.flatMap { entry -> entry.sourceFolders.asSequence() }
106-
.filter { it.file == null }
107+
.filterNotNull { it.file }
107108
.forEach {
108109
when (it.rootType) {
109110
JavaSourceRootType.SOURCE -> roots.put(SourceType.SOURCE, it.file)
@@ -116,26 +117,24 @@ class MinecraftFacet(module: Module, name: String, configuration: MinecraftFacet
116117

117118
private fun register(type: AbstractModuleType<*>) {
118119
type.performCreationSettingSetup(module.project)
119-
modules[type] = type.generateModule(this)
120+
moduleMap[type] = type.generateModule(this)
120121
}
121122

122-
@Contract(pure = true)
123-
fun getModules(): Collection<AbstractModule> = modules.values
124-
@Contract(pure = true)
125-
fun getTypes(): Collection<AbstractModuleType<*>> = modules.keys
123+
val modules get() = moduleMap.values
124+
val types get() = moduleMap.keys
126125

127126
@Contract(pure = true)
128-
fun isOfType(type: AbstractModuleType<*>) = modules.containsKey(type)
127+
fun isOfType(type: AbstractModuleType<*>) = moduleMap.containsKey(type)
129128

130129
@Contract(pure = true)
131130
fun <T : AbstractModule> getModuleOfType(type: AbstractModuleType<T>): T? {
132131
@Suppress("UNCHECKED_CAST")
133-
return modules[type] as? T
132+
return moduleMap[type] as? T
134133
}
135134

136135
@Contract(value = "null -> false", pure = true)
137136
fun isEventClassValidForModule(eventClass: PsiClass?) =
138-
eventClass != null && modules.values.any { it.isEventClassValid(eventClass, null) }
137+
eventClass != null && moduleMap.values.any { it.isEventClassValid(eventClass, null) }
139138

140139
@Contract(pure = true)
141140
fun isEventClassValid(eventClass: PsiClass, method: PsiMethod): Boolean {
@@ -166,7 +165,7 @@ class MinecraftFacet(module: Module, name: String, configuration: MinecraftFacet
166165
}
167166

168167
private inline fun <T> doIfGood(method: PsiMethod, action: (AbstractModule) -> T): T? {
169-
for (abstractModule in modules.values) {
168+
for (abstractModule in moduleMap.values) {
170169
val good = abstractModule.moduleType.listenerAnnotations.any {
171170
method.modifierList.findAnnotation(it) != null
172171
}
@@ -178,28 +177,27 @@ class MinecraftFacet(module: Module, name: String, configuration: MinecraftFacet
178177
return null
179178
}
180179

181-
@Contract(pure = true)
182-
fun isEventGenAvailable() = modules.keys.any { it.isEventGenAvailable }
180+
val isEventGenAvailable get() = moduleMap.keys.any { it.isEventGenAvailable }
183181

184182
@Contract(pure = true)
185-
fun shouldShowPluginIcon(element: PsiElement?) = modules.values.any { it.shouldShowPluginIcon(element) }
186-
187-
@Contract(pure = true)
188-
fun getIcon(): Icon? {
189-
val iconCount = modules.keys.count { it.hasIcon() }
190-
return when {
191-
iconCount == 0 -> null
192-
iconCount == 1 -> modules.keys.firstOrNull { it.hasIcon() }?.icon
193-
iconCount == 2 && modules.containsAllKeys(SpongeModuleType, ForgeModuleType) -> PlatformAssets.SPONGE_FORGE_ICON
194-
modules.size > 0 -> PlatformAssets.MINECRAFT_ICON
195-
else -> null
183+
fun shouldShowPluginIcon(element: PsiElement?) = moduleMap.values.any { it.shouldShowPluginIcon(element) }
184+
185+
val icon: Icon?
186+
get() {
187+
val iconCount = moduleMap.keys.count { it.hasIcon() }
188+
return when {
189+
iconCount == 0 -> null
190+
iconCount == 1 -> moduleMap.keys.firstOrNull { it.hasIcon() }?.icon
191+
iconCount == 2 && moduleMap.containsAllKeys(SpongeModuleType, ForgeModuleType) -> PlatformAssets.SPONGE_FORGE_ICON
192+
moduleMap.size > 0 -> PlatformAssets.MINECRAFT_ICON
193+
else -> null
194+
}
196195
}
197-
}
198196

199197
fun findFile(path: String, type: SourceType): VirtualFile? {
200198
val roots = roots[type]
201199
for (root in roots) {
202-
return root.findFileByRelativePath(path) ?: continue
200+
return root?.findFileByRelativePath(path) ?: continue
203201
}
204202
return null
205203
}

src/main/kotlin/com/demonwav/mcdev/insight/ColorUtil.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ fun <T> PsiElement.findColor(function: (Map<String, Color>, Map.Entry<String, Co
3333
val expression = this
3434
val type = expression.type ?: return null
3535

36-
for (abstractModuleType in facet.getTypes()) {
36+
for (abstractModuleType in facet.types) {
3737
val map = abstractModuleType.classToColorMappings
3838
for (entry in map.entries) {
3939
// This is such a hack

src/main/kotlin/com/demonwav/mcdev/insight/InsightUtil.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ val PsiElement.eventListener: Pair<PsiClass, PsiMethod>?
3838
val instance = MinecraftFacet.getInstance(module) ?: return null
3939
// Since each platform has their own valid listener annotations,
4040
// some platforms may have multiple allowed annotations for various cases
41-
val listenerAnnotations = instance.getTypes().flatMap { it.listenerAnnotations }
41+
val listenerAnnotations = instance.types.flatMap { it.listenerAnnotations }
4242
var contains = false
4343
for (listenerAnnotation in listenerAnnotations) {
4444
if (modifierList.findAnnotation(listenerAnnotation) != null) {

src/main/kotlin/com/demonwav/mcdev/insight/ListenerEventAnnotator.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class ListenerEventAnnotator : Annotator {
4545
val instance = MinecraftFacet.getInstance(module) ?: return
4646
// Since each platform has their own valid listener annotations,
4747
// some platforms may have multiple allowed annotations for various cases
48-
val moduleTypes = instance.getTypes()
48+
val moduleTypes = instance.types
4949
var contains = false
5050
for (moduleType in moduleTypes) {
5151
val listenerAnnotations = moduleType.listenerAnnotations

src/main/kotlin/com/demonwav/mcdev/insight/generation/GenerateEventListenerHandler.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class GenerateEventListenerHandler : GenerateMembersHandlerBase("Generate Event
6868
chosenClass = chooser.selected
6969

7070
chosenClass?.let { chosenClass ->
71-
val relevantModule = facet.getModules().asSequence()
71+
val relevantModule = facet.modules.asSequence()
7272
.filter { m -> isSuperEventListenerAllowed(chosenClass, m) }
7373
.firstOrNull() ?: return null
7474

@@ -131,7 +131,7 @@ class GenerateEventListenerHandler : GenerateMembersHandlerBase("Generate Event
131131
val module = ModuleUtilCore.findModuleForPsiElement(file) ?: return false
132132

133133
val instance = MinecraftFacet.getInstance(module)
134-
return instance != null && instance.isEventGenAvailable()
134+
return instance != null && instance.isEventGenAvailable
135135
}
136136

137137
companion object {

src/main/kotlin/com/demonwav/mcdev/inspection/IsCancelledInspection.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class IsCancelledInspection : BaseInspection() {
4040

4141
val instance = MinecraftFacet.getInstance(module) ?: return
4242

43-
val useless = instance.getModules().stream()
43+
val useless = instance.modules.stream()
4444
.mapNotNull { m -> m.checkUselessCancelCheck(expression) }
4545
.findAny()
4646

src/main/kotlin/com/demonwav/mcdev/platform/AbstractModule.kt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,13 @@ import javax.swing.Icon
2525

2626
abstract class AbstractModule(protected val facet: MinecraftFacet) {
2727

28-
@get:Contract(pure = true)
2928
val module: Module = facet.module
30-
@get:Contract(pure = true)
3129
val project = module.project
3230

33-
@get:Contract(pure = true)
3431
abstract val moduleType: AbstractModuleType<*>
3532

36-
@get:Contract(pure = true)
3733
abstract val type: PlatformType
3834

39-
@get:Contract(pure = true)
4035
open val icon: Icon?
4136
get() = moduleType.icon
4237

src/main/kotlin/com/demonwav/mcdev/platform/MinecraftProjectViewNodeDecorator.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class MinecraftProjectViewNodeDecorator : ProjectViewNodeDecorator {
6161
val manager = ModuleManager.getInstance(project)
6262
val path = manager.getModuleGroupPath(module)
6363
if (path == null) {
64-
data.setIcon(children.iterator().next().getIcon())
64+
data.setIcon(children.iterator().next().icon)
6565
return
6666
}
6767

@@ -70,7 +70,7 @@ class MinecraftProjectViewNodeDecorator : ProjectViewNodeDecorator {
7070
return
7171
}
7272

73-
data.setIcon(children.iterator().next().getIcon())
73+
data.setIcon(children.iterator().next().icon)
7474
}
7575

7676
override fun decorate(node: PackageDependenciesNode, cellRenderer: ColoredTreeCellRenderer) {}

src/main/kotlin/com/demonwav/mcdev/util/delegates.kt

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,32 +12,41 @@ package com.demonwav.mcdev.util
1212

1313
import kotlin.reflect.KProperty
1414

15-
class NullableDelegate<T>(private val supplier: () -> T?) {
15+
class NullableDelegate<T>(supplier: () -> T?) {
1616
private var field: T? = null
17+
private var func: (() -> T?)? = supplier
1718

1819
private val lock = Lock()
1920

2021
operator fun getValue(thisRef: Any?, property: KProperty<*>): T? {
21-
if (field != null) {
22-
return field
22+
var f = field
23+
if (f != null) {
24+
return f
2325
}
2426

2527
synchronized(lock) {
26-
if (field != null) {
27-
return field
28+
f = field
29+
if (f != null) {
30+
return f
2831
}
2932

30-
field = supplier()
33+
f = func!!()
34+
35+
// Don't hold on to the supplier after it's used and returned a value
36+
if (f != null) {
37+
field = f
38+
func = null
39+
}
3140
}
3241

33-
return field
42+
return f
3443
}
3544

3645
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) {
3746
this.field = value
3847
}
3948

40-
private inner class Lock
49+
private class Lock
4150
}
4251

4352
fun <T> nullable(supplier: () -> T?): NullableDelegate<T> = NullableDelegate(supplier)

0 commit comments

Comments
 (0)