diff options
author | Egor.Ushakov <egor.ushakov@jetbrains.com> | 2014-10-07 20:37:21 +0400 |
---|---|---|
committer | Egor.Ushakov <egor.ushakov@jetbrains.com> | 2014-10-07 20:39:03 +0400 |
commit | 125441a88fc58f74ecfe2c1081a04b6c4d05ea61 (patch) | |
tree | be047a9e4ff42d483fd6f135e740038671af6ee8 /src/org/jetbrains/java/decompiler/main/TextBuffer.java | |
parent | 9f9da912f666dc2d25b7ba7e03283f13b4c5b4bf (diff) | |
download | fernflower-125441a88fc58f74ecfe2c1081a04b6c4d05ea61.tar fernflower-125441a88fc58f74ecfe2c1081a04b6c4d05ea61.tar.gz fernflower-125441a88fc58f74ecfe2c1081a04b6c4d05ea61.tar.lz fernflower-125441a88fc58f74ecfe2c1081a04b6c4d05ea61.tar.xz fernflower-125441a88fc58f74ecfe2c1081a04b6c4d05ea61.zip |
decompiler: move generated lines as it is stated in debug line table (disabled for now)
Diffstat (limited to 'src/org/jetbrains/java/decompiler/main/TextBuffer.java')
-rw-r--r-- | src/org/jetbrains/java/decompiler/main/TextBuffer.java | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/src/org/jetbrains/java/decompiler/main/TextBuffer.java b/src/org/jetbrains/java/decompiler/main/TextBuffer.java new file mode 100644 index 0000000..6d279bf --- /dev/null +++ b/src/org/jetbrains/java/decompiler/main/TextBuffer.java @@ -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); + } +} |