Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/sde/SmapStratum.java
41162 views
/*1* Copyright (c) 2007, 2018, 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.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/22package nsk.share.jdi.sde;2324import java.util.ArrayList;25import java.util.List;2627/**28* Represents the line and file mappings associated with a JSR-04529* "stratum".30*/31public class SmapStratum32{3334//*********************************************************************35// Class for storing LineInfo data3637/**38* Represents a single LineSection in an SMAP, associated with39* a particular stratum.40*/41public static class LineInfo {42private int inputStartLine = -1;43private int outputStartLine = -1;44private int lineFileID = 0;45private int inputLineCount = 1;46private int outputLineIncrement = 1;47private boolean lineFileIDSet = false;4849/** Sets InputStartLine. */50public void setInputStartLine(int inputStartLine) {51if (inputStartLine < 0)52throw new IllegalArgumentException("" + inputStartLine);53this.inputStartLine = inputStartLine;54}5556/** Sets OutputStartLine. */57public void setOutputStartLine(int outputStartLine) {58if (outputStartLine < 0)59throw new IllegalArgumentException("" + outputStartLine);60this.outputStartLine = outputStartLine;61}6263/**64* Sets lineFileID. Should be called only when different from65* that of prior LineInfo object (in any given context) or 066* if the current LineInfo has no (logical) predecessor.67* <tt>LineInfo</tt> will print this file number no matter what.68*/69public void setLineFileID(int lineFileID) {70if (lineFileID < 0)71throw new IllegalArgumentException("" + lineFileID);72this.lineFileID = lineFileID;73this.lineFileIDSet = true;74}7576/** Sets InputLineCount. */77public void setInputLineCount(int inputLineCount) {78if (inputLineCount < 0)79throw new IllegalArgumentException("" + inputLineCount);80this.inputLineCount = inputLineCount;81}8283/** Sets OutputLineIncrement. */84public void setOutputLineIncrement(int outputLineIncrement) {85if (outputLineIncrement < 0)86throw new IllegalArgumentException("" + outputLineIncrement);87this.outputLineIncrement = outputLineIncrement;88}8990/**91* Retrieves the current LineInfo as a String, print all values92* only when appropriate (but LineInfoID if and only if it's been93* specified, as its necessity is sensitive to context).94*/95public String getString() {96if (inputStartLine == -1 || outputStartLine == -1)97throw new IllegalStateException();98StringBuffer out = new StringBuffer();99out.append(inputStartLine);100if (lineFileIDSet)101out.append("#" + lineFileID);102if (inputLineCount != 1)103out.append("," + inputLineCount);104out.append(":" + outputStartLine);105if (outputLineIncrement != 1)106out.append("," + outputLineIncrement);107out.append('\n');108return out.toString();109}110111public String toString() {112return getString();113}114}115116//*********************************************************************117// Private state118119private String stratumName;120private List<String> fileNameList;121private List<String> filePathList;122private List<LineInfo> lineData;123private int lastFileID;124125//*********************************************************************126// Constructor127128/**129* Constructs a new SmapStratum object for the given stratum name130* (e.g., JSP).131*132* @param stratumName the name of the stratum (e.g., JSP)133*/134public SmapStratum(String stratumName) {135this.stratumName = stratumName;136fileNameList = new ArrayList<String>();137filePathList = new ArrayList<String>();138lineData = new ArrayList<LineInfo>();139lastFileID = 0;140}141142//*********************************************************************143// Methods to add mapping information144145/**146* Adds record of a new file, by filename.147*148* @param filename the filename to add, unqualified by path.149*/150public void addFile(String filename) {151addFile(filename, filename);152}153154/**155* Adds record of a new file, by filename and path. The path156* may be relative to a source compilation path.157*158* @param filename the filename to add, unqualified by path159* @param filePath the path for the filename, potentially relative160* to a source compilation path161*/162public void addFile(String filename, String filePath) {163int pathIndex = filePathList.indexOf(filePath);164if (pathIndex == -1) {165fileNameList.add(filename);166filePathList.add(filePath);167}168}169170/**171* Adds complete information about a simple line mapping. Specify172* all the fields in this method; the back-end machinery takes care173* of printing only those that are necessary in the final SMAP.174* (My view is that fields are optional primarily for spatial efficiency,175* not for programmer convenience. Could always add utility methods176* later.)177*178* @param inputStartLine starting line in the source file179* (SMAP <tt>InputStartLine</tt>)180* @param inputFileName the filepath (or name) from which the input comes181* (yields SMAP <tt>LineFileID</tt>) Use unqualified names182* carefully, and only when they uniquely identify a file.183* @param inputLineCount the number of lines in the input to map184* (SMAP <tt>LineFileCount</tt>)185* @param outputStartLine starting line in the output file186* (SMAP <tt>OutputStartLine</tt>)187* @param outputLineIncrement number of output lines to map to each188* input line (SMAP <tt>OutputLineIncrement</tt>). <i>Given the189* fact that the name starts with "output", I continuously have190* the subconscious urge to call this field191* <tt>OutputLineExcrement</tt>.</i>192*/193public void addLineData(194int inputStartLine,195String inputFileName,196int inputLineCount,197int outputStartLine,198int outputLineIncrement) {199// check the input - what are you doing here??200int fileIndex = fileNameList.indexOf(inputFileName);201if (fileIndex == -1) // still202throw new IllegalArgumentException(203"inputFileName: " + inputFileName);204205//Jasper incorrectly SMAPs certain Nodes, giving them an206//outputStartLine of 0. This can cause a fatal error in207//optimizeLineSection, making it impossible for Jasper to208//compile the JSP. Until we can fix the underlying209//SMAPping problem, we simply ignore the flawed SMAP entries.210if (outputStartLine == 0)211return;212213// build the LineInfo214LineInfo li = new LineInfo();215li.setInputStartLine(inputStartLine);216li.setInputLineCount(inputLineCount);217li.setOutputStartLine(outputStartLine);218li.setOutputLineIncrement(outputLineIncrement);219if (fileIndex != lastFileID)220li.setLineFileID(fileIndex);221lastFileID = fileIndex;222223// save it224lineData.add(li);225}226227//*********************************************************************228// Methods to retrieve information229230/**231* Returns the name of the stratum.232*/233public String getStratumName() {234return stratumName;235}236237/**238* Returns the given stratum as a String: a StratumSection,239* followed by at least one FileSection and at least one LineSection.240*/241public String getString() {242// check state and initialize buffer243if (fileNameList.size() == 0 || lineData.size() == 0)244return null;245246StringBuffer out = new StringBuffer();247248// print StratumSection249out.append("*S " + stratumName + "\n");250251// print FileSection252out.append("*F\n");253int bound = fileNameList.size();254for (int i = 0; i < bound; i++) {255if (filePathList.get(i) != null) {256out.append("+ " + i + " " + fileNameList.get(i) + "\n");257// Source paths must be relative, not absolute, so we258// remove the leading "/", if one exists.259String filePath = (String)filePathList.get(i);260if (filePath.startsWith("/")) {261filePath = filePath.substring(1);262}263out.append(filePath + "\n");264} else {265out.append(i + " " + fileNameList.get(i) + "\n");266}267}268269// print LineSection270out.append("*L\n");271bound = lineData.size();272for (int i = 0; i < bound; i++) {273LineInfo li = (LineInfo)lineData.get(i);274out.append(li.getString());275}276277return out.toString();278}279280public String toString() {281return getString();282}283284}285286287