From a1d88a087726ffd2aa34478c0ae941334f35ad00 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Mon, 20 Feb 2012 22:37:06 +0400 Subject: [PATCH] recognize @NotNull http://youtrack.jetbrains.com/issue/KT-129 --- .../resolve/java/JavaDescriptorResolver.java | 18 +++++++++++++++--- .../java/JavaDescriptorResolverHelper.java | 10 +++++----- .../jet/lang/resolve/java/JvmAbi.java | 2 ++ .../jet/lang/resolve/java/TypeSource.java | 11 ++++++++++- .../notNull/NotNullField.java | 8 ++++++++ .../notNull/NotNullField.kt | 5 +++++ .../notNull/NotNullField.txt | 6 ++++++ .../notNull/NotNullMethod.java | 8 ++++++++ .../notNull/NotNullMethod.kt | 5 +++++ .../notNull/NotNullMethod.txt | 6 ++++++ .../notNull/NotNullParameter.java | 7 +++++++ .../notNull/NotNullParameter.kt | 5 +++++ .../notNull/NotNullParameter.txt | 6 ++++++ .../jet/compiler/ReadJavaBinaryClassTest.java | 2 +- 14 files changed, 89 insertions(+), 10 deletions(-) create mode 100644 compiler/testData/readJavaBinaryClass/notNull/NotNullField.java create mode 100644 compiler/testData/readJavaBinaryClass/notNull/NotNullField.kt create mode 100644 compiler/testData/readJavaBinaryClass/notNull/NotNullField.txt create mode 100644 compiler/testData/readJavaBinaryClass/notNull/NotNullMethod.java create mode 100644 compiler/testData/readJavaBinaryClass/notNull/NotNullMethod.kt create mode 100644 compiler/testData/readJavaBinaryClass/notNull/NotNullMethod.txt create mode 100644 compiler/testData/readJavaBinaryClass/notNull/NotNullParameter.java create mode 100644 compiler/testData/readJavaBinaryClass/notNull/NotNullParameter.kt create mode 100644 compiler/testData/readJavaBinaryClass/notNull/NotNullParameter.txt diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index 3f3d9f550f3..5454b65abfa 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -879,8 +879,6 @@ public class JavaDescriptorResolver { PsiType psiType = parameter.getPsiParameter().getType(); - boolean nullable = parameter.getJetValueParameter().nullable(); - // TODO: must be very slow, make it lazy? String name = parameter.getPsiParameter().getName() != null ? parameter.getPsiParameter().getName() : "p" + i; @@ -909,13 +907,22 @@ public class JavaDescriptorResolver { if (receiver) { return JvmMethodParameterMeaning.receiver(outType); } else { + + JetType transformedType; + if (parameter.getJetValueParameter().nullable()) { + transformedType = TypeUtils.makeNullableAsSpecified(outType, parameter.getJetValueParameter().nullable()); + } else if (parameter.getPsiParameter().getModifierList().findAnnotation(JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName()) != null) { + transformedType = TypeUtils.makeNullableAsSpecified(outType, false); + } else { + transformedType = outType; + } return JvmMethodParameterMeaning.regular(new ValueParameterDescriptorImpl( containingDeclaration, i, Collections.emptyList(), // TODO name, false, - nullable ? TypeUtils.makeNullableAsSpecified(outType, nullable) : outType, + transformedType, hasDefaultValue, varargElementType )); @@ -1142,6 +1149,9 @@ public class JavaDescriptorResolver { propertyType = semanticServices.getTypeTransformer().transformToType(anyMember.getType().getTypeString(), typeVariableResolverForPropertyInternals); } else { propertyType = semanticServices.getTypeTransformer().transformToType(anyMember.getType().getPsiType(), typeVariableResolverForPropertyInternals); + if (anyMember.getType().getPsiNotNullOwner().getModifierList().findAnnotation(JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName()) != null) { + propertyType = TypeUtils.makeNullableAsSpecified(propertyType, false); + } } JetType receiverType; @@ -1491,6 +1501,8 @@ public class JavaDescriptorResolver { } if (method.getJetMethod().returnTypeNullable()) { return TypeUtils.makeNullableAsSpecified(transformedType, true); + } else if (method.getPsiMethod().getModifierList().findAnnotation(JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName()) != null) { + return TypeUtils.makeNullableAsSpecified(transformedType, false); } else { return transformedType; } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolverHelper.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolverHelper.java index 5312df706de..f0c3c29e904 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolverHelper.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolverHelper.java @@ -88,7 +88,7 @@ class JavaDescriptorResolverHelper { NamedMembers namedMembers = getNamedMembers(field.getName()); - TypeSource type = new TypeSource("", field.getType()); + TypeSource type = new TypeSource("", field.getType(), field0); namedMembers.addPropertyAccessor(new PropertyAccessorData(field, type, null)); } } @@ -124,7 +124,7 @@ class JavaDescriptorResolverHelper { TypeSource receiverType; if (i < method.getParameters().size() && method.getParameter(i).getJetValueParameter().receiver()) { PsiParameterWrapper receiverParameter = method.getParameter(i); - receiverType = new TypeSource(receiverParameter.getJetValueParameter().type(), receiverParameter.getPsiParameter().getType()); + receiverType = new TypeSource(receiverParameter.getJetValueParameter().type(), receiverParameter.getPsiParameter().getType(), receiverParameter.getPsiParameter()); ++i; } else { receiverType = null; @@ -144,7 +144,7 @@ class JavaDescriptorResolverHelper { NamedMembers members = getNamedMembers(propertyName); // TODO: what if returnType == null? - TypeSource propertyType = new TypeSource(method.getJetMethod().propertyType(), method.getReturnType()); + TypeSource propertyType = new TypeSource(method.getJetMethod().propertyType(), method.getReturnType(), method.getPsiMethod()); members.addPropertyAccessor(new PropertyAccessorData(method, true, propertyType, receiverType)); } @@ -161,7 +161,7 @@ class JavaDescriptorResolverHelper { TypeSource receiverType = null; PsiParameterWrapper p1 = method.getParameter(0); if (p1.getJetValueParameter().receiver()) { - receiverType = new TypeSource(p1.getJetValueParameter().type(), p1.getPsiParameter().getType()); + receiverType = new TypeSource(p1.getJetValueParameter().type(), p1.getPsiParameter().getType(), p1.getPsiParameter()); ++i; } @@ -174,7 +174,7 @@ class JavaDescriptorResolverHelper { } PsiParameterWrapper propertyTypeParameter = method.getParameter(i); - TypeSource propertyType = new TypeSource(method.getJetMethod().propertyType(), propertyTypeParameter.getPsiParameter().getType()); + TypeSource propertyType = new TypeSource(method.getJetMethod().propertyType(), propertyTypeParameter.getPsiParameter().getType(), propertyTypeParameter.getPsiParameter()); String propertyName = StringUtil.decapitalize(method.getName().substring(JvmAbi.SETTER_PREFIX.length())); NamedMembers members = getNamedMembers(propertyName); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmAbi.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmAbi.java index 04656657f1e..d6678d76a9d 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmAbi.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmAbi.java @@ -27,4 +27,6 @@ public class JvmAbi { public static final String PACKAGE_CLASS = "namespace"; public static final String SET_TYPE_INFO_METHOD = "$setTypeInfo"; public static final String TYPE_INFO_FIELD = "$typeInfo"; + + public static final JvmClassName JETBRAINS_NOT_NULL_ANNOTATION = new JvmClassName("org.jetbrains.annotations.NotNull"); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeSource.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeSource.java index 4c8e828e1ab..c33522c78f5 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeSource.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeSource.java @@ -16,6 +16,7 @@ package org.jetbrains.jet.lang.resolve.java; +import com.intellij.psi.PsiModifierListOwner; import com.intellij.psi.PsiType; import org.jetbrains.annotations.NotNull; @@ -28,10 +29,13 @@ class TypeSource { private final String typeString; @NotNull private final PsiType psiType; + @NotNull + private final PsiModifierListOwner psiNotNullOwner; - TypeSource(@NotNull String typeString, @NotNull PsiType psiType) { + TypeSource(@NotNull String typeString, @NotNull PsiType psiType, @NotNull PsiModifierListOwner psiNotNullOwner) { this.typeString = typeString; this.psiType = psiType; + this.psiNotNullOwner = psiNotNullOwner; } @NotNull @@ -43,4 +47,9 @@ class TypeSource { public PsiType getPsiType() { return psiType; } + + @NotNull + public PsiModifierListOwner getPsiNotNullOwner() { + return psiNotNullOwner; + } } diff --git a/compiler/testData/readJavaBinaryClass/notNull/NotNullField.java b/compiler/testData/readJavaBinaryClass/notNull/NotNullField.java new file mode 100644 index 00000000000..d566dfc711a --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/notNull/NotNullField.java @@ -0,0 +1,8 @@ +package test; + +import org.jetbrains.annotations.NotNull; + +class NotNullField { + @NotNull + public String hi; +} diff --git a/compiler/testData/readJavaBinaryClass/notNull/NotNullField.kt b/compiler/testData/readJavaBinaryClass/notNull/NotNullField.kt new file mode 100644 index 00000000000..6dfa0e5bb24 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/notNull/NotNullField.kt @@ -0,0 +1,5 @@ +package test; + +open class NotNullField() { + var hi: String = ""; +} diff --git a/compiler/testData/readJavaBinaryClass/notNull/NotNullField.txt b/compiler/testData/readJavaBinaryClass/notNull/NotNullField.txt new file mode 100644 index 00000000000..b8cd3fff1ef --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/notNull/NotNullField.txt @@ -0,0 +1,6 @@ +namespace test + +open class test.NotNullField : jet.Any { + final /*constructor*/ fun (): test.NotNullField + var hi: jet.String +} diff --git a/compiler/testData/readJavaBinaryClass/notNull/NotNullMethod.java b/compiler/testData/readJavaBinaryClass/notNull/NotNullMethod.java new file mode 100644 index 00000000000..b7c571baa71 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/notNull/NotNullMethod.java @@ -0,0 +1,8 @@ +package test; + +import org.jetbrains.annotations.NotNull; + +class NotNullMethod { + @NotNull + public String hi() { return ""; } +} diff --git a/compiler/testData/readJavaBinaryClass/notNull/NotNullMethod.kt b/compiler/testData/readJavaBinaryClass/notNull/NotNullMethod.kt new file mode 100644 index 00000000000..2c990004363 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/notNull/NotNullMethod.kt @@ -0,0 +1,5 @@ +package test + +open class NotNullMethod() { + open fun hi(): String = "" +} diff --git a/compiler/testData/readJavaBinaryClass/notNull/NotNullMethod.txt b/compiler/testData/readJavaBinaryClass/notNull/NotNullMethod.txt new file mode 100644 index 00000000000..133095788df --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/notNull/NotNullMethod.txt @@ -0,0 +1,6 @@ +namespace test + +open class test.NotNullMethod : jet.Any { + final /*constructor*/ fun (): test.NotNullMethod + open fun hi(): jet.String +} diff --git a/compiler/testData/readJavaBinaryClass/notNull/NotNullParameter.java b/compiler/testData/readJavaBinaryClass/notNull/NotNullParameter.java new file mode 100644 index 00000000000..c065983340f --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/notNull/NotNullParameter.java @@ -0,0 +1,7 @@ +package test; + +import org.jetbrains.annotations.NotNull; + +class NotNullParameter { + public void hi(@NotNull String param) { } +} diff --git a/compiler/testData/readJavaBinaryClass/notNull/NotNullParameter.kt b/compiler/testData/readJavaBinaryClass/notNull/NotNullParameter.kt new file mode 100644 index 00000000000..ec1fc244b00 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/notNull/NotNullParameter.kt @@ -0,0 +1,5 @@ +package test + +open class NotNullParameter() { + open fun hi(p0: String): Unit { } +} diff --git a/compiler/testData/readJavaBinaryClass/notNull/NotNullParameter.txt b/compiler/testData/readJavaBinaryClass/notNull/NotNullParameter.txt new file mode 100644 index 00000000000..c9ebf840789 --- /dev/null +++ b/compiler/testData/readJavaBinaryClass/notNull/NotNullParameter.txt @@ -0,0 +1,6 @@ +namespace test + +open class test.NotNullParameter : jet.Any { + final /*constructor*/ fun (): test.NotNullParameter + open fun hi(/*0*/ p0: jet.String): jet.Tuple0 +} diff --git a/compiler/tests/org/jetbrains/jet/compiler/ReadJavaBinaryClassTest.java b/compiler/tests/org/jetbrains/jet/compiler/ReadJavaBinaryClassTest.java index 092b95e27a7..5f16df365b6 100644 --- a/compiler/tests/org/jetbrains/jet/compiler/ReadJavaBinaryClassTest.java +++ b/compiler/tests/org/jetbrains/jet/compiler/ReadJavaBinaryClassTest.java @@ -97,7 +97,7 @@ public class ReadJavaBinaryClassTest extends TestCaseWithTmpdir { try { Iterable javaFileObjectsFromFiles = fileManager.getJavaFileObjectsFromFiles(Collections.singleton(javaFile)); List options = Arrays.asList( - "-classpath", "out/production/stdlib", + "-classpath", "out/production/stdlib:ideaSDK/lib/annotations.jar", "-d", tmpdir.getPath() ); JavaCompiler.CompilationTask task = javaCompiler.getTask(null, fileManager, null, options, null, javaFileObjectsFromFiles);