如何在源代码文件中检测每个JavaDoc块的开始和结束行?

时间:2014-01-23 15:21:50

标签: java parsing javadoc

我正在创建一个解析实用程序,用于读取(一个)Java源代码文件的副本,并在JavaDoc块中的某些点插入一些额外信息重新输出它。

第一步是弄清楚每个JavaDoc块的开始和结束位置。下面是我写的代码。

我希望这有助于某人。

2 个答案:

答案 0 :(得分:0)

这将获取Java源代码文件的路径,并为每个找到的JavaDoc块输出开始和结束行。

   import  java.io.File;
   import  java.io.IOException;
   import  java.util.regex.Pattern;
   import  org.apache.commons.io.FileUtils;
   import  org.apache.commons.io.LineIterator;
   import  xbn.io.RTIOException;
/**
   <P>Prints the start and end line-numbers for all JavaDoc blocks in a Java source-code file. The one and only parameter is the path to the file. This assumes that the JavaDoc open-comment (slash-asterisk-asterisk) is the first non-whitespace on its line. The end comment (asterisk-slash) may be anywhere on the line.</P>

   java PrintJDBlocksStartStopLineNumsXmpl C:\java_code\PrintJDBlocksStartStopLineNumsXmpl.java
 **/
 public class PrintJDBlocksStartStopLineNumsXmpl  {
    /**
       <P>The main function.</P>
     **/
    public static final void main(String[] as_1RqdJavaSourcePath)  {

       //Read command-line parameter
          String sJPath = null;
          try  {
             sJPath = as_1RqdJavaSourcePath[0];
          }  catch(ArrayIndexOutOfBoundsException aibx)  {
             throw  new NullPointerException("Missing one-and-only required parameter: Path to java source-code file.");
          }
          System.out.println("Java source: " + sJPath);

       //Establish line-iterator
          LineIterator li = null;
          try  {
             li = FileUtils.lineIterator(new File(sJPath)); //Throws npx if null
          }  catch(IOException iox)  {
             throw  new RTIOException("PrintJDBlocksStartStopLinesXmpl", iox);
          }
          Pattern pTrmdJDBlockStart = Pattern.compile("^[\\t ]*/\\*\\*");

       String sDD = "..";
       int iLn = 1;
       boolean bInJDBlock = false;
       while(li.hasNext())  {
          String sLn = li.nextLine();
          if(!bInJDBlock)  {
             if(pTrmdJDBlockStart.matcher(sLn).matches())  {
                bInJDBlock = true;
                System.out.print(iLn + sDD);
             }
          }  else if(sLn.indexOf("*/") != -1)  {
             bInJDBlock = false;
             System.out.println(iLn);
          }
          iLn++;
       }
       if(bInJDBlock)  {
          throw  new IllegalStateException("Reach end of file. JavaDoc not closed.");
       }
    }
    /**
       <P>Another one</P>
     **/
    private static final void oneMoreForGoodMeasure()  {
    }
}

输出:

[C:\java_code]java PrintJDBlocksStartStopLineNumsXmpl C:\java_code\PrintJDBlocksStartStopLineNumsXmpl.java
Java source: C:\java_code\PrintJDBlocksStartStopLineNumsXmpl.java
8..12
14..16
54..56

答案 1 :(得分:0)

我的原始答案是创建FilteredLineIterator的第一步。

FilteredLineIterator过滤另一个字符串迭代器(通常是文本文件中的行),根据存在的实体保留或丢弃每一行:“blocks”,“single line”和“stealth block” “实体。每条保留的线都可以改变。

FilteredLineIteratorXBN-Java的一部分。下载必要的广告here。)

