提交 8c8ed3a1 编写于 作者: S Stepan Koltsov

KT-1388 Parse static final fields from java binary classes as non-null

#KT-1388 Fixed
上级 ae58c1c8
...@@ -1368,6 +1368,10 @@ public class JavaDescriptorResolver { ...@@ -1368,6 +1368,10 @@ public class JavaDescriptorResolver {
if (anyMember.getType().getPsiNotNullOwner().getModifierList().findAnnotation(JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName()) != null) { if (anyMember.getType().getPsiNotNullOwner().getModifierList().findAnnotation(JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName()) != null) {
propertyType = TypeUtils.makeNullableAsSpecified(propertyType, false); propertyType = TypeUtils.makeNullableAsSpecified(propertyType, false);
} }
else if (members.getter == null && members.setter == null && members.field.getMember().isFinal() && members.field.getMember().isStatic()) {
// http://youtrack.jetbrains.com/issue/KT-1388
propertyType = TypeUtils.makeNotNullable(propertyType);
}
} }
JetType receiverType; JetType receiverType;
......
...@@ -151,9 +151,9 @@ fun html(init : HTML.() -> Unit) : HTML { ...@@ -151,9 +151,9 @@ fun html(init : HTML.() -> Unit) : HTML {
fun <K, V> Map<K, V>.set(key : K, value : V) = this.put(key, value) fun <K, V> Map<K, V>.set(key : K, value : V) = this.put(key, value)
fun println(message : Any?) { fun println(message : Any?) {
System.out?.println(message) System.out.println(message)
} }
fun print(message : Any?) { fun print(message : Any?) {
System.out?.print(message) System.out.print(message)
} }
...@@ -26,6 +26,6 @@ val d = b.<!UNRESOLVED_REFERENCE!>x<!> ...@@ -26,6 +26,6 @@ val d = b.<!UNRESOLVED_REFERENCE!>x<!>
val s = <!NO_CLASS_OBJECT!>System<!> // error val s = <!NO_CLASS_OBJECT!>System<!> // error
fun test() { fun test() {
System.out?.println() System.out.println()
java.lang.System.out?.println() java.lang.System.out.println()
} }
...@@ -8,8 +8,8 @@ fun test() { ...@@ -8,8 +8,8 @@ fun test() {
a?.plus(1) a?.plus(1)
} }
val out : java.io.PrintStream? = null//= System.out val out : java.io.PrintStream? = null
val ins = System.`in` val ins : java.io.InputStream? = null
out?.println() out?.println()
ins?.read() ins?.read()
......
...@@ -35,7 +35,7 @@ fun test(<!UNUSED_PARAMETER!>l<!> : java.util.List<Int>) { ...@@ -35,7 +35,7 @@ fun test(<!UNUSED_PARAMETER!>l<!> : java.util.List<Int>) {
// ... // ...
} }
catch(e: Exception) { catch(e: Exception) {
System.out?.println(e.getMessage()) System.out.println(e.getMessage())
} }
PrintStream("sdf") PrintStream("sdf")
......
...@@ -22,10 +22,10 @@ fun main(args : Array<String>) { ...@@ -22,10 +22,10 @@ fun main(args : Array<String>) {
test(al, m) test(al, m)
} }
fun test(a : List<Int>, m : Map<String, Int>) { fun test(a : List<Int>, m : Map<String, Int>) {
System.out?.println( System.out.println(
a.get(0) + 1 a.get(0) + 1
) )
HashMap<Int, Int>().get(0) HashMap<Int, Int>().get(0)
if (m.get("") != null) if (m.get("") != null)
System.out?.println(m.get("").sure().plus(1)) System.out.println(m.get("").sure().plus(1))
} }
...@@ -3,5 +3,5 @@ ...@@ -3,5 +3,5 @@
fun foo(maybe: Int?) { fun foo(maybe: Int?) {
val i : Int = maybe ?: throw RuntimeException("No value") val i : Int = maybe ?: throw RuntimeException("No value")
System.out?.println(i) System.out.println(i)
} }
...@@ -15,7 +15,7 @@ fun foo(){ ...@@ -15,7 +15,7 @@ fun foo(){
} }
bar() bar()
System.out?.println(local) System.out.println(local)
} }
fun <T> Iterable<T>.foreach(operation: (element: T) -> Unit) { fun <T> Iterable<T>.foreach(operation: (element: T) -> Unit) {
......
...@@ -9,7 +9,7 @@ fun main(args : Array<String>) { ...@@ -9,7 +9,7 @@ fun main(args : Array<String>) {
2 -> i = 2 // i is surrounded by a black border 2 -> i = 2 // i is surrounded by a black border
else -> <!UNRESOLVED_REFERENCE!>j<!> = 2 else -> <!UNRESOLVED_REFERENCE!>j<!> = 2
} }
System.out?.println(i) System.out.println(i)
} }
//KT-351 Distinguish statement and expression positions //KT-351 Distinguish statement and expression positions
......
...@@ -57,7 +57,7 @@ import outer.* ...@@ -57,7 +57,7 @@ import outer.*
fun main(args: Array<String>) { fun main(args: Array<String>) {
System.out?.print(1) System.out.print(1)
val command = parse("") val command = parse("")
......
...@@ -23,6 +23,6 @@ fun <T : Any> T?.iterator() = object { ...@@ -23,6 +23,6 @@ fun <T : Any> T?.iterator() = object {
fun main(args : Array<String>) { fun main(args : Array<String>) {
val i : Int? = 1 val i : Int? = 1
for (x in i) { for (x in i) {
System.out?.println(x) System.out.println(x)
} }
} }
...@@ -7,7 +7,7 @@ fun f(s: String?) { ...@@ -7,7 +7,7 @@ fun f(s: String?) {
if (s != null) { if (s != null) {
s.length //ok s.length //ok
var <!UNUSED_VARIABLE!>i<!> = s.length //error: Only safe calls are allowed on a nullable receiver var <!UNUSED_VARIABLE!>i<!> = s.length //error: Only safe calls are allowed on a nullable receiver
System.out?.println(s.length) //error System.out.println(s.length) //error
} }
} }
......
...@@ -39,7 +39,7 @@ fun evaluate(expr: StringBuilder, numbers: ArrayList<Int>): Int { ...@@ -39,7 +39,7 @@ fun evaluate(expr: StringBuilder, numbers: ArrayList<Int>): Int {
} }
fun main(args: Array<String>) { fun main(args: Array<String>) {
System.out?.println("24 game") System.out.println("24 game")
val numbers = ArrayList<Int>(4) val numbers = ArrayList<Int>(4)
val rnd = Random(); val rnd = Random();
val prompt = StringBuilder() val prompt = StringBuilder()
...@@ -49,18 +49,18 @@ fun main(args: Array<String>) { ...@@ -49,18 +49,18 @@ fun main(args: Array<String>) {
if (i > 0) prompt.append(" "); if (i > 0) prompt.append(" ");
prompt.append(n) prompt.append(n)
} }
System.out?.println("Your numbers: " + prompt) System.out.println("Your numbers: " + prompt)
System.out?.println("Enter your expression:") System.out.println("Enter your expression:")
val reader = BufferedReader(InputStreamReader(System.`in`)) val reader = BufferedReader(InputStreamReader(System.`in`))
val expr = StringBuilder(reader.readLine()) val expr = StringBuilder(reader.readLine())
try { try {
val result = evaluate(expr, numbers) val result = evaluate(expr, numbers)
if (result != 24) if (result != 24)
System.out?.println("Sorry, that's " + result) System.out.println("Sorry, that's " + result)
else else
System.out?.println("You won!"); System.out.println("You won!");
} }
catch(e: Throwable) { catch(e: Throwable) {
System.out?.println(e.getMessage()) System.out.println(e.getMessage())
} }
} }
...@@ -11,7 +11,7 @@ val items: ArrayList<Item> = ArrayList<Item> ...@@ -11,7 +11,7 @@ val items: ArrayList<Item> = ArrayList<Item>
fun test(room : Object) { fun test(room : Object) {
for(val item: Item? in items) { for(val item: Item? in items) {
if (item?.room === room) { if (item?.room === room) {
System.out?.println("You see " + item?.name) System.out.println("You see " + item?.name)
} }
} }
} }
...@@ -6,7 +6,7 @@ fun main(args : Array<String>) ...@@ -6,7 +6,7 @@ fun main(args : Array<String>)
{ {
val c = ArrayList<Int>() val c = ArrayList<Int>()
c.add(3) c.add(3)
System.out?.println(++(c[0])) System.out.println(++(c[0]))
System.out?.println((c[1])--) System.out.println((c[1])--)
System.out?.println(-(c[2])) System.out.println(-(c[2]))
} }
\ No newline at end of file
...@@ -25,8 +25,8 @@ fun <T> generic_invoker(gen : () -> T) : T { ...@@ -25,8 +25,8 @@ fun <T> generic_invoker(gen : () -> T) : T {
return gen() return gen()
} }
fun println(message : Int) { System.out?.println(message) } fun println(message : Int) { System.out.println(message) }
fun println(message : Long) { System.out?.println(message) } fun println(message : Long) { System.out.println(message) }
inline fun run<T>(body : () -> T) : T = body() inline fun run<T>(body : () -> T) : T = body()
fun main(args : Array<String>) { fun main(args : Array<String>) {
......
...@@ -8,7 +8,7 @@ fun bar(list : List<Int>) { ...@@ -8,7 +8,7 @@ fun bar(list : List<Int>) {
for (i in 1..10) { for (i in 1..10) {
list += i // error list += i // error
} }
System.out?.println(list) System.out.println(list)
} }
fun <T> List<T>.plusAssign(t : T) { fun <T> List<T>.plusAssign(t : T) {
......
...@@ -12,6 +12,6 @@ package demo ...@@ -12,6 +12,6 @@ package demo
fun main(args : Array<String>) { fun main(args : Array<String>) {
for (a in filter(args, {it.length > 1})) { for (a in filter(args, {it.length > 1})) {
System.out?.println("Hello, ${a}!") System.out.println("Hello, ${a}!")
} }
} }
...@@ -12,5 +12,5 @@ fun <T> TypeInfo<T>.getJavaClass() : java.lang.Class<T> { ...@@ -12,5 +12,5 @@ fun <T> TypeInfo<T>.getJavaClass() : java.lang.Class<T> {
fun getJavaClass<T>() = typeinfo<T>.getJavaClass() fun getJavaClass<T>() = typeinfo<T>.getJavaClass()
fun main(args : Array<String>) { fun main(args : Array<String>) {
System.out?.println(getJavaClass<String>) System.out.println(getJavaClass<String>)
} }
...@@ -4,5 +4,5 @@ fun main(args : Array<String>) { ...@@ -4,5 +4,5 @@ fun main(args : Array<String>) {
var s : Int? = Integer.valueOf(100) var s : Int? = Integer.valueOf(100)
val o = i .sure() + s.sure() val o = i .sure() + s.sure()
System.out?.println(o) System.out.println(o)
} }
class StaticFinal {
public static final String foo = "aaa";
}
...@@ -20,14 +20,19 @@ import org.jetbrains.annotations.NotNull; ...@@ -20,14 +20,19 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.di.InjectorForJavaSemanticServices; import org.jetbrains.jet.di.InjectorForJavaSemanticServices;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode; import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
import org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule; import org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.types.TypeProjection;
import org.junit.Assert; import org.junit.Assert;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Collections;
import java.util.Set;
/** /**
* @author Stepan Koltsov * @author Stepan Koltsov
...@@ -40,16 +45,33 @@ public class JavaDescriptorResolverTest extends TestCaseWithTmpdir { ...@@ -40,16 +45,33 @@ public class JavaDescriptorResolverTest extends TestCaseWithTmpdir {
compileFileResolveDescriptor("inner.java", new FqName("A")); compileFileResolveDescriptor("inner.java", new FqName("A"));
} }
private void compileFileResolveDescriptor(@NotNull String fileRelativePath, @NotNull FqName fqName) throws IOException { // We cannot declare class and namespace with same name in Kotlin
// http://youtrack.jetbrains.com/issue/KT-1388
public void testStaticFinal() throws Exception {
JavaDescriptorResolver javaDescriptorResolver = compileFileGetJavaDescriptorResolver("staticFinal.java");
NamespaceDescriptor ns = javaDescriptorResolver.resolveNamespace(new FqName("StaticFinal"), DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN);
Set<VariableDescriptor> foos = ns.getMemberScope().getProperties("foo");
Assert.assertEquals(1, foos.size());
VariableDescriptor foo = foos.iterator().next();
Assert.assertFalse(foo.getType().isNullable());
}
private ClassDescriptor compileFileResolveDescriptor(@NotNull String fileRelativePath, @NotNull FqName fqName) throws IOException {
JavaDescriptorResolver javaDescriptorResolver = compileFileGetJavaDescriptorResolver(fileRelativePath);
ClassDescriptor classDescriptor = javaDescriptorResolver.resolveClass(fqName, DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN);
Assert.assertNotNull(classDescriptor);
return classDescriptor;
}
private JavaDescriptorResolver compileFileGetJavaDescriptorResolver(String fileRelativePath) throws IOException {
JetTestUtils.compileJavaFile(new File("compiler/testData/javaDescriptorResolver/" + fileRelativePath), tmpdir); JetTestUtils.compileJavaFile(new File("compiler/testData/javaDescriptorResolver/" + fileRelativePath), tmpdir);
JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdkAndIdeaAnnotations(myTestRootDisposable, CompilerSpecialMode.JDK_HEADERS); JetCoreEnvironment jetCoreEnvironment = JetTestUtils.createEnvironmentWithMockJdkAndIdeaAnnotations(
myTestRootDisposable, CompilerSpecialMode.JDK_HEADERS);
jetCoreEnvironment.addToClasspath(tmpdir); jetCoreEnvironment.addToClasspath(tmpdir);
InjectorForJavaSemanticServices injector = new InjectorForJavaSemanticServices( InjectorForJavaSemanticServices injector = new InjectorForJavaSemanticServices(
jetCoreEnvironment.getCompilerDependencies(), jetCoreEnvironment.getProject()); jetCoreEnvironment.getCompilerDependencies(), jetCoreEnvironment.getProject());
JavaDescriptorResolver javaDescriptorResolver = injector.getJavaDescriptorResolver(); return injector.getJavaDescriptorResolver();
ClassDescriptor classDescriptor = javaDescriptorResolver.resolveClass(fqName, DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN);
Assert.assertNotNull(classDescriptor);
} }
} }
...@@ -25,6 +25,6 @@ val d = b.<error>x</error> ...@@ -25,6 +25,6 @@ val d = b.<error>x</error>
val s = <error>System</error> // error val s = <error>System</error> // error
fun test() { fun test() {
System.out?.println() System.out.println()
java.lang.System.out?.println() java.lang.System.out.println()
} }
\ No newline at end of file
...@@ -52,7 +52,7 @@ fun Int.foo() = this ...@@ -52,7 +52,7 @@ fun Int.foo() = this
fun main(args: Array<String>) { fun main(args: Array<String>) {
System.out?.print(1) System.out.print(1)
val command = parse("") val command = parse("")
......
...@@ -7,8 +7,8 @@ fun test() { ...@@ -7,8 +7,8 @@ fun test() {
a?.plus(1) a?.plus(1)
} }
val out : java.io.PrintStream? = null//= System.out val out : java.io.PrintStream? = null
val ins = System.`in` val ins : java.io.InputStream? = null
out?.println() out?.println()
ins?.read() ins?.read()
...@@ -277,4 +277,4 @@ fun f9(a : Int?) : Int { ...@@ -277,4 +277,4 @@ fun f9(a : Int?) : Int {
if (a != null) if (a != null)
return a return a
return 1 return 1
} }
\ No newline at end of file
...@@ -33,7 +33,7 @@ fun test(<warning>l</warning> : java.util.List<Int>) { ...@@ -33,7 +33,7 @@ fun test(<warning>l</warning> : java.util.List<Int>) {
// ... // ...
} }
catch(e: Exception) { catch(e: Exception) {
System.out?.println(e.getMessage()) System.out.println(e.getMessage())
} }
PrintStream("sdf") PrintStream("sdf")
......
...@@ -38,7 +38,7 @@ fun evaluate(expr: StringBuilder, numbers: ArrayList<Int>): Int { ...@@ -38,7 +38,7 @@ fun evaluate(expr: StringBuilder, numbers: ArrayList<Int>): Int {
} }
fun main(args: Array<String>) { fun main(args: Array<String>) {
System.out?.println("24 game") System.out.println("24 game")
val numbers = ArrayList<Int>(4) val numbers = ArrayList<Int>(4)
val rnd = Random(); val rnd = Random();
val prompt = StringBuilder() val prompt = StringBuilder()
...@@ -48,18 +48,18 @@ fun main(args: Array<String>) { ...@@ -48,18 +48,18 @@ fun main(args: Array<String>) {
if (i > 0) prompt.append(" "); if (i > 0) prompt.append(" ");
prompt.append(n) prompt.append(n)
} }
System.out?.println("Your numbers: " + prompt) System.out.println("Your numbers: " + prompt)
System.out?.println("Enter your expression:") System.out.println("Enter your expression:")
val reader = BufferedReader(InputStreamReader(System.`in`)) val reader = BufferedReader(InputStreamReader(System.`in`))
val expr = StringBuilder(reader.readLine()) val expr = StringBuilder(reader.readLine())
try { try {
val result = evaluate(expr, numbers) val result = evaluate(expr, numbers)
if (result != 24) if (result != 24)
System.out?.println("Sorry, that's " + result) System.out.println("Sorry, that's " + result)
else else
System.out?.println("You won!"); System.out.println("You won!");
} }
catch(e: Throwable) { catch(e: Throwable) {
System.out?.println(e.getMessage()) System.out.println(e.getMessage())
} }
} }
...@@ -11,7 +11,7 @@ val items: ArrayList<Item> = ArrayList<Item> ...@@ -11,7 +11,7 @@ val items: ArrayList<Item> = ArrayList<Item>
fun test(room : Object) { fun test(room : Object) {
for(val item: Item in items) { for(val item: Item in items) {
if (item.room === room) { if (item.room === room) {
System.out?.println("You see " + item.name) System.out.println("You see " + item.name)
} }
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册