2023-08-18 15:55:31 +08:00
|
|
|
import java.io.FileInputStream;
|
|
|
|
|
import java.io.FileOutputStream;
|
|
|
|
|
import java.io.OutputStreamWriter;
|
|
|
|
|
import java.nio.charset.StandardCharsets;
|
2026-01-26 11:11:58 +08:00
|
|
|
import java.nio.file.Path;
|
|
|
|
|
import java.nio.file.Paths;
|
2023-08-18 15:55:31 +08:00
|
|
|
import java.util.List;
|
2023-08-20 12:13:40 +08:00
|
|
|
import java.util.stream.Collectors;
|
2023-08-18 15:55:31 +08:00
|
|
|
|
|
|
|
|
import org.antlr.v4.runtime.*;
|
|
|
|
|
|
2023-08-20 12:13:40 +08:00
|
|
|
public class CommonHelper {
|
|
|
|
|
|
|
|
|
|
// =========== Token Finder & Comments Processing ===========
|
2023-08-18 15:55:31 +08:00
|
|
|
|
|
|
|
|
public static Token getPreChannelToken(BufferedTokenStream stream, Token token, int channel) {
|
|
|
|
|
List<Token> tokens = stream.getHiddenTokensToLeft(token.getTokenIndex(), channel);
|
|
|
|
|
if (tokens == null)
|
|
|
|
|
return null;
|
|
|
|
|
return tokens.get(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Token getPostChannelToken(BufferedTokenStream stream, Token token, int channel) {
|
|
|
|
|
List<Token> tokens = stream.getHiddenTokensToRight(token.getTokenIndex(), channel);
|
|
|
|
|
if (tokens == null)
|
|
|
|
|
return null;
|
|
|
|
|
return tokens.get(0);
|
|
|
|
|
}
|
2023-10-12 10:42:06 +08:00
|
|
|
|
2023-08-20 12:13:40 +08:00
|
|
|
public static List<Token> getPreChannelTokens(BufferedTokenStream stream, Token token, int channel) {
|
|
|
|
|
return stream.getHiddenTokensToLeft(token.getTokenIndex(), channel);
|
|
|
|
|
}
|
2023-08-18 15:55:31 +08:00
|
|
|
|
2023-08-20 12:13:40 +08:00
|
|
|
public static List<Token> getPostChannelTokens(BufferedTokenStream stream, Token token, int channel) {
|
|
|
|
|
return stream.getHiddenTokensToRight(token.getTokenIndex(), channel);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Cut the head and tail of comment
|
2026-01-26 11:11:58 +08:00
|
|
|
*
|
2023-08-20 12:13:40 +08:00
|
|
|
* @param comment The comment need to be cut.
|
|
|
|
|
* @return The cut comment.
|
|
|
|
|
*/
|
2023-08-18 15:55:31 +08:00
|
|
|
public static String cutComment(Token comment) {
|
|
|
|
|
if (comment == null)
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
switch (comment.getType()) {
|
|
|
|
|
case CKGeneralLexer.CKGENERAL_LINE_COMMENT: {
|
2026-01-27 16:38:29 +08:00
|
|
|
// For line comment, we start to remove "//" prefix first
|
|
|
|
|
String slashRemoved = comment.getText().substring(2);
|
|
|
|
|
// Then remove successive starts
|
|
|
|
|
String starsRemoved = removeSeperator(slashRemoved);
|
|
|
|
|
// Do a strip for it.
|
|
|
|
|
String stripped = starsRemoved.strip();
|
|
|
|
|
// Then remove EOL to avoid unexpected line break.
|
|
|
|
|
String eolRemoved = removeEol(stripped);
|
|
|
|
|
// Okey
|
|
|
|
|
return eolRemoved;
|
2023-08-18 15:55:31 +08:00
|
|
|
}
|
|
|
|
|
case CKGeneralLexer.CKGENERAL_BLOCK_COMMENT: {
|
2026-01-27 16:38:29 +08:00
|
|
|
// For block comment, we first cut "/*" head and "*/" tail.
|
|
|
|
|
String blockComment = comment.getText();
|
|
|
|
|
String slashRemoved = blockComment.substring(2, blockComment.length() - 4);
|
|
|
|
|
|
|
|
|
|
// Then we break it at line breaker and process each line one by one.
|
|
|
|
|
String beautyComment = slashRemoved.lines().map((String line) -> {
|
|
|
|
|
// Remove successive starts
|
|
|
|
|
String starsRemoved = removeSeperator(line);
|
|
|
|
|
// Do a strip for it.
|
|
|
|
|
String stripped = starsRemoved.strip();
|
|
|
|
|
// Then remove EOL to avoid unexpected line break.
|
|
|
|
|
String eolRemoved = removeEol(stripped);
|
|
|
|
|
// Line process is okey now
|
|
|
|
|
return eolRemoved;
|
|
|
|
|
}).collect(Collectors.joining("\n")); // Then re-join with fresh line breaker
|
|
|
|
|
// Then return
|
|
|
|
|
return beautyComment;
|
2023-08-18 15:55:31 +08:00
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
return comment.getText();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-20 12:13:40 +08:00
|
|
|
/**
|
|
|
|
|
* Cut multiple comments.
|
|
|
|
|
* <p>
|
2023-10-12 10:42:06 +08:00
|
|
|
* Each comment will be cut the head and tail first. And strip all whitespace.
|
2023-08-20 12:13:40 +08:00
|
|
|
* Then join together.
|
|
|
|
|
*
|
|
|
|
|
* @param tokens Multiple comments.
|
|
|
|
|
* @return The joined comment.
|
|
|
|
|
*/
|
|
|
|
|
public static String cutComments(List<Token> tokens) {
|
|
|
|
|
if (tokens == null)
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
return tokens.stream().map(value -> {
|
2026-01-27 16:38:29 +08:00
|
|
|
return cutComment(value);
|
|
|
|
|
}).collect(Collectors.joining("\n"));
|
2023-08-20 12:13:40 +08:00
|
|
|
}
|
2023-10-12 10:42:06 +08:00
|
|
|
|
2023-08-20 12:13:40 +08:00
|
|
|
// =========== Number Operations ===========
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Check whether Antlr captured CKGENERAL_NUM is a negative number.
|
|
|
|
|
*
|
|
|
|
|
* @param numstr The captured number.
|
|
|
|
|
* @return true if it is negative number.
|
|
|
|
|
*/
|
|
|
|
|
public static boolean isNegativeNumber(String numstr) {
|
2023-08-18 15:55:31 +08:00
|
|
|
return numstr.startsWith("-");
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-20 12:13:40 +08:00
|
|
|
/**
|
|
|
|
|
* Check whether Altlr captured CKGENERAL_NUM is a hex number.
|
2026-01-27 16:38:29 +08:00
|
|
|
*
|
2023-08-20 12:13:40 +08:00
|
|
|
* @param numstr The captured number.
|
|
|
|
|
* @return true if it is hex number.
|
|
|
|
|
*/
|
|
|
|
|
public static boolean isHexNumber(String numstr) {
|
|
|
|
|
return numstr.startsWith("0x") || numstr.startsWith("0X");
|
|
|
|
|
}
|
2023-08-18 15:55:31 +08:00
|
|
|
|
2023-08-19 00:03:00 +08:00
|
|
|
// =========== File Operations ===========
|
2023-08-20 12:13:40 +08:00
|
|
|
|
2026-01-26 11:11:58 +08:00
|
|
|
private static Path getRootDirectoryPath() throws Exception {
|
|
|
|
|
String rootDir = System.getenv("ENUMS_MIGRATION_ROOT");
|
2026-01-26 22:52:56 +08:00
|
|
|
if (rootDir == null) {
|
|
|
|
|
throw new RuntimeException("Can not find essential environment variable ENUMS_MIGRATION_ROOT");
|
|
|
|
|
} else {
|
|
|
|
|
return Paths.get(rootDir);
|
|
|
|
|
}
|
2026-01-26 11:11:58 +08:00
|
|
|
}
|
|
|
|
|
|
2023-08-19 00:03:00 +08:00
|
|
|
public static class InputFilePair {
|
|
|
|
|
public CharStream mAntlrStream;
|
|
|
|
|
public FileInputStream mUnderlyingStream;
|
|
|
|
|
}
|
2023-08-20 12:13:40 +08:00
|
|
|
|
2023-08-19 00:03:00 +08:00
|
|
|
public static InputFilePair openInputFile(String filename) throws Exception {
|
|
|
|
|
InputFilePair pair = new InputFilePair();
|
|
|
|
|
pair.mUnderlyingStream = new FileInputStream(filename);
|
|
|
|
|
pair.mAntlrStream = CharStreams.fromStream(pair.mUnderlyingStream, StandardCharsets.UTF_8);
|
|
|
|
|
return pair;
|
|
|
|
|
}
|
2023-08-20 12:13:40 +08:00
|
|
|
|
2026-01-26 11:11:58 +08:00
|
|
|
public static String getInputFilePath(String filename) throws Exception {
|
|
|
|
|
Path rootDir = getRootDirectoryPath();
|
|
|
|
|
Path filePath = rootDir.resolve("Input").resolve(filename);
|
|
|
|
|
return filePath.toString();
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-19 00:03:00 +08:00
|
|
|
/**
|
|
|
|
|
* Get output file for writing.
|
2023-08-20 12:13:40 +08:00
|
|
|
*
|
2023-08-19 00:03:00 +08:00
|
|
|
* @param filename The name of file opening.
|
|
|
|
|
* @return An OutputStreamWriter.
|
|
|
|
|
* @throws Exception
|
|
|
|
|
*/
|
2023-08-18 15:55:31 +08:00
|
|
|
public static OutputStreamWriter openOutputFile(String filename) throws Exception {
|
|
|
|
|
FileOutputStream fs = new FileOutputStream(filename);
|
|
|
|
|
return new OutputStreamWriter(fs, StandardCharsets.UTF_8);
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-26 11:11:58 +08:00
|
|
|
public static String getOutputFilePath(String filename) throws Exception {
|
|
|
|
|
Path rootDir = getRootDirectoryPath();
|
|
|
|
|
Path filePath = rootDir.resolve("Intermediate").resolve(filename);
|
|
|
|
|
return filePath.toString();
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-19 00:03:00 +08:00
|
|
|
// =========== String Process ===========
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Remove all EOL (End of Line) characters.
|
|
|
|
|
*
|
|
|
|
|
* @param strl The string need to be processed.
|
|
|
|
|
* @return The string eliminated all EOL.
|
|
|
|
|
*/
|
|
|
|
|
public static String removeEol(String strl) {
|
|
|
|
|
return strl.replace("\n", "").replace("\r", "");
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-15 13:21:49 +08:00
|
|
|
/**
|
2026-01-27 16:38:29 +08:00
|
|
|
* Remove seperator bar consisted by '*' or '-' (at least 5 successive chars)
|
2023-10-12 10:42:06 +08:00
|
|
|
*
|
2023-09-15 13:21:49 +08:00
|
|
|
* @param cmt The string provided.
|
|
|
|
|
* @return The string processed.
|
|
|
|
|
*/
|
2026-01-27 16:38:29 +08:00
|
|
|
public static String removeSeperator(String cmt) {
|
2023-09-15 13:21:49 +08:00
|
|
|
// only remove at least 5 continuous star chars.
|
2026-01-27 16:38:29 +08:00
|
|
|
return cmt.replaceAll("[\\*\\-]{5,}", "");
|
2023-10-12 10:42:06 +08:00
|
|
|
}
|
|
|
|
|
|
2023-08-18 15:55:31 +08:00
|
|
|
}
|