Warn when certain constructor is used

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Thu May 31 23:02:07 UTC 2018


You can get a treepath from an element here:

https://docs.oracle.com/javase/7/docs/jdk/api/javac/tree/com/sun/source/util/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/util/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/util/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