Warn when certain constructor is used
Pietro Paolini
Pietro.Paolini at alfasystems.com
Fri Jun 1 08:29:19 UTC 2018
>(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