1 /*
   2  * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package vm.mlvm.tools;
  25 
  26 import java.util.HashMap;
  27 import java.util.Map;
  28 import java.util.Set;
  29 import java.util.TreeSet;
  30 
  31 import com.sun.source.tree.CompilationUnitTree;
  32 import com.sun.source.tree.LabeledStatementTree;
  33 import com.sun.source.util.TreePathScanner;
  34 import com.sun.source.util.Trees;
  35 
  36 public class StratumAPTreeVisitor extends TreePathScanner<Object, Trees> {
  37     public static final String LABEL_PREFIX = "Stratum_";
  38 
  39     public static class StratumLineInfo implements Comparable<StratumLineInfo> {
  40         String stratumName;
  41         int stratumLineOrder;
  42         String stratumLine;
  43         int javaLineNum;
  44 
  45         public StratumLineInfo(String stratumName, int stratumLineOrder, String stratumLine, int javaLineNum) {
  46             this.stratumName = stratumName;
  47             this.stratumLineOrder = stratumLineOrder;
  48             this.stratumLine = stratumLine;
  49             this.javaLineNum = javaLineNum;
  50         }
  51 
  52         public String getStratumName() {
  53             return stratumName;
  54         }
  55 
  56         public int getStratumLineOrder() {
  57             return stratumLineOrder;
  58         }
  59 
  60         public String getStratumSourceLine() {
  61             return stratumLine;
  62         }
  63 
  64         public int getJavaLineNum() {
  65             return javaLineNum;
  66         }
  67 
  68         @Override
  69         public int compareTo(StratumLineInfo o) {
  70             int i;
  71             if ( (i = getStratumName().compareTo(o.getStratumName())) != 0 )
  72                 return i;
  73 
  74             if ( (i = getStratumLineOrder() - o.getStratumLineOrder()) != 0 )
  75                 return i;
  76 
  77             return 0;
  78         }
  79 
  80         @Override
  81         public String toString() {
  82             return getStratumName() + ":" + getStratumLineOrder()
  83                  + " =>  Java:" + getJavaLineNum()
  84                  + " [" + getStratumSourceLine() + "]";
  85         }
  86     }
  87 
  88     public Map<String, Set<StratumLineInfo>> strata = new HashMap<String, Set<StratumLineInfo>>();
  89 
  90     @Override
  91     public Object visitLabeledStatement(LabeledStatementTree node, Trees p) {
  92         processLabel(node, p);
  93         return super.visitLabeledStatement(node, p);
  94     }
  95 
  96     private void processLabel(LabeledStatementTree node, Trees p) {
  97         String label = node.getLabel().toString();
  98 
  99         if ( ! label.startsWith(LABEL_PREFIX) )
 100             return;
 101 
 102         int stratumNameEndPos = label.indexOf('_', LABEL_PREFIX.length());
 103         if ( stratumNameEndPos == -1 )
 104             return;
 105 
 106         String stratumName = label.substring(LABEL_PREFIX.length(), stratumNameEndPos);
 107 
 108         int stratumLineEndPos = label.indexOf('_', stratumNameEndPos + 1);
 109         if ( stratumLineEndPos == -1 )
 110             return;
 111 
 112         String stratumLineNumStr = label.substring(stratumNameEndPos + 1, stratumLineEndPos);
 113         int stratumLineNum = Integer.parseInt(stratumLineNumStr);
 114 
 115         String stratumLine = label.substring(stratumLineEndPos + 1);
 116 
 117         CompilationUnitTree unit = getCurrentPath().getCompilationUnit();
 118         int javaLineNum = (int) unit.getLineMap().getLineNumber(p.getSourcePositions().getStartPosition(unit, node));
 119 
 120         Set<StratumLineInfo> stratumLines = this.strata.get(stratumName);
 121         if ( stratumLines == null ) {
 122             stratumLines = new TreeSet<StratumLineInfo>();
 123             this.strata.put(stratumName, stratumLines);
 124         }
 125 
 126         stratumLines.add(new StratumLineInfo(stratumName, stratumLineNum, stratumLine, javaLineNum));
 127     }
 128 }