以下示例声明了“JavaDoc块”block entity和“Java多行注释”stealth entity。隐藏实体是必要的,以避免非JavaDoc注释块中的最后一行错误地导致“在块打开之前找到结束行”错误(因为JavaDoc和非JavaDoc注释块都以*/结束)。

   import  com.github.xbn.linefilter.entity.KeepMatched;
   import  com.github.xbn.linefilter.entity.EntityRequired;
   import  com.github.xbn.linefilter.FilteredLineIterator;
   import  com.github.xbn.linefilter.KeepUnmatched;
   import  com.github.xbn.linefilter.Returns;
   import  com.github.xbn.linefilter.entity.BlockEntity;
   import  com.github.xbn.linefilter.entity.NewBlockEntityFor;
   import  com.github.xbn.linefilter.entity.NewStealthBlockEntityFor;
   import  com.github.xbn.linefilter.entity.StealthBlockEntity;
   import  com.github.xbn.testdev.GetFromCommandLineAtIndex;
   import  com.github.xbn.util.IncludeJavaDoc;
   import  java.util.Iterator;
/**
   <P>{@code java PrintAllJavaDocBlockStartAndEndLineNums C:\java_code\example_input\JavaClassWithOneCommentAndTwoJavaDocBlocks_input.txt}</P>
 **/
public class PrintAllJavaDocBlockStartAndEndLineNums  {
   public static final void main(String[] cmd_lineParams)  {
      //Example setup
         Iterator<String> itr = GetFromCommandLineAtIndex.fileLineIterator(
            cmd_lineParams, 0,
            null);     //debugPath

正确的例子:

      StealthBlockEntity javaMlcStealth = NewStealthBlockEntityFor.javaComment(
         "comment", IncludeJavaDoc.NO,
         null,         //dbgStart (on:System.out, off:null)
         null,         //dbgEnd
         KeepMatched.YES, EntityRequired.YES, null,
         null);        //dbgLineNums

      BlockEntity javaDocBlock = NewBlockEntityFor.javaDocComment_Cfg(
         "doccomment",
         null,       //dbgStart
         null,       //dbgEnd
         EntityRequired.YES, null,
         null).      //dbgLineNums
         keepAll().build();

      FilteredLineIterator filteredItr = new FilteredLineIterator(
         itr, Returns.KEPT, KeepUnmatched.NO,
         null, null,    //dbgEveryLine and its line-range
         javaMlcStealth, javaDocBlock);

      while(filteredItr.hasNext())  {
         filteredItr.next();

         if(filteredItr.getActiveChildType().isBlock()  &&
               filteredItr.getActiveChildBlock().isStartLine())  {
            System.out.print("Block: " + filteredItr.getNextLineNum() + "..");

         }  else if(filteredItr.getActiveChildType().isBlock()  &&
               filteredItr.getActiveChildBlock().isEndLine())  {
            System.out.println(filteredItr.getNextLineNum());
         }
      }
   }
}

输出:

Block: 9..11
Block: 13..24
Block: 28..30

另一种方法是使用自动调试打印块行号:

BlockEntity javaDocBlock = NewBlockEntityFor.javaDocComment_Cfg(
   "doccomment",
   null,       //dbgStart
   null,       //dbgEnd
   EntityRequired.YES, null,
   System.out).   //<--Automated line-number debugging
   keepAll().build();

FilteredLineIterator filteredItr = new FilteredLineIterator...

while(filteredItr.hasNext())  {
   filteredItr.next();
} 

输出:

[9:BLOCK:"doccomment"] block-start
[11:BLOCK:"doccomment":active] block end
[13:BLOCK:"doccomment"] block-start
[24:BLOCK:"doccomment":active] block end
[28:BLOCK:"doccomment"] block-start
[30:BLOCK:"doccomment":active] block end

输入文件:

/*
   Not a JavaDoc block. The following sub-mode is ignored, because it's not in a JavaDoc block.

      //sub-mode...START

      //sub-mode...END
 */
package  fully.qualified.package.name;
/**
  <P>A JavaDoc block</P>
 */
public class StayClassy  {
   /**
      <P>Another JavaDoc block</P>

      <P>info</P>        //sub-mode...START

      <P>info</P>

      <P>info</P>        //sub-mode...END

      <P>info</P>

    */
   public StayClassy()  {
      //Do stuff
   }
   /**
     <P>Does stuff.</P>
    */
   public void doStuff()  {
   }
}