Eclipse JDT ASTParser - проблема с MethodVisitor
Я пишу код для разбора исходного кода Java. Я экспериментирую с Eclipse JDT AST Parser. Мой код приведен ниже. (Разбор кода). Я тестирую парсер для приложения Mailer, написанного на Java (второй фрагмент кода). Мой парсер посещает все методы, кроме метода generateEmail() и debug(). Я посмотрел повсюду, но я не могу понять всю жизнь, почему это происходит. Может кто-нибудь сказать мне, что я делаю не так? Это проблема с памятью? Я не получаю OutOfMemoryException
Я хочу посетить конкретные методы с методом MethodVisitor, чтобы получить доступ к операторам и переменным в конкретном методе.
Мой код разбора
public class RuleEngine {
public static void parse(String file) {
File java = new File(file);
ASTParser parser = ASTParser.newParser(AST.JLS3);
String code = readFile(java);
parser.setSource(code.toCharArray());
parser.setKind(ASTParser.K_COMPILATION_UNIT);
final CompilationUnit cu = (CompilationUnit) parser.createAST(null);
cu.accept(new ASTVisitor() {
public boolean visit(ImportDeclaration id) {
Name imp = id.getName();
debug("import", id.getName().getFullyQualifiedName());
return false;
}
public boolean visit(VariableDeclarationFragment node) {
SimpleName name = node.getName();
debug("var.declaration", (name.getFullyQualifiedName() + ":" + cu.getLineNumber(name.getStartPosition())));
return false; // do not continue
}
public boolean visit(MethodDeclaration method) {
debug("method", method.getName().getFullyQualifiedName());
debug("method.return", method.getReturnType2().toString());
List<SingleVariableDeclaration> params = method.parameters();
for(SingleVariableDeclaration param: params) {
debug("param", param.getName().getFullyQualifiedName());
}
Block methodBlock = method.getBody();
String myblock = methodBlock.toString();
methodVisitor(myblock);
return false;
}
});
}
public static void methodVisitor(String content) {
debug("entering met visitor", "1");
ASTParser metparse = ASTParser.newParser(AST.JLS3);
metparse.setSource(content.toCharArray());
metparse.setKind(ASTParser.K_STATEMENTS);
Block block = (Block) metparse.createAST(null);
block.accept(new ASTVisitor() {
public boolean visit(VariableDeclarationFragment var) {
debug("met.var", var.getName().getFullyQualifiedName());
return false;
}
public boolean visit(SimpleName node) {
debug("SimpleName node", node.getFullyQualifiedName());
return false;
}
public boolean visit(IfStatement myif) {
debug("if.statement", myif.toString());
return false;
}
});
}
public static void debug(String ref, String message) {
System.out.println(ref +": " + message);
}
public static void main(String[]args) {
parse("MailerDaemon.java");
}
Это мой код MailerDaemon
public boolean isBccMode() {
return bccMode;
}
public void setBccMode(boolean bccMode) {
this.bccMode = bccMode;
}
public void setServerPort(String serverPortAddr) {
String[] elems = serverPortAddr.split("\\:");
this.setServerAddr(elems[0]);
this.setSmtpPort(elems[1]);
}
public String getServerAddr() {
int i = 0;
return serverAddr;
}
public void setServerAddr(String serverAddr) {
this.serverAddr = serverAddr;
}
public boolean isSslOn() {
return isSslOn;
}
public void setSslOn(boolean isSslOn) {
this.isSslOn = isSslOn;
}
public String getSmtpPort() {
return smtpPort;
}
public void setSmtpPort(String smtpPort) {
this.smtpPort = smtpPort;
}
public String getFromEmail() {
return fromEmail;
}
public void setFromEmail(String fromEmail) {
this.fromEmail = fromEmail;
}
public String getToEmails() {
return toEmails;
}
public void setToEmails(String toEmails) {
this.toEmails = toEmails;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getCcList() {
return ccList;
}
public void setCcList(String ccList) {
this.ccList = ccList;
}
public String getBccList() {
return bccList;
}
public void setBccList(String bccList) {
this.bccList = bccList;
}
public String getFile() {
return file;
}
public void setFile(String file) {
debug("filename: " + file);
this.file = file;
}
public void generateEmail() {
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", this.getSmtpPort());
if(isSslOn()) {
props.put("mail.smtp.socketFactory.port", this.getSmtpPort());
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
}
props.put("mail.smtp.host", getServerAddr());
Session session = Session.getDefaultInstance(props, new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(getUsername(), getPassword());
}
});
Message msg = new MimeMessage(session);
try {
msg.setFrom(new InternetAddress(this.getFromEmail()));
if (getToEmails() != null) {
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(getToEmails()));
} else if (isBccMode()) {
msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(getFromEmail()));
}
//msg.setRecipients(Message.RecipientType.CC, InternetAddress.parse(getCcList()));
msg.setSubject(getSubject());
//msg.setText(getMessage());
MimeBodyPart messagePart = new MimeBodyPart();
messagePart.setText(getMessage());
/*
MimeBodyPart attachments = new MimeBodyPart();
FileDataSource fd = new FileDataSource(getFile());
attachments.setDataHandler(new DataHandler(fd));
attachments.setFileName(fd.getName());
*/
Multipart mp = new MimeMultipart();
mp.addBodyPart(messagePart);
//mp.addBodyPart(attachments);
msg.setContent(mp);
Transport.send(msg);
debug("Done. Closing Session...");
} catch (AddressException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void debug(String message) {
System.out.println("[DEBUG]: " + message);
}
2 ответа
Я не вижу явных проблем с вашим кодом для разбора. Я надеюсь, что его где-то не получится, когда он пытается разобрать generateEmail()
метод. Поскольку синтаксический анализатор следует последовательному подходу, debug()
метод тоже не разбирается. Попробуйте приложить заявления в public boolean visit(MethodDeclaration method)
в блоке try-catch с условием Throwable.
Также проверьте ваш readFile()
метод. Одна проблема, которая чаще всего наблюдается при чтении файла, отсутствует для добавления символа новой строки в каждую строку. Не добавление новой строки приводит к ошибочному построению кода, особенно когда в коде есть комментарии. Вы можете проверить compilationUnit.getProblems()
способ проверить любые такие проблемы.
@UnniKris - Спасибо за ваш ответ. Я изменил readFile()
метод и включены \n
после того, как символ новой строки был записан в StringBuilder. Это сработало. Все мои методы были успешно проанализированы.
Мой фрагмент кода для метода readFile() размещен здесь:
public static String readFile(File file) {
StringBuilder sb = new StringBuilder();
try {
Scanner scan = new Scanner(file);
while(scan.hasNext()) {
sb.append(scan.nextLine()+"\n"); //added the new line feed here
}
scan.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String fullcode = sb.toString();
//debug("full.code", fullcode);
return fullcode;
}