decompiler: move generated lines as it is stated in debug line table (disabled for now)
This commit is contained in:
163
src/org/jetbrains/java/decompiler/main/TextBuffer.java
Normal file
163
src/org/jetbrains/java/decompiler/main/TextBuffer.java
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.java.decompiler.main;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Allows to connect text with resulting lines
|
||||
*
|
||||
* @author egor
|
||||
*/
|
||||
public class TextBuffer {
|
||||
private final String myLineSeparator = DecompilerContext.getNewLineSeparator();
|
||||
private final StringBuilder myStringBuilder;
|
||||
private Map<Integer, Integer> myLineToOffsetMapping = null;
|
||||
|
||||
public TextBuffer() {
|
||||
myStringBuilder = new StringBuilder();
|
||||
}
|
||||
|
||||
public TextBuffer(int size) {
|
||||
myStringBuilder = new StringBuilder(size);
|
||||
}
|
||||
|
||||
public void setCurrentLine(int line) {
|
||||
if (line >= 0) {
|
||||
checkMapCreated();
|
||||
myLineToOffsetMapping.put(line, myStringBuilder.length()+1);
|
||||
}
|
||||
}
|
||||
|
||||
public TextBuffer append(String str) {
|
||||
myStringBuilder.append(str);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextBuffer append(char ch) {
|
||||
myStringBuilder.append(ch);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextBuffer appendLineSeparator() {
|
||||
myStringBuilder.append(myLineSeparator);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void addBanner(String banner) {
|
||||
myStringBuilder.insert(0, banner);
|
||||
if (myLineToOffsetMapping != null) {
|
||||
for (Integer line : myLineToOffsetMapping.keySet()) {
|
||||
myLineToOffsetMapping.put(line, myLineToOffsetMapping.get(line) + banner.length());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String original = myStringBuilder.toString();
|
||||
if (myLineToOffsetMapping == null || myLineToOffsetMapping.isEmpty()) {
|
||||
return original;
|
||||
}
|
||||
else {
|
||||
StringBuilder res = new StringBuilder();
|
||||
String[] srcLines = original.split(myLineSeparator);
|
||||
int currentLineStartOffset = 0;
|
||||
int currentLine = 0;
|
||||
int previousMarkLine = 0;
|
||||
int dumpedLines = 0;
|
||||
ArrayList<Integer> linesWithMarks = new ArrayList<Integer>(myLineToOffsetMapping.keySet());
|
||||
Collections.sort(linesWithMarks);
|
||||
for (Integer markLine : linesWithMarks) {
|
||||
Integer markOffset = myLineToOffsetMapping.get(markLine);
|
||||
while (currentLine < srcLines.length) {
|
||||
String line = srcLines[currentLine];
|
||||
int lineEnd = currentLineStartOffset + line.length() + myLineSeparator.length();
|
||||
if (markOffset >= currentLineStartOffset && markOffset <= lineEnd) {
|
||||
int requiredLinesNumber = markLine - dumpedLines;
|
||||
dumpedLines = markLine;
|
||||
appendLines(res, srcLines, previousMarkLine, currentLine, requiredLinesNumber);
|
||||
previousMarkLine = currentLine;
|
||||
break;
|
||||
}
|
||||
currentLineStartOffset = lineEnd;
|
||||
currentLine++;
|
||||
}
|
||||
}
|
||||
if (previousMarkLine < srcLines.length) {
|
||||
appendLines(res, srcLines, previousMarkLine, srcLines.length, srcLines.length - previousMarkLine);
|
||||
}
|
||||
|
||||
return res.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private void appendLines(StringBuilder res, String[] srcLines, int from, int to, int requiredLineNumber) {
|
||||
if (to - from > requiredLineNumber) {
|
||||
int separatorsRequired = to - from - requiredLineNumber - 1;
|
||||
for (int i = from; i < to; i++) {
|
||||
res.append(srcLines[i]);
|
||||
if (separatorsRequired-- > 0) {
|
||||
res.append(myLineSeparator);
|
||||
}
|
||||
}
|
||||
res.append(myLineSeparator);
|
||||
}
|
||||
else if (to - from <= requiredLineNumber) {
|
||||
for (int i = from; i < to; i++) {
|
||||
res.append(srcLines[i]).append(myLineSeparator);
|
||||
}
|
||||
for (int i = 0; i < requiredLineNumber - to + from; i++) {
|
||||
res.append(myLineSeparator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return myStringBuilder.length();
|
||||
}
|
||||
|
||||
public String substring(int start) {
|
||||
return myStringBuilder.substring(start);
|
||||
}
|
||||
|
||||
public void setLength(int position) {
|
||||
myStringBuilder.setLength(position);
|
||||
}
|
||||
|
||||
public void append(TextBuffer buffer) {
|
||||
if (buffer.myLineToOffsetMapping != null && !buffer.myLineToOffsetMapping.isEmpty()) {
|
||||
checkMapCreated();
|
||||
for (Map.Entry<Integer, Integer> entry : buffer.myLineToOffsetMapping.entrySet()) {
|
||||
myLineToOffsetMapping.put(entry.getKey(), entry.getValue() + myStringBuilder.length());
|
||||
}
|
||||
}
|
||||
myStringBuilder.append(buffer.myStringBuilder);
|
||||
}
|
||||
|
||||
private void checkMapCreated() {
|
||||
if (myLineToOffsetMapping == null) {
|
||||
myLineToOffsetMapping = new HashMap<Integer, Integer>();
|
||||
}
|
||||
}
|
||||
|
||||
public void insert(int offset, String s) {
|
||||
if (myLineToOffsetMapping != null) {
|
||||
throw new IllegalStateException("insert not yet supported with Line mapping");
|
||||
}
|
||||
myStringBuilder.insert(offset, s);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user