问题
I am writing some code to parse java source code. I am experimenting with Eclipse JDT AST Parser. My code is given below. (Parsing code). I am testing the parser against a Mailer application that I wrote in Java (second code snippet). My parser is visiting all methods except the generateEmail() and the debug() methods. I have looked all over the place but I am not able to understand for the life of me why its happening. Can anyone tell me what I am doing wrong? Is it a memory issue? I am not getting any OutOfMemoryException
I want to visit the specific methods with the MethodVisitor method to get access to statements and variables in a particular method.
My Parsing code
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");
}
This is my MailerDaemon Code
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);
}
回答1:
I see no evident problem with your parsing code. I hope its failing somewhere when its trying to parse the generateEmail()
method. Since the parser follows a sequential approach, the debug()
method is also not getting parsed. Try to enclose the statements within the public boolean visit(MethodDeclaration method)
in a try-catch block with probably a Throwable clause.
Also have a check for your readFile()
method. One issue that is mostly seen while reading a file is missing to append new line character to each line. Not appending a new line results in erroneous construction of the code, especially when there are comments in the code. You may inspect compilationUnit.getProblems()
method to check any such problems.
回答2:
@UnniKris - Thank you for your response. I changed the readFile()
method and included a \n
after the newline was written to the StringBuilder. This worked. All my methods were successfully parsed.
My code snippet for the readFile() method is posted here:
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;
}
来源:https://stackoverflow.com/questions/14293450/eclipse-jdt-astparser-issue-with-methodvisitor