Warn when certain constructor is used

Pietro Paolini Pietro.Paolini at alfasystems.com
Mon Jun 4 07:23:00 UTC 2018


Hi Maurizio,

> Of these various analyzers, one looks quite similar to what you want:
> 
> http://hg.openjdk.java.net/jdk/jdk/file/1d5694c1aa03/make/langtools/tools/c
> rules/AssertCheckAnalyzer.java
> 
> The only difference is that it looks for the symbol associated with a
> method call, rather than that associated with a new class tree.
> 
> So, my suggestion is, maybe you can start by pulling in all that code
> into a project and then gradually chop it down until it just do whatever
> it is you need?

I've got it done that way, it contained all examples I needed, thanks a lot for your help.

P.



> 
> Regarding javac-specific documentation, you can find some info here:
> 
> http://openjdk.java.net/groups/compiler/
> 
> (see links at the bottom)
> 
> Hope this helps.
> 
> Maurizio
> 
> 
> 
> On 01/06/18 09:29, Pietro Paolini wrote:
> >> (4)
> >> obtain the TreePath for the node (by passing compilation unit and tree),
> >> and then (5) you call getElement on that path.
> > I am probably getting lost here,
> >
> >         @Override
> >          public Object visitNewClass(NewClassTree newClassTree, Object o) {
> >
> >              TreePath treePath = trees.getPath(compilationUnitTree,
> newClassTree);
> >
> >           ....
> >         }
> >
> > The TreePath class does provide a getElement() method. From the element
> somehow I could get to the symbol signature which is exactly what I need, I
> don't quite know how though.
> >
> > Would you recommend any good source of reliable information on how the
> compiler organizes the AST and what are the key data structures involved ? I
> find myself asking you basically everything as - even though I have some
> familiarity with compiler concepts such as AST, reduce, grammar etc etc - I
> have a poor knowledge on the javac specific aspects.
> >
> >
> >
> >> -----Original Message-----
> >> From: Maurizio Cimadamore [mailto:maurizio.cimadamore at oracle.com]
> >> Sent: 01 June 2018 00:02
> >> To: Pietro Paolini
> >> Cc: compiler-dev at openjdk.java.net
> >> Subject: Re: Warn when certain constructor is used
> >>
> >> You can get a treepath from an element here:
> >>
> >>
> https://docs.oracle.com/javase/7/docs/jdk/api/javac/tree/com/sun/source/ut
> >> il/Trees.html#getPath(javax.lang.model.element.Element)
> >>
> >> And from the TreePath you obtain there, you can get a compilation unit:
> >>
> >>
> https://docs.oracle.com/javase/7/docs/jdk/api/javac/tree/com/sun/source/ut
> >> il/TreePath.html#getCompilationUnit()
> >>
> >> Once you have this ingredient, you can finally obtain a path for any
> >> tree you'd like:
> >>
> >>
> https://docs.oracle.com/javase/7/docs/jdk/api/javac/tree/com/sun/source/ut
> >>
> il/Trees.html#getPath(com.sun.source.tree.CompilationUnitTree,%20com.sun.
> >> source.tree.Tree)
> >>
> >>
> >> So, I suggest you (1) obtain the TreePath form one of your root elements
> >> (2) extract the compilation unit from one of these path and stash it
> >> somewhere (3) when you reach the node you want (visitNewClass), you (4)
> >> obtain the TreePath for the node (by passing compilation unit and tree),
> >> and then (5) you call getElement on that path.
> >>
> >> Maurizio
> >>
> >> On 31/05/18 22:25, Pietro Paolini wrote:
> >>
> https://docs.oracle.com/javase/7/docs/jdk/api/javac/tree/com/sun/source/ut
> >>>> il/Trees.html#getElement(com.sun.source.util.TreePath)
> >>> On what kind of object ?
> >>>
> >>> if (!roundEnv.processingOver()) {
> >>>               Set<? extends Element> elements = roundEnv.getRootElements();
> >>>               for (Element element : elements) {
> >>>                   if (element.getKind() == ElementKind.CLASS) {
> >>>                       JCTree tree = (JCTree) trees.getTree(element).accept(new
> >> LocalDateUtilDate(), null);
> >>>                   }
> >>>
> >>>                   System.out.println(element);
> >>>               }
> >>>           }
> >>>
> >>> I haven't met any "TreePath" as yet.
> >>>
> >>>> -----Original Message-----
> >>>> From: Maurizio Cimadamore [mailto:maurizio.cimadamore at oracle.com]
> >>>> Sent: 31 May 2018 15:45
> >>>> To: Pietro Paolini
> >>>> Cc: compiler-dev at openjdk.java.net
> >>>> Subject: Re: Warn when certain constructor is used
> >>>>
> >>>> Try to call
> >>>>
> >>>>
> >>
> https://docs.oracle.com/javase/7/docs/jdk/api/javac/tree/com/sun/source/ut
> >>>> il/Trees.html#getElement(com.sun.source.util.TreePath)
> >>>>
> >>>> This should trigger attribution of the tree and give you the 'symbol'
> >>>> associated with the constructor. From there you can access the symbol
> >>>> signature using
> >>>>
> >>>>
> >>
> https://docs.oracle.com/javase/7/docs/api/javax/lang/model/element/Eleme
> >>>> nt.html#asType()
> >>>>
> >>>> And downcasting to this:
> >>>>
> >>>>
> >>
> https://docs.oracle.com/javase/7/docs/api/javax/lang/model/type/Executable
> >>>> Type.html
> >>>>
> >>>> If this works, good, otherwise the solution would be more cumbersome -
> >>>> and it will involve setting up a task listener. But try this first.
> >>>>
> >>>> Maurizio
> >>>>
> >>>>
> >>>> On 31/05/18 13:19, Pietro Paolini wrote:
> >>>>> Hi Maurizio,
> >>>>>
> >>>>> Thanks a lot. I would have an additional, and hopefully last, question.
> >>>>>
> >>>>> I am getting the NewClassTree which seems to provide me access to the
> -
> >>>> forgive me the coarse wording of it -  the "token", namely the textual
> >>>> representation
> >>>>> of it, while I am mainly interested in the type.
> >>>>>
> >>>>> I am getting around it by comparing strings but I wonder if there is any
> >> way
> >>>> to get to the type of the expression :
> >>>>> := new identifier ( arguments )
> >>>>>
> >>>>> What I have in my mind is to detect all instances in which the identifier
> >> has
> >>>> *type* A and the argument's  list is composed by a single *type* , let say
> B.
> >>>> That allows me to
> >>>>> print something:
> >>>>>
> >>>>> "Hey, constructor new A(B) has been detected"
> >>>>>
> >>>>> Thanks a lot for your help so far, really.
> >>>>>
> >>>>> Thanks,
> >>>>> P.
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>>> -----Original Message-----
> >>>>>> From: Maurizio Cimadamore
> [mailto:maurizio.cimadamore at oracle.com]
> >>>>>> Sent: 31 May 2018 12:45
> >>>>>> To: Pietro Paolini
> >>>>>> Cc: compiler-dev at openjdk.java.net
> >>>>>> Subject: Re: Warn when certain constructor is used
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> On 31/05/18 12:21, Pietro Paolini wrote:
> >>>>>>> JCTree tree = (JCTree) trees.getTree(element);
> >>>>>>> tree.accept(new LocalDateUtilDate());
> >>>>>> There re two visitor methods in JCTree, one internal (used by javac),
> >>>>>> one external (used by the API). I don't think you need to cast down to
> >>>>>> JCTree (yet, at least). Just keep it as a com.sun.source.tree.Tree, and
> >>>>>> you will see that the only 'accept' method there takes two arguments:
> a
> >>>>>> visitor (which you have) and a visitor parameter; since you don't seem
> >>>>>> to need a visitor parameter, you can just pass 'null' as second
> >> parameter.
> >>>>>> Maurizio



More information about the compiler-dev mailing list