Path: blob/master/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeScanner.java
66647 views
/*1* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.source.util;2627import com.sun.source.doctree.*;282930/**31* A DocTreeVisitor that visits all the child tree nodes.32* To visit nodes of a particular type, just override the33* corresponding visitXYZ method.34* Inside your method, call super.visitXYZ to visit descendant35* nodes.36*37* <p>Here is an example to count the number of erroneous nodes in a tree:38* <pre>39* class CountErrors extends DocTreeScanner<Integer,Void> {40* {@literal @}Override41* public Integer visitErroneous(ErroneousTree node, Void p) {42* return 1;43* }44* {@literal @}Override45* public Integer reduce(Integer r1, Integer r2) {46* return (r1 == null ? 0 : r1) + (r2 == null ? 0 : r2);47* }48* }49* </pre>50*51* @implSpec52* <p>The default implementation of the visitXYZ methods will determine53* a result as follows:54* <ul>55* <li>If the node being visited has no children, the result will be {@code null}.56* <li>If the node being visited has one child, the result will be the57* result of calling {@code scan} with that child. The child may be a simple node58* or itself a list of nodes.59* <li>If the node being visited has more than one child, the result will60* be determined by calling {@code scan} with each child in turn, and then combining the61* result of each scan after the first with the cumulative result62* so far, as determined by the {@link #reduce} method. Each child may be either63* a simple node or a list of nodes. The default behavior of the {@code reduce}64* method is such that the result of the visitXYZ method will be the result of65* the last child scanned.66* </ul>67*68* @since 1.869*/70public class DocTreeScanner<R,P> implements DocTreeVisitor<R,P> {71/**72* Constructs a {@code DocTreeScanner}.73*/74public DocTreeScanner() {}7576/**77* Scans a single node.78* @param node the node to be scanned79* @param p a parameter value passed to the visit method80* @return the result value from the visit method81*/82public R scan(DocTree node, P p) {83return (node == null) ? null : node.accept(this, p);84}8586private R scanAndReduce(DocTree node, P p, R r) {87return reduce(scan(node, p), r);88}8990/**91* Scans a sequence of nodes.92* @param nodes the nodes to be scanned93* @param p a parameter value to be passed to the visit method for each node94* @return the combined return value from the visit methods.95* The values are combined using the {@link #reduce reduce} method.96*/97public R scan(Iterable<? extends DocTree> nodes, P p) {98R r = null;99if (nodes != null) {100boolean first = true;101for (DocTree node : nodes) {102r = (first ? scan(node, p) : scanAndReduce(node, p, r));103first = false;104}105}106return r;107}108109private R scanAndReduce(Iterable<? extends DocTree> nodes, P p, R r) {110return reduce(scan(nodes, p), r);111}112113/**114* Reduces two results into a combined result.115* The default implementation is to return the first parameter.116* The general contract of the method is that it may take any action whatsoever.117* @param r1 the first of the values to be combined118* @param r2 the second of the values to be combined119* @return the result of combining the two parameters120*/121public R reduce(R r1, R r2) {122return r1;123}124125126/* ***************************************************************************127* Visitor methods128****************************************************************************/129130/**131* {@inheritDoc}132*133* @implSpec This implementation scans the children in left to right order.134*135* @param node {@inheritDoc}136* @param p {@inheritDoc}137* @return the result of scanning138*/139@Override140public R visitAttribute(AttributeTree node, P p) {141return scan(node.getValue(), p);142}143144/**145* {@inheritDoc}146*147* @implSpec This implementation scans the children in left to right order.148*149* @param node {@inheritDoc}150* @param p {@inheritDoc}151* @return the result of scanning152*/153@Override154public R visitAuthor(AuthorTree node, P p) {155return scan(node.getName(), p);156}157158/**159* {@inheritDoc}160*161* @implSpec This implementation returns {@code null}.162*163* @param node {@inheritDoc}164* @param p {@inheritDoc}165* @return the result of scanning166*/167@Override168public R visitComment(CommentTree node, P p) {169return null;170}171172/**173* {@inheritDoc}174*175* @implSpec This implementation scans the children in left to right order.176*177* @param node {@inheritDoc}178* @param p {@inheritDoc}179* @return the result of scanning180*/181@Override182public R visitDeprecated(DeprecatedTree node, P p) {183return scan(node.getBody(), p);184}185186/**187* {@inheritDoc}188*189* @implSpec This implementation scans the children in left to right order.190*191* @param node {@inheritDoc}192* @param p {@inheritDoc}193* @return the result of scanning194*/195@Override196public R visitDocComment(DocCommentTree node, P p) {197R r = scan(node.getFirstSentence(), p);198r = scanAndReduce(node.getBody(), p, r);199r = scanAndReduce(node.getBlockTags(), p, r);200return r;201}202203/**204* {@inheritDoc}205*206* @implSpec This implementation returns {@code null}.207*208* @param node {@inheritDoc}209* @param p {@inheritDoc}210* @return the result of scanning211*/212@Override213public R visitDocRoot(DocRootTree node, P p) {214return null;215}216217/**218* {@inheritDoc}219*220* @implSpec This implementation returns {@code null}.221*222* @param node {@inheritDoc}223* @param p {@inheritDoc}224* @return the result of scanning225*/226@Override227public R visitDocType(DocTypeTree node, P p) {228return null;229}230231/**232* {@inheritDoc}233*234* @implSpec This implementation returns {@code null}.235*236* @param node {@inheritDoc}237* @param p {@inheritDoc}238* @return the result of scanning239*/240@Override241public R visitEndElement(EndElementTree node, P p) {242return null;243}244245/**246* {@inheritDoc}247*248* @implSpec This implementation returns {@code null}.249*250* @param node {@inheritDoc}251* @param p {@inheritDoc}252* @return the result of scanning253*/254@Override255public R visitEntity(EntityTree node, P p) {256return null;257}258259/**260* {@inheritDoc}261*262* @implSpec This implementation returns {@code null}.263*264* @param node {@inheritDoc}265* @param p {@inheritDoc}266* @return the result of scanning267*/268@Override269public R visitErroneous(ErroneousTree node, P p) {270return null;271}272273/**274* {@inheritDoc}275*276* @implSpec This implementation scans the children in left to right order.277*278* @param node {@inheritDoc}279* @param p {@inheritDoc}280* @return the result of scanning281*/282@Override283public R visitHidden(HiddenTree node, P p) {284return scan(node.getBody(), p);285}286287/**288* {@inheritDoc}289*290* @implSpec This implementation returns {@code null}.291*292* @param node {@inheritDoc}293* @param p {@inheritDoc}294* @return the result of scanning295*/296@Override297public R visitIdentifier(IdentifierTree node, P p) {298return null;299}300301/**302* {@inheritDoc}303*304* @implSpec This implementation scans the children in left to right order.305*306* @param node {@inheritDoc}307* @param p {@inheritDoc}308* @return the result of scanning309*/310@Override311public R visitIndex(IndexTree node, P p) {312R r = scan(node.getSearchTerm(), p);313r = scanAndReduce(node.getDescription(), p, r);314return r;315}316317/**318* {@inheritDoc}319*320* @implSpec This implementation returns {@code null}.321*322* @param node {@inheritDoc}323* @param p {@inheritDoc}324* @return the result of scanning325*/326@Override327public R visitInheritDoc(InheritDocTree node, P p) {328return null;329}330331/**332* {@inheritDoc}333*334* @implSpec This implementation scans the children in left to right order.335*336* @param node {@inheritDoc}337* @param p {@inheritDoc}338* @return the result of scanning339*/340@Override341public R visitLink(LinkTree node, P p) {342R r = scan(node.getReference(), p);343r = scanAndReduce(node.getLabel(), p, r);344return r;345}346347/**348* {@inheritDoc}349*350* @implSpec This implementation scans the children in left to right order.351*352* @param node {@inheritDoc}353* @param p {@inheritDoc}354* @return the result of scanning355*/356@Override357public R visitLiteral(LiteralTree node, P p) {358return scan(node.getBody(), p);359}360361/**362* {@inheritDoc}363*364* @implSpec This implementation scans the children in left to right order.365*366* @param node {@inheritDoc}367* @param p {@inheritDoc}368* @return the result of scanning369*/370@Override371public R visitParam(ParamTree node, P p) {372R r = scan(node.getName(), p);373r = scanAndReduce(node.getDescription(), p, r);374return r;375}376377/**378* {@inheritDoc}379*380* @implSpec This implementation scans the children in left to right order.381*382* @param node {@inheritDoc}383* @param p {@inheritDoc}384* @return the result of scanning385*/386@Override387public R visitProvides(ProvidesTree node, P p) {388R r = scan(node.getServiceType(), p);389r = scanAndReduce(node.getDescription(), p, r);390return r;391}392393/**394* {@inheritDoc}395*396* @implSpec This implementation returns {@code null}.397*398* @param node {@inheritDoc}399* @param p {@inheritDoc}400* @return the result of scanning401*/402@Override403public R visitReference(ReferenceTree node, P p) {404return null;405}406407/**408* {@inheritDoc}409*410* @implSpec This implementation scans the children in left to right order.411*412* @param node {@inheritDoc}413* @param p {@inheritDoc}414* @return the result of scanning415*/416@Override417public R visitReturn(ReturnTree node, P p) {418return scan(node.getDescription(), p);419}420421/**422* {@inheritDoc}423*424* @implSpec This implementation scans the children in left to right order.425*426* @param node {@inheritDoc}427* @param p {@inheritDoc}428* @return the result of scanning429*/430@Override431public R visitSee(SeeTree node, P p) {432return scan(node.getReference(), p);433}434435/**436* {@inheritDoc}437*438* @implSpec This implementation scans the children in left to right order.439*440* @param node {@inheritDoc}441* @param p {@inheritDoc}442* @return the result of scanning443*/444@Override445public R visitSerial(SerialTree node, P p) {446return scan(node.getDescription(), p);447}448449/**450* {@inheritDoc}451*452* @implSpec This implementation scans the children in left to right order.453*454* @param node {@inheritDoc}455* @param p {@inheritDoc}456* @return the result of scanning457*/458@Override459public R visitSerialData(SerialDataTree node, P p) {460return scan(node.getDescription(), p);461}462463/**464* {@inheritDoc}465*466* @implSpec This implementation scans the children in left to right order.467*468* @param node {@inheritDoc}469* @param p {@inheritDoc}470* @return the result of scanning471*/472@Override473public R visitSerialField(SerialFieldTree node, P p) {474R r = scan(node.getName(), p);475r = scanAndReduce(node.getType(), p, r);476r = scanAndReduce(node.getDescription(), p, r);477return r;478}479480/**481* {@inheritDoc}482*483* @implSpec This implementation scans the children in left to right order.484*485* @param node {@inheritDoc}486* @param p {@inheritDoc}487* @return the result of scanning488*/489@Override490public R visitSince(SinceTree node, P p) {491return scan(node.getBody(), p);492}493494/**495* {@inheritDoc}496*497* @implSpec This implementation scans the children in left to right order.498*499* @param node {@inheritDoc}500* @param p {@inheritDoc}501* @return the result of scanning502*/503@Override504public R visitStartElement(StartElementTree node, P p) {505return scan(node.getAttributes(), p);506}507508/**509* {@inheritDoc}510*511* @implSpec This implementation scans the children in left to right order.512*513* @param node {@inheritDoc}514* @param p {@inheritDoc}515* @return the result of scanning516* @since 10517*/518@Override519public R visitSummary(SummaryTree node, P p) {520return scan(node.getSummary(), p);521}522523/**524* {@inheritDoc}525*526* @implSpec This implementation returns {@code null}.527*528* @param node {@inheritDoc}529* @param p {@inheritDoc}530* @return the result of scanning531* @since 12532*/533@Override534public R visitSystemProperty(SystemPropertyTree node, P p) {535return null;536}537538/**539* {@inheritDoc}540*541* @implSpec This implementation returns {@code null}.542*543* @param node {@inheritDoc}544* @param p {@inheritDoc}545* @return the result of scanning546*/547@Override548public R visitText(TextTree node, P p) {549return null;550}551552/**553* {@inheritDoc}554*555* @implSpec This implementation scans the children in left to right order.556*557* @param node {@inheritDoc}558* @param p {@inheritDoc}559* @return the result of scanning560*/561@Override562public R visitThrows(ThrowsTree node, P p) {563R r = scan(node.getExceptionName(), p);564r = scanAndReduce(node.getDescription(), p, r);565return r;566}567568/**569* {@inheritDoc}570*571* @implSpec This implementation scans the children in left to right order.572*573* @param node {@inheritDoc}574* @param p {@inheritDoc}575* @return the result of scanning576*/577@Override578public R visitUnknownBlockTag(UnknownBlockTagTree node, P p) {579return scan(node.getContent(), p);580}581582/**583* {@inheritDoc}584*585* @implSpec This implementation scans the children in left to right order.586*587* @param node {@inheritDoc}588* @param p {@inheritDoc}589* @return the result of scanning590*/591@Override592public R visitUnknownInlineTag(UnknownInlineTagTree node, P p) {593return scan(node.getContent(), p);594}595596/**597* {@inheritDoc}598*599* @implSpec This implementation scans the children in left to right order.600*601* @param node {@inheritDoc}602* @param p {@inheritDoc}603* @return the result of scanning604*/605@Override606public R visitUses(UsesTree node, P p) {607R r = scan(node.getServiceType(), p);608r = scanAndReduce(node.getDescription(), p, r);609return r;610}611612/**613* {@inheritDoc}614*615* @implSpec This implementation scans the children in left to right order.616*617* @param node {@inheritDoc}618* @param p {@inheritDoc}619* @return the result of scanning620*/621@Override622public R visitValue(ValueTree node, P p) {623return scan(node.getReference(), p);624}625626/**627* {@inheritDoc}628*629* @implSpec This implementation scans the children in left to right order.630*631* @param node {@inheritDoc}632* @param p {@inheritDoc}633* @return the result of scanning634*/635@Override636public R visitVersion(VersionTree node, P p) {637return scan(node.getBody(), p);638}639640/**641* {@inheritDoc}642*643* @implSpec This implementation returns {@code null}.644*645* @param node {@inheritDoc}646* @param p {@inheritDoc}647* @return the result of scanning648*/649@Override650public R visitOther(DocTree node, P p) {651return null;652}653654}655656657