Skip to content

Commit

Permalink
Merge branch 'refs/heads/2024.1' into 2024.2
Browse files Browse the repository at this point in the history
  • Loading branch information
RedNesto committed Jun 14, 2024
2 parents 7f4f185 + 96172b2 commit d4b39e6
Show file tree
Hide file tree
Showing 38 changed files with 1,201 additions and 66 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ kotlin.code.style=official
ideaVersion = 242.16677.21-EAP-SNAPSHOT
ideaVersionName = 2024.2

coreVersion = 1.7.5
coreVersion = 1.7.6
downloadIdeaSources = true

# Silences a build-time warning because we are bundling our own kotlin library
Expand Down
6 changes: 5 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ Minecraft Development for IntelliJ
<td align="left">2024.1</td>
<td align="left"><a href="https://ci.mcdev.io/viewType.html?buildTypeId=MinecraftDev_Nightly_20241"><img src="https://ci.mcdev.io/app/rest/builds/buildType:(id:MinecraftDev_Nightly_20241)/statusIcon.svg" alt="2024.1 Nightly Status" /></a></td>
</tr>
<tr>
<td align="left">2024.2</td>
<td align="left"><a href="https://ci.mcdev.io/viewType.html?buildTypeId=MinecraftDev_Nightly_20242"><img src="https://ci.mcdev.io/app/rest/builds/buildType:(id:MinecraftDev_Nightly_20242)/statusIcon.svg" alt="2024.2 Nightly Status" /></a></td>
</tr>
<tr>
<td align="right"><b>OS Tests</b></td>
<td align="left" colspan="2">
Expand All @@ -31,7 +35,7 @@ Minecraft Development for IntelliJ
</tr>
</table>

