Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check if these annotation locations are supported #2216

Closed
matozoid opened this issue May 8, 2019 · 8 comments
Closed

Check if these annotation locations are supported #2216

matozoid opened this issue May 8, 2019 · 8 comments
Labels
Grammar Improvement Not a bug, but a way that JP can be be enhanced to work better.

Comments

@matozoid
Copy link
Contributor

matozoid commented May 8, 2019

https://dzone.com/articles/java-8-type-annotations (as suggested by @edefazio)

@matozoid matozoid added Improvement Not a bug, but a way that JP can be be enhanced to work better. Grammar labels May 8, 2019
@edefazio
Copy link
Contributor

I'm working on a Test Class that contains all different kinds of Type & TypeParameter usages presented in the article. (So far everything works!) I'll put it in here and we can decide whether we want to add it as a test.

@edefazio
Copy link
Contributor

Here is the test code I created, and everything works accept for the last case (a generic constructor with a type annotations) meaning the code below IS valid Java, but JavaParser cannot parse it.

import draft.java._class;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.Serializable;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import java.util.List;
import junit.framework.TestCase;

/**
 *
 * @author Eric
 */
public class TestDifferentAnnotations 
    extends TestCase {
    
    /** 
     * These "type Annotations" aer normally used by the Checker Framework:
     * https://checkerframework.org/
     * for compile time checking (integrated wwith the Javac compiler)
     */
    @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
    @interface TypeAnno{ }
    
    @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
    @interface TA2{}
    
    public static class Nested{
        public static void saySomething(){ System.out.println("hi"); }
    }
    public class NN{
        public class F{
            
        }
    }
    class TT {
	//Generics constructor
	public <T> TT(T item){ }
    }
    
    static class GT<T>{
        public static<R> void size(){}
    }
    
    interface Sayable{  
        void say();  
    }
    public void testTypeAnnotations(){
        
        class TC <@TypeAnno @TA2 F> /*In Type Parameters*/
            implements @TypeAnno @TA2 Serializable /*in inheritance*/ {
            
            /* on a type Declaration */ 
            @TypeAnno @TA2 String s; 
            Object o = "STR";
            /* nested type declaration */
            TestDifferentAnnotations.@TypeAnno @TA2 Nested n; 
            
            void m(){
                /*In Constructors with type annotations:*/
                NN n = new @TypeAnno @TA2 NN(); 
                /*In (non static) class constructors: */
                n.new @TypeAnno @TA2 F(); 
            }
            
            /* in cast */
            String anotherString = (@TypeAnno @TA2 String)o; 
            
            /* in Type Generic */
            List<@TA2 @TypeAnno Integer> l = null;  
            
            /* In intersection types ( x & y) */
            public <E extends @TypeAnno @TA2 Serializable & @TypeAnno @TA2 Cloneable> void foo(){
            
            }
            /* In wildcard bounds */
            List<? extends @TypeAnno @TA2 Comparable<String>> nno = null;
            List<? super @TypeAnno @TA2 File> c = null;
            List<@TypeAnno @TA2 ? extends Comparable<String>> unchangeable = null;
            
            /* throwing exceptions */
            void mm() throws @TypeAnno @TA2 FileNotFoundException, 
                @TypeAnno @TA2 RuntimeException {}
            
            /* in MethodReferences/ClassReferences */
            boolean isNonNull = o instanceof @TypeAnno @TA2 String;
            Sayable sayable = @TypeAnno @TA2 Nested::saySomething;              
            Sayable st = GT::<@TypeAnno @TA2 String>size;       
            
            /* FAILS HERE : In generic constructor */
            TT tt = new <String> @TypeAnno @TA2 TT( "S" );
        }        
        
        _class _c = _class.of( TC.class ); //this is my handy shortcut for just loading the code above in JP
        System.out.println(_c);
    }    
}

here is where it fails:

TT tt = new <String> @TypeAnno @TA2 TT( "S" );

exception summary:
(line 93,col 32) Parse error. Found "@", expected one of "enum" "exports" "module" "open" "opens" "provides" "requires" "strictfp" "to" "transitive" "uses" "with" Problem stacktrace :
...
(line 96,col 20) Parse error. Found "(", expected one of "enum" "exports" "module" "open" "opens" "provides" "requires" "strictfp" "to" "transitive" "uses" "with"

@edefazio
Copy link
Contributor

FWIW I hated writing the above code... it makes my eyes hurt, it's ugly, and I dont use the checker framework, but I guess categorize this as a "you COULD break parsing if you try really hard to do something you shouldn't do", but its certainly not a pressing issue with the grammar.

@matozoid
Copy link
Contributor Author

Funny, Intellij says this one is not allowed: Sayable sayable = @TypeAnno @TA2 Nested::saySomething;. "Static member qualifying type not allowed"

I'll check the other. This still needs a test suite though.

@matozoid
Copy link
Contributor Author

See #2247

@edefazio
Copy link
Contributor

Sayable sayable = @TypeAnno @TA2 Nested::saySomething;
Truth be told, I've been using NetBeans and TBH i've been having lots of issues lately (its constantly scanning the background)

Anyways, I was able to successfully load the code above in a new Netbeans project, and it seemed to compile... as long as I commented out the last line:

/* FAILS HERE : In generic constructor */
//TT tt = new <String> @TypeAnno @TA2 TT( "S" );

the test passes.(i.e. Javaparser works for everything accept the last one)

I'm using a Java11 compiler (Zulu 11). and I dunno if there are different levels of compiler warnings in your IDE... I also have intelliJ and will try it out)

@matozoid
Copy link
Contributor Author

Hey, intellij might be wrong - I've seen it mess up before :-) But your particular issue was solved in the PR I mentioned.

@edefazio
Copy link
Contributor

Cool... I was able to reproduce the same issue you had in IntelliJ on the same line:

Sayable sayable = @TypeAnno @TA2 Nested::saySomething;

I'm using the most current Community edition of IntelliJ (it's using a Java 8 JRE)

@matozoid matozoid closed this as completed Aug 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Grammar Improvement Not a bug, but a way that JP can be be enhanced to work better.
Projects
None yet
Development

No branches or pull requests

2 participants