ada.editor/src/org/netbeans/modules/ada/editor/parser/AdaStructureScanner.java
author Andrea Lucarelli <raster@netbeans.org>
Sun, 22 Aug 2010 23:37:11 +0200
branchrelease68
changeset 16367 d2820c029d3a
parent 15779 367c7fdb5d23
permissions -rw-r--r--
Add JVM compiler support.
     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
     5  *
     6  * The contents of this file are subject to the terms of either the GNU
     7  * General Public License Version 2 only ("GPL") or the Common
     8  * Development and Distribution License("CDDL") (collectively, the
     9  * "License"). You may not use this file except in compliance with the
    10  * License. You can obtain a copy of the License at
    11  * http://www.netbeans.org/cddl-gplv2.html
    12  * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    13  * specific language governing permissions and limitations under the
    14  * License.  When distributing the software, include this License Header
    15  * Notice in each file and include the License file at
    16  * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
    17  * particular file as subject to the "Classpath" exception as provided
    18  * by Sun in the GPL Version 2 section of the License file that
    19  * accompanied this code. If applicable, add the following below the
    20  * License Header, with the fields enclosed by brackets [] replaced by
    21  * your own identifying information:
    22  * "Portions Copyrighted [year] [name of copyright owner]"
    23  *
    24  * If you wish your version of this file to be governed by only the CDDL
    25  * or only the GPL Version 2, indicate your decision by adding
    26  * "[Contributor] elects to include this software in this distribution
    27  * under the [CDDL or GPL Version 2] license." If you do not indicate a
    28  * single choice of license, a recipient has the option to distribute
    29  * your version of this file under either the CDDL, the GPL Version 2 or
    30  * to extend the choice of license to its licensees as provided above.
    31  * However, if you add GPL Version 2 code and therefore, elected the GPL
    32  * Version 2 license, then the option applies only if the new code is
    33  * made subject to such option by the copyright holder.
    34  *
    35  * Contributor(s):
    36  *
    37  * Portions Copyrighted 2008 Sun Microsystems, Inc.
    38  */
    39 package org.netbeans.modules.ada.editor.parser;
    40 
    41 import org.netbeans.modules.ada.editor.ast.nodes.Program;
    42 import org.netbeans.modules.ada.editor.ast.nodes.Identifier;
    43 import org.netbeans.modules.ada.editor.ast.ASTNode;
    44 import java.util.ArrayList;
    45 import java.util.Collections;
    46 import java.util.HashMap;
    47 import java.util.List;
    48 import java.util.Map;
    49 import java.util.Set;
    50 import java.util.logging.Logger;
    51 import javax.swing.ImageIcon;
    52 import javax.swing.text.Document;
    53 import org.netbeans.modules.ada.editor.CodeUtils;
    54 import org.netbeans.modules.ada.editor.ast.ASTError;
    55 import org.netbeans.modules.ada.editor.ast.ASTUtils;
    56 import org.netbeans.modules.ada.editor.ast.nodes.Block;
    57 import org.netbeans.modules.ada.editor.ast.nodes.BlockStatement;
    58 import org.netbeans.modules.ada.editor.ast.nodes.Comment;
    59 import org.netbeans.modules.ada.editor.ast.nodes.Expression;
    60 import org.netbeans.modules.ada.editor.ast.nodes.FieldsDeclaration;
    61 import org.netbeans.modules.ada.editor.ast.nodes.FormalParameter;
    62 import org.netbeans.modules.ada.editor.ast.nodes.MethodDeclaration;
    63 import org.netbeans.modules.ada.editor.ast.nodes.PackageBody;
    64 import org.netbeans.modules.ada.editor.ast.nodes.PackageSpecification;
    65 import org.netbeans.modules.ada.editor.ast.nodes.SubprogramBody;
    66 import org.netbeans.modules.ada.editor.ast.nodes.SubprogramSpecification;
    67 import org.netbeans.modules.ada.editor.ast.nodes.TypeAccess;
    68 import org.netbeans.modules.ada.editor.ast.nodes.TypeDeclaration;
    69 import org.netbeans.modules.ada.editor.ast.nodes.TypeName;
    70 import org.netbeans.modules.ada.editor.ast.nodes.Variable;
    71 import org.netbeans.modules.ada.editor.ast.nodes.visitors.DefaultVisitor;
    72 import org.netbeans.modules.ada.editor.parser.AdaElementHandle.SubprogramSpecificationHandle;
    73 import org.netbeans.modules.ada.editor.parser.AdaElementHandle.MethodSubprogSpecHandle;
    74 import org.netbeans.modules.ada.editor.parser.AdaElementHandle.MethodSubprogBodyHandle;
    75 import org.netbeans.modules.ada.editor.parser.AdaElementHandle.PackageBodyHandle;
    76 import org.netbeans.modules.ada.editor.parser.AdaElementHandle.PackageSpecificationHandle;
    77 import org.netbeans.modules.ada.editor.parser.AdaElementHandle.SubprogramBodyHandle;
    78 import org.netbeans.modules.csl.api.ElementHandle;
    79 import org.netbeans.modules.csl.api.ElementKind;
    80 import org.netbeans.modules.csl.api.HtmlFormatter;
    81 import org.netbeans.modules.csl.api.Modifier;
    82 import org.netbeans.modules.csl.api.OffsetRange;
    83 import org.netbeans.modules.csl.api.StructureItem;
    84 import org.netbeans.modules.csl.api.StructureScanner;
    85 import org.netbeans.modules.csl.spi.ParserResult;
    86 import org.netbeans.modules.parsing.api.Source;
    87 import org.openide.util.ImageUtilities;
    88 
    89 /**
    90  * Based on org.netbeans.modules.php.editor.parser.PhpStructureScanner
    91  *
    92  * @author Andrea Lucarelli
    93  */
    94 public class AdaStructureScanner implements StructureScanner {
    95 
    96     private static final Logger LOGGER = Logger.getLogger(AdaStructureScanner.class.getName());
    97     private static ImageIcon TYPE_ICON = null;
    98     private static ImageIcon TYPE_PRIVATE_ICON = null;
    99     private ParserResult info;
   100     private static final String FOLD_CODE_BLOCKS = "codeblocks"; //NOI18N
   101     private static final String FOLD_PACKAGE = "codeblocks"; //NOI18N
   102     private static final String FOLD_ADADOC = "comments"; //NOI18N
   103     private static final String FOLD_COMMENT = "initial-comment"; //NOI18N
   104     private static final String FONT_GRAY_COLOR = "<font color=\"#999999\">"; //NOI18N
   105     private static final String CLOSE_FONT = "</font>";                   //NOI18N
   106     private static final String LAST_CORRECT_FOLDING_PROPERTY = "LAST_CORRECT_FOLDING_PROPERY";
   107 
   108     public List<? extends StructureItem> scan(final ParserResult info) {
   109         this.info = info;
   110         Program program = ASTUtils.getRoot(info);
   111         final List<StructureItem> items = new ArrayList<StructureItem>();
   112         if (program != null) {
   113             program.accept(new StructureVisitor(items, program));
   114             return items;
   115         }
   116         return Collections.emptyList();
   117     }
   118 
   119     public Map<String, List<OffsetRange>> folds(ParserResult info) {
   120         Program program = ASTUtils.getRoot(info);
   121         final Map<String, List<OffsetRange>> folds = new HashMap<String, List<OffsetRange>>();
   122         if (program != null) {
   123             if (program.getStatements().size() == 1) {
   124                 // check whether the ast is broken.
   125                 if (program.getStatements().get(0) instanceof ASTError) {
   126                     @SuppressWarnings("unchecked")
   127                     Map<String, List<OffsetRange>> lastCorrect = (Map<String, List<OffsetRange>>) info.getSnapshot().getSource().getDocument(false).getProperty(LAST_CORRECT_FOLDING_PROPERTY);
   128                     if (lastCorrect != null) {
   129                         return lastCorrect;
   130                     } else {
   131                         return Collections.emptyMap();
   132                     }
   133                 }
   134             }
   135             (new FoldVisitor(folds)).scan(program);
   136             List<Comment> comments = program.getComments();
   137             if (comments != null) {
   138                 for (Comment comment : comments) {
   139                     // TODO: for ada doc and spark ???
   140                 }
   141             }
   142             Source source = info.getSnapshot().getSource();
   143             assert source != null : "source was null";
   144             Document doc = source.getDocument(false);
   145             if (doc != null){
   146                 doc.putProperty(LAST_CORRECT_FOLDING_PROPERTY, folds);
   147             }
   148             return folds;
   149         }
   150         return Collections.emptyMap();
   151     }
   152 
   153     private OffsetRange createOffsetRange(ASTNode node) {
   154         return new OffsetRange(node.getStartOffset(), node.getEndOffset());
   155     }
   156 
   157     private List<OffsetRange> getRanges(Map<String, List<OffsetRange>> folds, String kind) {
   158         List<OffsetRange> ranges = folds.get(kind);
   159         if (ranges == null) {
   160             ranges = new ArrayList<OffsetRange>();
   161             folds.put(kind, ranges);
   162         }
   163         return ranges;
   164     }
   165 
   166     public Configuration getConfiguration() {
   167         return null;
   168     }
   169 
   170     private class StructureVisitor extends DefaultVisitor {
   171 
   172         final List<StructureItem> items;
   173         private List<StructureItem> children = null;
   174         private Program program;
   175         private PackageSpecification pkgspc;
   176         private PackageBody pkgbdy;
   177 
   178         public StructureVisitor(List<StructureItem> items, Program program) {
   179             //LOGGER.setLevel(Level.FINE);
   180             this.items = items;
   181             this.program = program;
   182         }
   183 
   184         public StructureVisitor(List<StructureItem> items, PackageSpecification pkgspc) {
   185             //LOGGER.setLevel(Level.FINE);
   186             this.items = items;
   187             this.pkgspc = pkgspc;
   188         }
   189 
   190         public StructureVisitor(List<StructureItem> items, PackageBody pkgbdy) {
   191             //LOGGER.setLevel(Level.FINE);
   192             this.items = items;
   193             this.pkgbdy = pkgbdy;
   194         }
   195 
   196         @Override
   197         public void visit(SubprogramSpecification subprogSpec) {
   198             if (children == null && subprogSpec.getSubprogramName() != null) {
   199                 AdaStructureItem item = new AdaSubprogSpecStructureItem(new AdaElementHandle.SubprogramSpecificationHandle(info, subprogSpec));
   200                 items.add(item);
   201             }
   202         }
   203 
   204         @Override
   205         public void visit(SubprogramBody procedure) {
   206             if (children == null && procedure.getSubprogramSpecification().getSubprogramName() != null) {
   207                 AdaStructureItem item = new AdaSubprogBodyStructureItem(new AdaElementHandle.SubprogramBodyHandle(info, procedure));
   208                 items.add(item);
   209             }
   210         }
   211 
   212         @Override
   213         public void visit(PackageSpecification pkgspc) {
   214             if (pkgspc.getName() != null) {
   215                 LOGGER.fine(pkgspc.getName().getName());
   216                 if (children == null) {
   217                     children = new ArrayList<StructureItem>();
   218                     super.visit(pkgspc);
   219                     AdaStructureItem item = new AdaPackageSpecificationStructureItem(new AdaElementHandle.PackageSpecificationHandle(info, pkgspc), children); //NOI18N
   220                     items.add(item);
   221                 } else {
   222                     final List<StructureItem> subitems = new ArrayList<StructureItem>();
   223                     pkgspc.accept(new StructureVisitor(subitems, pkgspc));
   224                     children.addAll(subitems);
   225                 }
   226             }
   227         }
   228 
   229         @Override
   230         public void visit(PackageBody pkgbdy) {
   231             if (pkgbdy.getName() != null) {
   232                 LOGGER.fine(pkgbdy.getName().getName());
   233                 if (children == null) {
   234                     children = new ArrayList<StructureItem>();
   235                     super.visit(pkgbdy);
   236                     AdaStructureItem item = new AdaPackageBodyStructureItem(new AdaElementHandle.PackageBodyHandle(info, pkgbdy), children); //NOI18N
   237                     items.add(item);
   238                 } else {
   239                     final List<StructureItem> subitems = new ArrayList<StructureItem>();
   240                     pkgbdy.accept(new StructureVisitor(subitems, pkgbdy));
   241                     children.addAll(subitems);
   242                 }
   243             }
   244         }
   245 
   246         @Override
   247         public void visit(FieldsDeclaration fields) {
   248             Variable[] variables = fields.getVariableNames();
   249             if (variables != null) {
   250                 for (Variable variable : variables) {
   251                     String name = ASTUtils.resolveVariableName(variable);
   252                     LOGGER.fine(name);
   253                     if (name != null) {
   254                         String text = name;
   255                         AdaStructureItem item = new AdaSimpleStructureItem(new AdaElementHandle.FieldsDeclarationHandle(info, fields), text, "0"); //NOI18N
   256                         children.add(item);
   257                     }
   258                 }
   259             }
   260         }
   261 
   262         @Override
   263         public void visit(TypeDeclaration type) {
   264             Identifier id = type.getTypeName();
   265             if (id != null) {
   266                 String name = id.getName();
   267                 LOGGER.fine(name);
   268                 if (name != null) {
   269                     String text = name;
   270                     AdaStructureItem item = new AdaTypeStructureItem(new AdaElementHandle.TypeDeclarationHandle(info, type), text, "0"); //NOI18N
   271                     children.add(item);
   272                 }
   273             }
   274         }
   275 
   276         @Override
   277         public void visit(MethodDeclaration method) {
   278             if (children == null) {
   279                 children = items;
   280             }
   281             LOGGER.fine(method.getMethodName());
   282             if (method.getSubprogramBody() != null) {
   283                 SubprogramBody subprog = method.getSubprogramBody();
   284                 if (subprog != null && subprog.getSubprogramSpecification().getSubprogramName() != null) {
   285                     AdaStructureItem item;
   286                     // className doesn't have to be defined if it's interace
   287                     item = new AdaMethodSubprogBodyStructureItem(new AdaElementHandle.MethodSubprogBodyHandle(info, method));
   288                     children.add(item);
   289                 }
   290             } else {
   291                 SubprogramSpecification subprog = method.getSubprogramSpecification();
   292                 if (subprog != null && subprog.getSubprogramName() != null) {
   293                     AdaStructureItem item;
   294                     // className doesn't have to be defined if it's interace
   295                     item = new AdaMethodSubprogSpecStructureItem(new AdaElementHandle.MethodSubprogSpecHandle(info, method));
   296                     children.add(item);
   297                 }
   298             }
   299         }
   300     }
   301 
   302     private abstract class AdaStructureItem implements StructureItem {
   303 
   304         final private AdaElementHandle elementHandle;
   305         final private List<? extends StructureItem> children;
   306         final private String sortPrefix;
   307 
   308         public AdaStructureItem(AdaElementHandle elementHandle, List<? extends StructureItem> children, String sortPrefix) {
   309             this.elementHandle = elementHandle;
   310             this.sortPrefix = sortPrefix;
   311             if (children != null) {
   312                 this.children = children;
   313             } else {
   314                 this.children = Collections.emptyList();
   315             }
   316         }
   317 
   318         @Override
   319         public boolean equals(Object obj) {
   320             boolean thesame = false;
   321             if (obj instanceof AdaStructureItem) {
   322                 AdaStructureItem item = (AdaStructureItem) obj;
   323                 if (item.getName() != null && this.getName() != null) {
   324                     thesame = item.elementHandle.getName().equals(elementHandle.getName()) && item.elementHandle.getASTNode().getStartOffset() == elementHandle.getASTNode().getStartOffset();
   325                 }
   326             }
   327             return thesame;
   328         }
   329 
   330         @Override
   331         public int hashCode() {
   332             //int hashCode = super.hashCode();
   333             int hashCode = 11;
   334             if (getName() != null) {
   335                 hashCode = 31 * getName().hashCode() + hashCode;
   336             }
   337             hashCode = (int) (31 * getPosition() + hashCode);
   338             return hashCode;
   339         }
   340 
   341         public String getName() {
   342             return elementHandle.getName();
   343         }
   344 
   345         public String getSortText() {
   346             return sortPrefix + elementHandle.getName();
   347         }
   348 
   349         public ElementHandle getElementHandle() {
   350             return elementHandle;
   351         }
   352 
   353         public ElementKind getKind() {
   354             return elementHandle.getKind();
   355         }
   356 
   357         public Set<Modifier> getModifiers() {
   358             return elementHandle.getModifiers();
   359         }
   360 
   361         public boolean isLeaf() {
   362             return (children.size() == 0);
   363         }
   364 
   365         public List<? extends StructureItem> getNestedItems() {
   366             return children;
   367         }
   368 
   369         public long getPosition() {
   370             return elementHandle.getASTNode().getStartOffset();
   371         }
   372 
   373         public long getEndPosition() {
   374             return elementHandle.getASTNode().getEndOffset();
   375         }
   376 
   377         public ImageIcon getCustomIcon() {
   378             return null;
   379         }
   380 
   381         protected void appendSubprogDescription(SubprogramSpecification subprog, HtmlFormatter formatter) {
   382             formatter.reset();
   383             if (subprog == null || subprog.getSubprogramName() == null) {
   384                 return;
   385             }
   386             formatter.appendText(subprog.getSubprogramName().getName());
   387             formatter.appendText("(");   //NOI18N
   388 
   389             List<FormalParameter> parameters = subprog.getFormalParameters();
   390             if (parameters != null && parameters.size() > 0) {
   391                 boolean first = true;
   392                 for (FormalParameter formalParameter : parameters) {
   393                     String name = null;
   394                     Expression parameter = formalParameter.getParameterName();
   395                     if (parameter != null) {
   396                         Variable variable = null;
   397                         if (parameter instanceof Variable) {
   398                             variable = (Variable) parameter;
   399                         }
   400 
   401                         if (variable != null) {
   402                             name = ASTUtils.resolveVariableName(variable);
   403                         } else {
   404                             name = "??"; //NOI18N
   405                         }
   406                     }
   407                     String type = null;
   408                     if (formalParameter.getParameterType() != null) {
   409                         type = CodeUtils.extractTypeName(formalParameter.getParameterType());
   410                     }
   411                     if (name != null) {
   412                         if (!first) {
   413                             formatter.appendText("; "); //NOI18N
   414                         }
   415 
   416                         formatter.appendText(name);
   417 
   418                         if (type != null) {
   419                             formatter.appendText(" : ");   //NOI18N
   420                             FormalParameter.Mode mode = formalParameter.getParameterMode();
   421                             formatter.appendHtml(FONT_GRAY_COLOR);
   422                             if (mode == FormalParameter.Mode.IN) {
   423                                 formatter.appendText("in ");   //NOI18N
   424                             } else if (mode == FormalParameter.Mode.OUT) {
   425                                 formatter.appendText("out ");   //NOI18N
   426                             } else if (mode == FormalParameter.Mode.IN_OUT) {
   427                                 formatter.appendText("in out ");   //NOI18N
   428                             }
   429                             formatter.appendText(type);
   430                             formatter.appendHtml(CLOSE_FONT);
   431                         }
   432                         first = false;
   433                     }
   434                 }
   435             }
   436             formatter.appendText(")");   //NOI18N
   437 
   438             if (subprog.getSubtypeReturn() != null) {
   439                 String type = subprog.getSubtypeReturn().getName();
   440                 formatter.appendText(" : out ");   //NOI18N
   441                 formatter.appendHtml(FONT_GRAY_COLOR);
   442                 formatter.appendText(type);
   443                 formatter.appendHtml(CLOSE_FONT);
   444             }
   445 
   446         }
   447 
   448         protected void appendSubprogDescription(SubprogramBody subprog, HtmlFormatter formatter) {
   449             formatter.reset();
   450             if (subprog == null || subprog.getSubprogramSpecification().getSubprogramName() == null) {
   451                 return;
   452             }
   453             formatter.appendText(subprog.getSubprogramSpecification().getSubprogramName().getName());
   454             formatter.appendText("(");   //NOI18N
   455 
   456             List<FormalParameter> parameters = subprog.getSubprogramSpecification().getFormalParameters();
   457             if (parameters != null && parameters.size() > 0) {
   458                 boolean first = true;
   459                 for (FormalParameter formalParameter : parameters) {
   460                     String name = null;
   461                     Expression parameter = formalParameter.getParameterName();
   462                     if (parameter != null) {
   463                         Variable variable = null;
   464                         if (parameter instanceof Variable) {
   465                             variable = (Variable) parameter;
   466                         }
   467 
   468                         if (variable != null) {
   469                             name = ASTUtils.resolveVariableName(variable);
   470                         } else {
   471                             name = "??"; //NOI18N
   472                         }
   473                     }
   474                     String type = null;
   475                     if (formalParameter.getParameterType() != null) {
   476                         type = CodeUtils.extractTypeName(formalParameter.getParameterType());
   477                     }
   478                     if (name != null) {
   479                         if (!first) {
   480                             formatter.appendText("; "); //NOI18N
   481                         }
   482 
   483                         formatter.appendText(name);
   484 
   485                         if (type != null) {
   486                             formatter.appendText(" : ");   //NOI18N
   487                             FormalParameter.Mode mode = formalParameter.getParameterMode();
   488                             formatter.appendHtml(FONT_GRAY_COLOR);
   489                             if (mode == FormalParameter.Mode.IN) {
   490                                 formatter.appendText("in ");   //NOI18N
   491                             } else if (mode == FormalParameter.Mode.OUT) {
   492                                 formatter.appendText("out ");   //NOI18N
   493                             } else if (mode == FormalParameter.Mode.IN_OUT) {
   494                                 formatter.appendText("in out ");   //NOI18N
   495                             }
   496                             formatter.appendText(type);
   497                             formatter.appendHtml(CLOSE_FONT);
   498                         }
   499                         first = false;
   500                     }
   501                 }
   502             }
   503             formatter.appendText(")");   //NOI18N
   504 
   505             if (subprog.getSubprogramSpecification().getSubtypeReturn() != null) {
   506                 String type = subprog.getSubprogramSpecification().getSubtypeReturn().getName();
   507                 formatter.appendText(" : out ");   //NOI18N
   508                 formatter.appendHtml(FONT_GRAY_COLOR);
   509                 formatter.appendText(type);
   510                 formatter.appendHtml(CLOSE_FONT);
   511             }
   512         }
   513     }
   514 
   515     private class AdaTypeStructureItem extends AdaStructureItem {
   516 
   517         private static final String ADA_TYPE_ICON = "org/netbeans/modules/ada/editor/resources/icons/type_16.png"; //NOI18N
   518         private static final String ADA_TYPE_PRIVATE_ICON = "org/netbeans/modules/ada/editor/resources/icons/type_private_16.png"; //NOI18N
   519         private String simpleText;
   520 
   521         public AdaTypeStructureItem(AdaElementHandle elementHandle, String simpleText, String prefix) {
   522             super(elementHandle, null, prefix);
   523             this.simpleText = simpleText;
   524         }
   525 
   526         @Override
   527         public ImageIcon getCustomIcon() {
   528             Set<Modifier> modifiers = this.getModifiers();
   529 
   530             if (TYPE_ICON == null) {
   531                 TYPE_ICON = new ImageIcon(ImageUtilities.loadImage(ADA_TYPE_ICON));
   532             }
   533 
   534             ImageIcon icon = TYPE_ICON;
   535 
   536             for (Modifier modifier : modifiers) {
   537                 if (modifier == Modifier.PRIVATE) {
   538                     if (TYPE_PRIVATE_ICON == null) {
   539                         TYPE_PRIVATE_ICON = new ImageIcon(ImageUtilities.loadImage(ADA_TYPE_PRIVATE_ICON));
   540                     }
   541                     icon = TYPE_PRIVATE_ICON;
   542                 }
   543             }
   544             return icon;
   545         }
   546 
   547         public String getHtml(HtmlFormatter formatter) {
   548             formatter.appendText(simpleText);
   549             return formatter.getText();
   550         }
   551     }
   552 
   553     private class AdaSimpleStructureItem extends AdaStructureItem {
   554 
   555         private String simpleText;
   556 
   557         public AdaSimpleStructureItem(AdaElementHandle elementHandle, String simpleText, String prefix) {
   558             super(elementHandle, null, prefix);
   559             this.simpleText = simpleText;
   560         }
   561 
   562         public String getHtml(HtmlFormatter formatter) {
   563             formatter.appendText(simpleText);
   564             return formatter.getText();
   565         }
   566     }
   567 
   568     private class AdaSubprogSpecStructureItem extends AdaStructureItem {
   569 
   570         public AdaSubprogSpecStructureItem(AdaElementHandle elementHandle) {
   571             super(elementHandle, null, "subspc"); //NOI18N
   572         }
   573 
   574         public String getHtml(HtmlFormatter formatter) {
   575             formatter.reset();
   576             SubprogramSpecificationHandle handle = (SubprogramSpecificationHandle) getElementHandle();
   577             SubprogramSpecification subprog = (SubprogramSpecification) handle.getASTNode();
   578             appendSubprogDescription(subprog, formatter);
   579             return formatter.getText();
   580         }
   581     }
   582 
   583     private class AdaSubprogBodyStructureItem extends AdaStructureItem {
   584 
   585         public AdaSubprogBodyStructureItem(AdaElementHandle elementHandle) {
   586             super(elementHandle, null, "subbdy"); //NOI18N
   587         }
   588 
   589         public String getHtml(HtmlFormatter formatter) {
   590             formatter.reset();
   591             SubprogramBodyHandle handle = (SubprogramBodyHandle) getElementHandle();
   592             SubprogramBody subprog = (SubprogramBody) handle.getASTNode();
   593             appendSubprogDescription(subprog, formatter);
   594             return formatter.getText();
   595         }
   596     }
   597 
   598     private class AdaPackageSpecificationStructureItem extends AdaStructureItem {
   599 
   600         public AdaPackageSpecificationStructureItem(AdaElementHandle elementHandle, List<? extends StructureItem> children) {
   601             super(elementHandle, children, "pkgspc"); //NOI18N
   602         }
   603 
   604         public String getHtml(HtmlFormatter formatter) {
   605             formatter.reset();
   606             PackageSpecificationHandle handle = (PackageSpecificationHandle) getElementHandle();
   607             formatter.appendText(handle.getName());
   608             formatter.appendHtml(FONT_GRAY_COLOR + " (specification)" + CLOSE_FONT);
   609             return formatter.getText();
   610         }
   611     }
   612 
   613     private class AdaPackageBodyStructureItem extends AdaStructureItem {
   614 
   615         public AdaPackageBodyStructureItem(AdaElementHandle elementHandle, List<? extends StructureItem> children) {
   616             super(elementHandle, children, "pkgbdy"); //NOI18N
   617         }
   618 
   619         public String getHtml(HtmlFormatter formatter) {
   620             formatter.reset();
   621             PackageBodyHandle handle = (PackageBodyHandle) getElementHandle();
   622             formatter.appendText(handle.getName());
   623             formatter.appendHtml(FONT_GRAY_COLOR + " (body)" + CLOSE_FONT);
   624             return formatter.getText();
   625         }
   626     }
   627 
   628     private class AdaMethodSubprogSpecStructureItem extends AdaStructureItem {
   629 
   630         public AdaMethodSubprogSpecStructureItem(AdaElementHandle elementHandle) {
   631             super(elementHandle, null, "subspc"); //NOI18N
   632         }
   633 
   634         public String getHtml(HtmlFormatter formatter) {
   635             formatter.reset();
   636             MethodSubprogSpecHandle handle = (MethodSubprogSpecHandle) getElementHandle();
   637             MethodDeclaration method = (MethodDeclaration) handle.getASTNode();
   638             appendSubprogDescription(method.getSubprogramSpecification(), formatter);
   639             return formatter.getText();
   640         }
   641     }
   642 
   643     private class AdaMethodSubprogBodyStructureItem extends AdaStructureItem {
   644 
   645         public AdaMethodSubprogBodyStructureItem(AdaElementHandle elementHandle) {
   646             super(elementHandle, null, "subbdy"); //NOI18N
   647         }
   648 
   649         public String getHtml(HtmlFormatter formatter) {
   650             formatter.reset();
   651             MethodSubprogBodyHandle handle = (MethodSubprogBodyHandle) getElementHandle();
   652             MethodDeclaration method = (MethodDeclaration) handle.getASTNode();
   653             appendSubprogDescription(method.getSubprogramBody(), formatter);
   654             return formatter.getText();
   655         }
   656     }
   657 
   658     private class FoldVisitor extends DefaultVisitor {
   659 
   660         final Map<String, List<OffsetRange>> folds;
   661         private String foldType;
   662 
   663         public FoldVisitor(Map<String, List<OffsetRange>> folds) {
   664             this.folds = folds;
   665             this.foldType = null;
   666 
   667         }
   668 
   669         @Override
   670         public void visit(PackageSpecification pkgspc) {
   671             this.foldType = FOLD_PACKAGE;
   672             if (pkgspc.getBody() != null) {
   673                 scan(pkgspc.getBody());
   674             }
   675         }
   676 
   677         @Override
   678         public void visit(PackageBody pkgbdy) {
   679             this.foldType = FOLD_PACKAGE;
   680             if (pkgbdy.getBody() != null) {
   681                 scan(pkgbdy.getBody());
   682             }
   683         }
   684 
   685         @Override
   686         public void visit(Block block) {
   687             if (foldType != null) {
   688                 getRanges(folds, foldType).add(createOffsetRange(block));
   689                 foldType = null;
   690             }
   691             if (block.getStatements() != null) {
   692                 scan(block.getStatements());
   693             }
   694         }
   695 
   696         @Override
   697         public void visit(BlockStatement block) {
   698             if (foldType != null) {
   699                 getRanges(folds, foldType).add(createOffsetRange(block));
   700                 foldType = null;
   701             }
   702             if (block.getDeclarations() != null) {
   703                 scan(block.getDeclarations());
   704             }
   705             if (block.getBody() != null) {
   706                 scan(block.getBody());
   707             }
   708         }
   709 
   710         @Override
   711         public void visit(SubprogramBody subprog) {
   712             foldType = FOLD_CODE_BLOCKS;
   713             if (subprog.getDeclarations() != null) {
   714                 scan(subprog.getDeclarations());
   715             }
   716             foldType = FOLD_CODE_BLOCKS;
   717             if (subprog.getBody() != null) {
   718                 scan(subprog.getBody());
   719             }
   720         }
   721     }
   722 }