Info and Documentation [![Current Release](https://img.shields.io/badge/release-1.7.5-orange.svg?style=flat-square)](https://plugins.jetbrains.com/plugin/8327)
Info and Documentation [![Current Release](https://img.shields.io/badge/release-1.7.6-orange.svg?style=flat-square)](https://plugins.jetbrains.com/plugin/8327)
----------------------

<a href="https://discord.gg/j6UNcfr"><img src="https://i.imgur.com/JXu9C1G.png" height="48px"></img></a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import com.demonwav.mcdev.util.SemanticVersion
class BungeeMainPlatformStep(parent: BungeePlatformStep) : AbstractBungeePlatformStep(parent, PlatformType.BUNGEECORD) {
override fun getRepositories(mcVersion: SemanticVersion) = listOf(
BuildRepository("sonatype", "https://oss.sonatype.org/content/groups/public/"),
// Seems to be required since 1.21
BuildRepository("Minecraft Libraries", "https://libraries.minecraft.net/"),
)

override fun getDependencies(mcVersion: SemanticVersion) = listOf(
Expand Down
2 changes: 2 additions & 0 deletions src/main/kotlin/platform/forge/creator/asset-steps.kt
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ class ForgeProjectFilesStep(parent: NewProjectWizardStep) : AbstractLongRunningA
}

val mainClassTemplate = when {
mcVersion >= MinecraftVersions.MC1_20_6 -> MinecraftTemplates.FG3_1_20_6_MAIN_CLASS_TEMPLATE
mcVersion >= MinecraftVersions.MC1_20 -> MinecraftTemplates.FG3_1_20_MAIN_CLASS_TEMPLATE
mcVersion >= MinecraftVersions.MC1_19_3 -> MinecraftTemplates.FG3_1_19_3_MAIN_CLASS_TEMPLATE
mcVersion >= MinecraftVersions.MC1_19 -> MinecraftTemplates.FG3_1_19_MAIN_CLASS_TEMPLATE
Expand All @@ -124,6 +125,7 @@ class ForgeProjectFilesStep(parent: NewProjectWizardStep) : AbstractLongRunningA
)

val configTemplate = when {
mcVersion >= MinecraftVersions.MC1_21 -> MinecraftTemplates.FG3_1_21_CONFIG_TEMPLATE
mcVersion >= MinecraftVersions.MC1_20 -> MinecraftTemplates.FG3_1_20_CONFIG_TEMPLATE
else -> null
}
Expand Down
6 changes: 4 additions & 2 deletions src/main/kotlin/platform/forge/util/ForgePackDescriptor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ data class ForgePackDescriptor(val format: Int, val comment: String) {
val FORMAT_15 = ForgePackDescriptor(15, "")
val FORMAT_18 = ForgePackDescriptor(18, "")
val FORMAT_26 = ForgePackDescriptor(26, "")
val FORMAT_41 = ForgePackDescriptor(26, "")
val FORMAT_41 = ForgePackDescriptor(41, "")
val FORMAT_48 = ForgePackDescriptor(48, "")

// See https://minecraft.gamepedia.com/Tutorials/Creating_a_resource_pack#.22pack_format.22
fun forMcVersion(version: SemanticVersion): ForgePackDescriptor? = when {
Expand All @@ -71,7 +72,8 @@ data class ForgePackDescriptor(val format: Int, val comment: String) {
version < MinecraftVersions.MC1_20_2 -> FORMAT_15
version < MinecraftVersions.MC1_20_3 -> FORMAT_18
version < MinecraftVersions.MC1_20_5 -> FORMAT_26
version >= MinecraftVersions.MC1_20_5 -> FORMAT_41
version < MinecraftVersions.MC1_21 -> FORMAT_41
version >= MinecraftVersions.MC1_21 -> FORMAT_48
else -> null
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,19 +54,25 @@ import org.objectweb.asm.tree.MethodNode

abstract class InjectorAnnotationHandler : MixinAnnotationHandler {
override fun resolveTarget(annotation: PsiAnnotation, targetClass: ClassNode): List<MixinTargetMember> {
val targetClassMethods = targetClass.methods ?: return emptyList()

val methodAttr = annotation.findAttributeValue("method")
val method = methodAttr?.computeStringArray() ?: emptyList()
val desc = annotation.findAttributeValue("desc")?.findAnnotations() ?: emptyList()
val selectors = method.mapNotNull { parseMixinSelector(it, methodAttr!!) } +
desc.mapNotNull { DescSelectorParser.descSelectorFromAnnotation(it) }

return targetClassMethods.mapNotNull { targetMethod ->
if (selectors.any { it.matchMethod(targetMethod, targetClass) }) {
MethodTargetMember(targetClass, targetMethod)
} else {
null
val targetClassMethods = selectors.associateWith { selector ->
val actualTarget = selector.getCustomOwner(targetClass)
(actualTarget to actualTarget.methods)
}

return targetClassMethods.mapNotNull { (selector, pair) ->
val (clazz, methods) = pair
methods.firstNotNullOfOrNull { method ->
if (selector.matchMethod(method, clazz)) {
MethodTargetMember(clazz, method)
} else {
null
}
}
}
}
Expand Down Expand Up @@ -99,7 +105,7 @@ abstract class InjectorAnnotationHandler : MixinAnnotationHandler {
override fun resolveForNavigation(annotation: PsiAnnotation, targetClass: ClassNode): List<PsiElement> {
return resolveTarget(annotation, targetClass).flatMap { targetMember ->
val targetMethod = targetMember as? MethodTargetMember ?: return@flatMap emptyList()
resolveForNavigation(annotation, targetClass, targetMethod.classAndMethod.method)
resolveForNavigation(annotation, targetMethod.classAndMethod.clazz, targetMethod.classAndMethod.method)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

package com.demonwav.mcdev.platform.mixin.handlers.injectionPoint

import com.demonwav.mcdev.platform.mixin.reference.MixinSelector
import com.demonwav.mcdev.platform.mixin.reference.isMiscDynamicSelector
import com.demonwav.mcdev.platform.mixin.reference.parseMixinSelector
import com.demonwav.mcdev.platform.mixin.reference.target.TargetReference
Expand Down Expand Up @@ -152,7 +153,7 @@ class AtResolver(
val collectVisitor = injectionPoint.createCollectVisitor(
at,
target,
targetClass,
getTargetClass(target),
CollectVisitor.Mode.MATCH_FIRST,
)
if (collectVisitor == null) {
Expand Down Expand Up @@ -181,7 +182,7 @@ class AtResolver(
val targetAttr = at.findAttributeValue("target")
val target = targetAttr?.let { parseMixinSelector(it) }

val collectVisitor = injectionPoint.createCollectVisitor(at, target, targetClass, mode)
val collectVisitor = injectionPoint.createCollectVisitor(at, target, getTargetClass(target), mode)
?: return InsnResolutionInfo.Failure()
collectVisitor.visit(targetMethod)
val result = collectVisitor.result
Expand All @@ -201,7 +202,7 @@ class AtResolver(

// Then attempt to find the corresponding source elements using the navigation visitor
val targetElement = targetMethod.findSourceElement(
targetClass,
getTargetClass(target),
at.project,
GlobalSearchScope.allScope(at.project),
canDecompile = true,
Expand All @@ -223,16 +224,23 @@ class AtResolver(

// Collect all possible targets
fun <T : PsiElement> doCollectVariants(injectionPoint: InjectionPoint<T>): List<Any> {
val visitor = injectionPoint.createCollectVisitor(at, target, targetClass, CollectVisitor.Mode.COMPLETION)
val visitor = injectionPoint.createCollectVisitor(
at, target, getTargetClass(target),
CollectVisitor.Mode.COMPLETION
)
?: return emptyList()
visitor.visit(targetMethod)
return visitor.result
.mapNotNull { result ->
injectionPoint.createLookup(targetClass, result)?.let { completionHandler(it) }
injectionPoint.createLookup(getTargetClass(target), result)?.let { completionHandler(it) }
}
}
return doCollectVariants(injectionPoint)
}

private fun getTargetClass(selector: MixinSelector?): ClassNode {
return selector?.getCustomOwner(targetClass) ?: targetClass
}
}

sealed class InsnResolutionInfo {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Minecraft Development for IntelliJ
*
* https://mcdev.io/
*
* Copyright (C) 2024 minecraft-dev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, version 3.0 only.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package com.demonwav.mcdev.platform.mixin.handlers.mixinextras

import com.demonwav.mcdev.platform.mixin.handlers.InjectorAnnotationHandler
import com.demonwav.mcdev.platform.mixin.handlers.injectionPoint.InsnResolutionInfo
import com.demonwav.mcdev.platform.mixin.inspection.injector.MethodSignature
import com.demonwav.mcdev.platform.mixin.inspection.injector.ParameterGroup
import com.demonwav.mcdev.platform.mixin.util.findSourceElement
import com.demonwav.mcdev.platform.mixin.util.getGenericReturnType
import com.demonwav.mcdev.platform.mixin.util.mixinExtrasOperationType
import com.demonwav.mcdev.util.Parameter
import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiElement
import com.intellij.psi.search.GlobalSearchScope
import org.objectweb.asm.tree.ClassNode
import org.objectweb.asm.tree.MethodNode

class WrapMethodHandler : InjectorAnnotationHandler() {
override fun expectedMethodSignature(
annotation: PsiAnnotation,
targetClass: ClassNode,
targetMethod: MethodNode,
): List<MethodSignature> {
val returnType = targetMethod.getGenericReturnType(targetClass, annotation.project)

return listOf(
MethodSignature(
listOf(
ParameterGroup(
collectTargetMethodParameters(annotation.project, targetClass, targetMethod) +
Parameter(
"original",
mixinExtrasOperationType(annotation, returnType) ?: return emptyList()
),
)
),
returnType
)
)
}

override fun isUnresolved(
annotation: PsiAnnotation,
targetClass: ClassNode,
targetMethod: MethodNode
): InsnResolutionInfo.Failure? {
// If we've got a target method that's good enough
return null
}

override fun resolveForNavigation(
annotation: PsiAnnotation,
targetClass: ClassNode,
targetMethod: MethodNode
): List<PsiElement> {
val project = annotation.project
return targetMethod.findSourceElement(
targetClass,
project,
GlobalSearchScope.allScope(project),
canDecompile = true
)?.let(::listOf).orEmpty()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,9 @@
package com.demonwav.mcdev.platform.mixin.handlers.mixinextras

import com.demonwav.mcdev.platform.mixin.inspection.injector.ParameterGroup
import com.demonwav.mcdev.platform.mixin.util.MixinConstants.MixinExtras.OPERATION
import com.demonwav.mcdev.platform.mixin.util.mixinExtrasOperationType
import com.demonwav.mcdev.util.Parameter
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiPrimitiveType
import com.intellij.psi.PsiType
import org.objectweb.asm.tree.AbstractInsnNode
import org.objectweb.asm.tree.ClassNode
Expand All @@ -50,21 +47,9 @@ class WrapOperationHandler : MixinExtrasInjectorAnnotationHandler() {
): Pair<ParameterGroup, PsiType>? {
val params = getPsiParameters(insn, targetClass, annotation) ?: return null
val returnType = getPsiReturnType(insn, annotation) ?: return null
val operationType = getOperationType(annotation, returnType) ?: return null
val operationType = mixinExtrasOperationType(annotation, returnType) ?: return null
return ParameterGroup(
params + Parameter("original", operationType)
) to returnType
}

private fun getOperationType(context: PsiElement, type: PsiType): PsiType? {
val project = context.project
val boxedType = if (type is PsiPrimitiveType) {
type.getBoxedType(context) ?: return null
} else {
type
}

return JavaPsiFacade.getElementFactory(project)
.createTypeFromText("$OPERATION<${boxedType.canonicalText}>", context)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import com.intellij.psi.PsiModifier
class StaticMemberInspection : MixinInspection() {

override fun getStaticDescription() =
"A mixin class does not exist at runtime, and thus having them public does not make sense. " +
"A mixin class does not exist at runtime, and thus having them not private does not make sense. " +
"Make the field/method private instead."

override fun buildVisitor(holder: ProblemsHolder): PsiElementVisitor = Visitor(holder)
Expand All @@ -56,7 +56,7 @@ class StaticMemberInspection : MixinInspection() {
if (isProblematic(member)) {
holder.registerProblem(
member,
"Public static members are not allowed in Mixin classes",
"Non-private static members are not allowed in Mixin classes",
QuickFixFactory.getInstance().createModifierListFix(member, PsiModifier.PRIVATE, true, false),
)
}
Expand All @@ -70,7 +70,7 @@ class StaticMemberInspection : MixinInspection() {

val modifiers = member.modifierList!!

return modifiers.hasModifierProperty(PsiModifier.PUBLIC) &&
return !modifiers.hasModifierProperty(PsiModifier.PRIVATE) &&
modifiers.hasModifierProperty(PsiModifier.STATIC) &&
modifiers.findAnnotation(SHADOW) == null &&
modifiers.findAnnotation(OVERWRITE) == null &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ class WrongOperationParametersInspection : MixinInspection() {
PsiField::class.java
) ?: return

if (!containingMethod.hasAnnotation(MixinConstants.MixinExtras.WRAP_OPERATION)) {
if (!containingMethod.hasAnnotation(MixinConstants.MixinExtras.WRAP_OPERATION) &&
!containingMethod.hasAnnotation(MixinConstants.MixinExtras.WRAP_METHOD)
) {
return
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ abstract class AbstractMethodReference : PolyReferenceResolver(), MixinReference
val stringValue = context.constantStringValue ?: return false
val targetMethodInfo = parseSelector(stringValue, context) ?: return false
val targets = getTargets(context) ?: return false
return !targets.asSequence().flatMap { it.findMethods(targetMethodInfo) }.any()
return !targets.asSequence().flatMap {
targetMethodInfo.getCustomOwner(it).findMethods(targetMethodInfo)
}.any()
}

fun getReferenceIfAmbiguous(context: PsiElement): MemberReference? {
Expand Down Expand Up @@ -125,7 +127,10 @@ abstract class AbstractMethodReference : PolyReferenceResolver(), MixinReference
selector: MixinSelector,
): Sequence<ClassAndMethodNode> {
return targets.asSequence()
.flatMap { target -> target.findMethods(selector).map { ClassAndMethodNode(target, it) } }
.flatMap { target ->
val actualTarget = selector.getCustomOwner(target)
actualTarget.findMethods(selector).map { ClassAndMethodNode(actualTarget, it) }
}
}

fun resolveIfUnique(context: PsiElement): ClassAndMethodNode? {
Expand Down
Loading

0 comments on commit d4b39e6

Please sign in to comment.