帆软使用的第三方框架。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
4.3 KiB

package com.fr.third.antlr;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
// assumes one source file for now -- may need to change if ANTLR allows
// file inclusion in the future
// TODO optimize the output using line ranges for input/output files
// currently this writes one mapping per line
public class PrintWriterWithSMAP extends PrintWriter {
private int currentOutputLine = 1;
private int currentSourceLine = 0;
private Map sourceMap = new HashMap();
private boolean lastPrintCharacterWasCR = false;
private boolean mapLines = false;
private boolean mapSingleSourceLine = false;
private boolean anythingWrittenSinceMapping = false;
public PrintWriterWithSMAP(OutputStream out) {
super(out);
}
public PrintWriterWithSMAP(OutputStream out, boolean autoFlush) {
super(out, autoFlush);
}
public PrintWriterWithSMAP(Writer out) {
super(out);
}
public PrintWriterWithSMAP(Writer out, boolean autoFlush) {
super(out, autoFlush);
}
public void startMapping(int sourceLine) {
mapLines = true;
if (sourceLine != JavaCodeGenerator.CONTINUE_LAST_MAPPING)
currentSourceLine = sourceLine;
}
public void startSingleSourceLineMapping(int sourceLine) {
mapSingleSourceLine = true;
mapLines = true;
if (sourceLine != JavaCodeGenerator.CONTINUE_LAST_MAPPING)
currentSourceLine = sourceLine;
}
public void endMapping() {
mapLine(false);
mapLines = false;
mapSingleSourceLine = false;
}
protected void mapLine(boolean incrementOutputLineCount) {
if (mapLines && anythingWrittenSinceMapping) {
Integer sourceLine = new Integer(currentSourceLine);
Integer outputLine = new Integer(currentOutputLine);
List outputLines = (List)sourceMap.get(sourceLine);
if (outputLines == null) {
outputLines = new ArrayList();
sourceMap.put(sourceLine,outputLines);
}
if (!outputLines.contains(outputLine))
outputLines.add(outputLine);
}
if (incrementOutputLineCount)
currentOutputLine++;
if (!mapSingleSourceLine)
currentSourceLine++;
anythingWrittenSinceMapping = false;
}
public void dump(PrintWriter smapWriter, String targetClassName, String grammarFile) {
smapWriter.println("SMAP");
smapWriter.println(targetClassName + ".java");
smapWriter.println('G');
smapWriter.println("*S G");
smapWriter.println("*F");
smapWriter.println("+ 0 " + grammarFile);
smapWriter.println(grammarFile);
smapWriter.println("*L");
List sortedSourceLines = new ArrayList(sourceMap.keySet());
Collections.sort(sortedSourceLines);
for (Iterator i = sortedSourceLines.iterator(); i.hasNext();) {
Integer sourceLine = (Integer)i.next();
List outputLines = (List)sourceMap.get(sourceLine);
for (Iterator j = outputLines.iterator(); j.hasNext();) {
Integer outputLine = (Integer)j.next();
smapWriter.println(sourceLine + ":" + outputLine);
}
}
smapWriter.println("*E");
smapWriter.close();
}
public void write(char[] buf, int off, int len) {
int stop = off+len;
for(int i = off; i < stop; i++) {
checkChar(buf[i]);
}
super.write(buf,off,len);
}
// after testing, may want to inline this
public void checkChar(int c) {
if (lastPrintCharacterWasCR && c != '\n')
mapLine(true);
else if (c == '\n')
mapLine(true);
else if (!Character.isWhitespace((char)c))
anythingWrittenSinceMapping = true;
lastPrintCharacterWasCR = (c == '\r');
}
public void write(int c) {
checkChar(c);
super.write(c);
}
public void write(String s, int off, int len) {
int stop = off+len;
for(int i = off; i < stop; i++) {
checkChar(s.charAt(i));
}
super.write(s,off,len);
}
// PrintWriter delegates write(char[]) to write(char[], int, int)
// PrintWriter delegates write(String) to write(String, int, int)
// dependent on current impl of PrintWriter, which directly
// dumps a newline sequence to the target file w/o going through
// the other write methods.
public void println() {
mapLine(true);
super.println();
lastPrintCharacterWasCR = false;
}
public Map getSourceMap() {
return sourceMap;
}
public int getCurrentOutputLine() {
return currentOutputLine;
}
}