package com.redhat.ceylon.compiler.typechecker.tree;

import com.redhat.ceylon.compiler.typechecker.model.Declaration;
import com.redhat.ceylon.compiler.typechecker.model.TypedDeclaration;


public class Util {
    
    public static String name(Tree.Identifier id) {
        if (id==null) {
            return "program element with missing name";
        }
        else {
            return id.getText();
        }
    }

    public static boolean hasAnnotation(Tree.AnnotationList al, String name) {
        if (al!=null) {
            for (Tree.Annotation a: al.getAnnotations()) {
                Tree.BaseMemberExpression p = (Tree.BaseMemberExpression) a.getPrimary();
                if (p!=null) {
                    if ( name(p.getIdentifier()).equals(name) ) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
    
    public static boolean hasUncheckedNulls(Tree.Term term) {
        if (term instanceof Tree.MemberOrTypeExpression) {
            Declaration d = ((Tree.MemberOrTypeExpression) term).getDeclaration();
            return d instanceof TypedDeclaration && 
                    ((TypedDeclaration) d).hasUncheckedNullType();
        }
        else if (term instanceof Tree.InvocationExpression) {
            return hasUncheckedNulls(((Tree.InvocationExpression) term).getPrimary());
        }
        else {
            return false;
        }
    }

}

@@ -112,16 +112,76 @@
 ration;%0A
+import com.redhat.ceylon.compiler.typechecker.model.Method;%0A
 import c
@@ -954,31 +954,148 @@
 ;%0A    %7D%0A
+%0A
     
-%0A    
 public
+ static boolean hasUncheckedNulls(Tree.Term term) %7B%0A        return hasUncheckedNulls(term, false);%0A    %7D%0A    %0A    private
  static 
@@ -1126,32 +1126,50 @@
 s(Tree.Term term
+, boolean invoking
 ) %7B%0A        if (
@@ -1351,11 +1351,8 @@
 ion 
-&& 
 %0A   
@@ -1367,16 +1367,19 @@
         
+ &&
  ((Typed
@@ -1416,16 +1416,387 @@
 llType()
+%0A                    // only consider method types when invoking them, because java method references can't be null%0A                    && (d instanceof Method == false %7C%7C invoking);%0A        %7D%0A        else if (term instanceof Tree.QualifiedMemberOrTypeExpression) %7B%0A            return hasUncheckedNulls(((Tree.QualifiedMemberOrTypeExpression)term).getPrimary(), invoking)
 ;%0A      
@@ -1945,16 +1945,167 @@
 rimary()
+, true);%0A        %7D%0A        else if (term instanceof Tree.Expression) %7B%0A            return hasUncheckedNulls(((Tree.Expression)term).getTerm(), invoking
 );%0A     

support Expression and QualifiedMemberOrTypeExpr, don't treat java method references as nullable ceylon/ceylon-compiler#810