blob: d5b10e85eb37b6b910a7de6052fd066de05f0c6f [file] [log] [blame]
/**********************************************************************
* This file is part of "Object Teams Development Tooling"-Software
*
* Copyright 2006 Fraunhofer Gesellschaft, Munich, Germany,
* for its Fraunhofer Institute for Computer Architecture and Software
* Technology (FIRST), Berlin, Germany and Technical University Berlin,
* Germany.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
* $Id: FileInfo.java 23417 2010-02-03 20:13:55Z stephan $
*
* Please visit http://www.eclipse.org/objectteams for updates and contact.
*
* Contributors:
* Fraunhofer FIRST - Initial API and implementation
* Technical University Berlin - Initial API and implementation
**********************************************************************/
package org.eclipse.objectteams.otdt.internal.core.compiler.smap;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.TreeMap;
/** Represents the filesection part, specified in JSR-045-Spec. Almost a copy of
* org.eclipse.jdi.internal.ReferenceTypeImpl.FileInfo
*
* @author ike
*/
public class FileInfo
{
/**
* The id.
*/
private int _fileId;
/**
* The name of the source file.
*/
private String _fileName;
/**
* The path of the source file.
*/
private String _absoluteFileName;
/**
* Map line number in the input source file ->
* list of [ InputStartLine, RepeatCount, OutputStartLine, OutputLineIncrement].
* (Integer -> List of lineInfos).
*
* non-null
*/
private TreeMap <Integer,List<LineInfo>> _lineInfos;
/**
* FileInfo constructor.
*
* @param fileId
* the id.
* @param fileName
* the name of the source file.
* @param absoluteFileName
* the path of the source file (can be <code>null</code>).
*/
public FileInfo(int fileId, String fileName, String absoluteFileName)
{
this._fileId = fileId;
this._fileName = fileName;
this._absoluteFileName = absoluteFileName;
this._lineInfos = new TreeMap<Integer, List<LineInfo>>();
}
public void addLineInfo(LineInfo lineInfo)
{
Integer key = new Integer(lineInfo.getInputStartLine());
List <LineInfo>lineInfosForInputStartLine = this._lineInfos.get(key);
if (lineInfosForInputStartLine == null)
{
lineInfosForInputStartLine = new ArrayList<LineInfo>();
this._lineInfos.put(key, lineInfosForInputStartLine);
}
lineInfosForInputStartLine.add(lineInfo);
}
public void addLineInfo(List<LineInfo> lineInfos)
{
for (Iterator<LineInfo> iter = lineInfos.iterator(); iter.hasNext();)
addLineInfo(iter.next());
}
/**
* Return a list of line information about the code in the output source
* file associated to the given line in the input source file.
*
* @param intputStartLine
* the line number in the input source file.
* @return a List lineInfos.
*/
public List<LineInfo> getLinesForInputStartLine(int intputStartLine)
{
return this._lineInfos.get(new Integer(intputStartLine));
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object object)
{
if (!(object instanceof FileInfo))
{
return false;
}
FileInfo fileInfo = (FileInfo)object;
if (this._fileId != fileInfo._fileId)
{
return false;
}
if (this._absoluteFileName != null)
{
if (!this._absoluteFileName.equals(fileInfo._absoluteFileName))
{
return false;
}
}
if (!this._fileName.equals(fileInfo._fileName))
{
return false;
}
TreeMap<Integer,List<LineInfo>> map = fileInfo._lineInfos;
// both lineInfos are non-null
if (map.size() != this._lineInfos.size())
return false;
for (Iterator<Integer> iter = this._lineInfos.keySet().iterator(); iter.hasNext();)
{
Integer key = iter.next();
List<LineInfo> value = this._lineInfos.get(key);
List<LineInfo> mapValue = map.get(key);
if ((value == null) != (mapValue == null)) {
return false; // null vs. non-null
} else if (value == null || mapValue == null) { // second check is redundant, helps null-analysis below
return true; // both null
}
if (value.size() != mapValue.size())
{
return false;
}
for (int idx = 0; idx < value.size(); idx++)
{
LineInfo listEntries1 = value.get(idx);
LineInfo listEntries2 = mapValue.get(idx);
if (!listEntries1.equals(listEntries2))
{
return false;
}
}
}
return true;
}
@SuppressWarnings("nls")
public String getFileInfoDataAsString()
{
StringBuffer out = new StringBuffer();
for (Iterator<Integer> iter = this._lineInfos.keySet().iterator(); iter.hasNext();)
{
Integer inputStartLine = iter.next();
List<LineInfo> lineInfos = this._lineInfos.get(inputStartLine);
for (int idx = 0; idx < lineInfos.size(); idx++)
{
LineInfo singleLineInfo = lineInfos.get(idx);
out.append(inputStartLine + "#" + this._fileId);
if (singleLineInfo.hasRepeatCount())
{
out.append(",");
out.append(singleLineInfo.getRepeatCount());
}
out.append(":");
out.append(singleLineInfo.getOutputStartLine());
if (singleLineInfo.hasOutputLineIncrement())
out.append("," + singleLineInfo.getOutputLineIncrement());
out.append("\n");
}
}
return out.toString();
}
@Override
public String toString()
{
return getFileInfoDataAsString();
}
public int getFileId()
{
return this._fileId;
}
public String getFileName()
{
return this._fileName;
}
public String getAbsoluteFileName()
{
return this._absoluteFileName;
}
public boolean hasLineInfos()
{
if ( this._lineInfos.isEmpty())
return false;
return true;
}
public void optimizeLineInfos()
{
TreeMap<Integer, List<LineInfo>> optimizedLineInfos = new TreeMap<Integer, List<LineInfo>>();
for (Iterator<Integer> iter = this._lineInfos.keySet().iterator(); iter.hasNext();)
{
Integer key = iter.next();
List <LineInfo> listofLineInfos = this._lineInfos.get(key);
if (listofLineInfos.size() > 1)
{
List <LineInfo> optimizedSimliarLineInfos = optimizeListOfSimilarLineInfos(listofLineInfos);
this._lineInfos.put(key, optimizedSimliarLineInfos);
}
}
Integer firstKey = this._lineInfos.firstKey();
List <LineInfo> listofFirstLineInfos = cloneLineInfos(this._lineInfos.get(firstKey));
LineInfo firstLineInfo = listofFirstLineInfos.get(0);
optimizedLineInfos.put(firstKey, listofFirstLineInfos);
Integer[] keys = this._lineInfos.keySet().toArray(new Integer[this._lineInfos.size()]);
for (int idx = 1; idx < keys.length; idx++)
{
Integer iterKey1 = keys[idx];
List <LineInfo> iterKey1ListofLineInfos = this._lineInfos.get(iterKey1);
LineInfo iterKey1LineInfo = iterKey1ListofLineInfos.get(0);
Integer iterKey2 = keys[idx-1];
List <LineInfo> iterKey2ListofLineInfos = this._lineInfos.get(iterKey2);
LineInfo iterKey2LineInfo = iterKey2ListofLineInfos.get(0);
if(iterKey1LineInfo.isPreviousLineInfo(firstLineInfo))
{
int oldRepeatCount = firstLineInfo.getRepeatCount();
int newRepeatCount = oldRepeatCount == -1 ? 2 : oldRepeatCount +1;
firstLineInfo.setRepeatCount(newRepeatCount);
}
else
{
if (iterKey1LineInfo.isPreviousLineInfo(iterKey2LineInfo))
{
int oldRepeatCount = firstLineInfo.getRepeatCount();
int newRepeatCount = oldRepeatCount == -1 ? 1 : oldRepeatCount + 1;
firstLineInfo.setRepeatCount(newRepeatCount);
}
else
{
firstKey = iterKey1;
listofFirstLineInfos = cloneLineInfos(this._lineInfos.get(firstKey));
firstLineInfo = listofFirstLineInfos.get(0);
optimizedLineInfos.put(firstKey, listofFirstLineInfos);
}
}
}
this._lineInfos = optimizedLineInfos;
}
private List<LineInfo> cloneLineInfos(List<LineInfo> listofLineInfos)
{
List <LineInfo> clonedList = new ArrayList<LineInfo>();
for (int idx = 0; idx < listofLineInfos.size(); idx++)
{
LineInfo lineInfo = listofLineInfos.get(idx);
LineInfo copiedLineInfo = lineInfo.clone();
clonedList.add(copiedLineInfo);
}
return clonedList;
}
/** Filter doubled entries in smap.
*
*/
private List<LineInfo> optimizeListOfSimilarLineInfos(List<LineInfo> listofLineInfos)
{
List<LineInfo> optimizedListOfSimilarLineInfos = new ArrayList<LineInfo>();
LineInfo lineInfo = listofLineInfos.get(0);
optimizedListOfSimilarLineInfos.add(lineInfo);
for (Iterator<LineInfo> iter = listofLineInfos.iterator(); iter.hasNext();)
{
LineInfo tmpLineInfo = iter.next();
if (!lineInfo.equals(tmpLineInfo) && !optimizedListOfSimilarLineInfos.contains(tmpLineInfo))
optimizedListOfSimilarLineInfos.add(tmpLineInfo);
}
return optimizedListOfSimilarLineInfos;
}
protected boolean isEqualTo(String fileName, String absoluteFileName) {
return this._fileName.equals(fileName) && this._absoluteFileName.equals(absoluteFileName);
}
}