From 6a8a68a2631b4c91df5f5c1dfebdc3145081d865 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Thu, 9 Jan 2020 13:48:45 +0300 Subject: [PATCH] New J2K: fix UninitializedPropertyAccessException when calculating type of anonymous class #KT-35395 fixed --- .../kotlin/nj2k/types/JKTypeFactory.kt | 7 +++++++ .../AccesssThisInsideAnonClass.java | 15 +++++++++++++++ .../AccesssThisInsideAnonClass.kt | 13 +++++++++++++ .../AccesssThisInsideAnonClass2.java | 19 +++++++++++++++++++ .../AccesssThisInsideAnonClass2.kt | 19 +++++++++++++++++++ ...otlinConverterSingleFileTestGenerated.java | 10 ++++++++++ 6 files changed, 83 insertions(+) create mode 100644 nj2k/testData/newJ2k/objectLiteral/AccesssThisInsideAnonClass.java create mode 100644 nj2k/testData/newJ2k/objectLiteral/AccesssThisInsideAnonClass.kt create mode 100644 nj2k/testData/newJ2k/objectLiteral/AccesssThisInsideAnonClass2.java create mode 100644 nj2k/testData/newJ2k/objectLiteral/AccesssThisInsideAnonClass2.kt diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/types/JKTypeFactory.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/types/JKTypeFactory.kt index f6702f2eb58..81836f59e5c 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/types/JKTypeFactory.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/types/JKTypeFactory.kt @@ -78,6 +78,13 @@ class JKTypeFactory(val symbolProvider: JKSymbolProvider) { JKClassType(JKUnresolvedClassSymbol(type.rawType().canonicalText, this), parameters) is PsiTypeParameter -> JKTypeParameterType(symbolProvider.provideDirectSymbol(target) as JKTypeParameterSymbol) + is PsiAnonymousClass -> { + /* + If anonymous class is declared inside the converting code, we will not be able to access JKUniverseClassSymbol's target + And get UninitializedPropertyAccessException exception, so it is ok to use base class for now + */ + createPsiType(target.baseClassType) + } else -> { JKClassType( target.let { symbolProvider.provideDirectSymbol(it) as JKClassSymbol }, diff --git a/nj2k/testData/newJ2k/objectLiteral/AccesssThisInsideAnonClass.java b/nj2k/testData/newJ2k/objectLiteral/AccesssThisInsideAnonClass.java new file mode 100644 index 00000000000..3caca1087da --- /dev/null +++ b/nj2k/testData/newJ2k/objectLiteral/AccesssThisInsideAnonClass.java @@ -0,0 +1,15 @@ +interface Foo { +} + +public class Bar { + void test() { + new Foo() { + void foo() { + bug(this); + } + }; + } + + void bug(Foo foo) { + } +} \ No newline at end of file diff --git a/nj2k/testData/newJ2k/objectLiteral/AccesssThisInsideAnonClass.kt b/nj2k/testData/newJ2k/objectLiteral/AccesssThisInsideAnonClass.kt new file mode 100644 index 00000000000..6228ed5ab44 --- /dev/null +++ b/nj2k/testData/newJ2k/objectLiteral/AccesssThisInsideAnonClass.kt @@ -0,0 +1,13 @@ +// ERROR: 'public' function exposes its 'internal' parameter type Foo +internal interface Foo +class Bar { + fun test() { + object : Foo { + fun foo() { + bug(this) + } + } + } + + fun bug(foo: Foo?) {} +} diff --git a/nj2k/testData/newJ2k/objectLiteral/AccesssThisInsideAnonClass2.java b/nj2k/testData/newJ2k/objectLiteral/AccesssThisInsideAnonClass2.java new file mode 100644 index 00000000000..ff0d3da1823 --- /dev/null +++ b/nj2k/testData/newJ2k/objectLiteral/AccesssThisInsideAnonClass2.java @@ -0,0 +1,19 @@ +public class Foo { + + void fail() { + new Test.FrameCallback() { + public void doFrame() { + new Test().postFrameCallbackDelayed(this); + } + }; + } +} + +class Test { + public interface FrameCallback { + void doFrame(); + } + + void postFrameCallbackDelayed(Test.FrameCallback callback) { + } +} \ No newline at end of file diff --git a/nj2k/testData/newJ2k/objectLiteral/AccesssThisInsideAnonClass2.kt b/nj2k/testData/newJ2k/objectLiteral/AccesssThisInsideAnonClass2.kt new file mode 100644 index 00000000000..1aea6d76b49 --- /dev/null +++ b/nj2k/testData/newJ2k/objectLiteral/AccesssThisInsideAnonClass2.kt @@ -0,0 +1,19 @@ +import Test.FrameCallback + +class Foo { + fun fail() { + object : FrameCallback { + override fun doFrame() { + Test().postFrameCallbackDelayed(this) + } + } + } +} + +internal class Test { + interface FrameCallback { + fun doFrame() + } + + fun postFrameCallbackDelayed(callback: FrameCallback?) {} +} diff --git a/nj2k/tests/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverterSingleFileTestGenerated.java b/nj2k/tests/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverterSingleFileTestGenerated.java index cefebcfe5f3..638a6396e08 100644 --- a/nj2k/tests/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverterSingleFileTestGenerated.java +++ b/nj2k/tests/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverterSingleFileTestGenerated.java @@ -4027,6 +4027,16 @@ public class NewJavaToKotlinConverterSingleFileTestGenerated extends AbstractNew KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); } + @TestMetadata("AccesssThisInsideAnonClass.java") + public void testAccesssThisInsideAnonClass() throws Exception { + runTest("nj2k/testData/newJ2k/objectLiteral/AccesssThisInsideAnonClass.java"); + } + + @TestMetadata("AccesssThisInsideAnonClass2.java") + public void testAccesssThisInsideAnonClass2() throws Exception { + runTest("nj2k/testData/newJ2k/objectLiteral/AccesssThisInsideAnonClass2.java"); + } + public void testAllFilesPresentInObjectLiteral() throws Exception { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("nj2k/testData/newJ2k/objectLiteral"), Pattern.compile("^([^\\.]+)\\.java$"), null, true); }