Skip to content

Commit 846c49f

Browse files
RedNestoDenWav
authored andcommitted
Properly handle ctor of mixed in inner classes
1 parent 3609ff8 commit 846c49f

File tree

2 files changed

+142
-0
lines changed

2 files changed

+142
-0
lines changed

src/main/kotlin/com/demonwav/mcdev/platform/mixin/inspection/injector/InjectorType.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import com.demonwav.mcdev.platform.mixin.util.callbackInfoType
1818
import com.demonwav.mcdev.util.Parameter
1919
import com.demonwav.mcdev.util.constantStringValue
2020
import com.demonwav.mcdev.util.constantValue
21+
import com.intellij.lang.jvm.JvmModifier
2122
import com.intellij.psi.JavaPsiFacade
2223
import com.intellij.psi.PsiAnnotation
2324
import com.intellij.psi.PsiAnnotationOwner
@@ -38,6 +39,16 @@ enum class InjectorType(private val annotation: String) {
3839

3940
val result = ArrayList<ParameterGroup>()
4041

42+
if (targetMethod.isConstructor) {
43+
val containingClass = targetMethod.containingClass
44+
val outerClass = containingClass?.containingClass
45+
if (outerClass != null && !containingClass.hasModifier(JvmModifier.STATIC)) {
46+
val outerClassType = JavaPsiFacade.getElementFactory(outerClass.project).createType(outerClass)
47+
// Inner classes ctors take their outer class as first parameter (required)
48+
result.add(ParameterGroup(listOf(Parameter("outer", outerClassType))))
49+
}
50+
}
51+
4152
// Parameters from injected method (optional)
4253
result.add(ParameterGroup(collectTargetMethodParameters(targetMethod), required = false, default = true))
4354

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/*
2+
* Minecraft Dev for IntelliJ
3+
*
4+
* https://minecraftdev.org
5+
*
6+
* Copyright (c) 2020 minecraft-dev
7+
*
8+
* MIT License
9+
*/
10+
11+
package com.demonwav.mcdev.platform.mixin
12+
13+
import com.demonwav.mcdev.framework.EdtInterceptor
14+
import com.demonwav.mcdev.platform.mixin.inspection.injector.InvalidInjectorMethodSignatureInspection
15+
import org.intellij.lang.annotations.Language
16+
import org.junit.jupiter.api.DisplayName
17+
import org.junit.jupiter.api.Test
18+
import org.junit.jupiter.api.extension.ExtendWith
19+
20+
@ExtendWith(EdtInterceptor::class)
21+
@DisplayName("Invalid Injector Method Signature Inspection Test")
22+
class InvalidInjectorMethodSignatureInspectionTest : BaseMixinTest() {
23+
24+
private fun doTest(@Language("JAVA") code: String) {
25+
buildProject {
26+
dir("test") {
27+
java(
28+
"MixedInOuter.java",
29+
"""
30+
package test;
31+
32+
import java.lang.String;
33+
34+
class MixedInOuter {
35+
public class MixedInInner {
36+
public MixedInInner() {
37+
}
38+
39+
public MixedInInner(String string) {
40+
}
41+
}
42+
43+
public static class MixedInStaticInner {
44+
public MixedInStaticInner() {
45+
}
46+
47+
public MixedInStaticInner(String string) {
48+
}
49+
}
50+
}
51+
""",
52+
configure = false
53+
)
54+
java("TestMixin.java", code)
55+
}
56+
}
57+
58+
fixture.enableInspections(InvalidInjectorMethodSignatureInspection::class)
59+
fixture.checkHighlighting(false, false, false)
60+
}
61+
62+
@Test
63+
@DisplayName("Inner Ctor @Inject Parameters")
64+
fun innerCtorInjectParameters() {
65+
doTest(
66+
"""
67+
package test;
68+
69+
import org.spongepowered.asm.mixin.Mixin;
70+
import org.spongepowered.asm.mixin.injection.At;
71+
import org.spongepowered.asm.mixin.injection.Inject;
72+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
73+
74+
@Mixin(MixedInOuter.MixedInInner.class)
75+
public class TestMixin {
76+
77+
@Inject(method = "<init>", at = @At("RETURN"))
78+
private void injectCtor(MixedInOuter outer, CallbackInfo ci) {
79+
}
80+
81+
@Inject(method = "<init>", at = @At("RETURN"))
82+
private void injectCtor<error descr="Method parameters do not match expected parameters for @Inject">(CallbackInfo ci)</error> {
83+
}
84+
85+
@Inject(method = "<init>(Ljava/lang/String;)V", at = @At("RETURN"))
86+
private void injectCtor(MixedInOuter outer, String string, CallbackInfo ci) {
87+
}
88+
89+
@Inject(method = "<init>(Ljava/lang/String;)V", at = @At("RETURN"))
90+
private void injectCtor<error descr="Method parameters do not match expected parameters for @Inject">(String string, CallbackInfo ci)</error> {
91+
}
92+
}
93+
"""
94+
)
95+
}
96+
97+
@Test
98+
@DisplayName("Static Inner Ctor @Inject Parameters")
99+
fun staticInnerCtorInjectParameters() {
100+
doTest(
101+
"""
102+
package test;
103+
104+
import org.spongepowered.asm.mixin.Mixin;
105+
import org.spongepowered.asm.mixin.injection.At;
106+
import org.spongepowered.asm.mixin.injection.Inject;
107+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
108+
109+
@Mixin(MixedInOuter.MixedInStaticInner.class)
110+
public class TestMixin {
111+
112+
@Inject(method = "<init>", at = @At("RETURN"))
113+
private void injectCtor<error descr="Method parameters do not match expected parameters for @Inject">(MixedInOuter outer, CallbackInfo ci)</error> {
114+
}
115+
116+
@Inject(method = "<init>", at = @At("RETURN"))
117+
private void injectCtor(CallbackInfo ci) {
118+
}
119+
120+
@Inject(method = "<init>(Ljava/lang/String;)V", at = @At("RETURN"))
121+
private void injectCtor<error descr="Method parameters do not match expected parameters for @Inject">(MixedInOuter outer, String string, CallbackInfo ci)</error> {
122+
}
123+
124+
@Inject(method = "<init>(Ljava/lang/String;)V", at = @At("RETURN"))
125+
private void injectCtor(String string, CallbackInfo ci) {
126+
}
127+
}
128+
"""
129+
)
130+
}
131+
}

0 commit comments

Comments
 (0)