Eclipse JDT ASTParser - MethodVisitor问题

时间:2013-01-12 12:45:34

标签: java parsing abstract-syntax-tree eclipse-jdt

我正在编写一些代码来解析java源代码。我正在尝试使用Eclipse JDT AST Parser。我的代码如下。 (解析代码)。我正在针对我用Java编写的Mailer应用程序(第二个代码片段)测试解析器。我的解析器正在访问除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 个答案:

答案 0 :(得分:1)

我发现你的解析代码没有明显的问题。我希望它在试图解析generateEmail()方法时失败了。由于解析器遵循顺序方法,因此debug()方法也不会被解析。尝试将public boolean visit(MethodDeclaration method)中的语句包含在try-catch块中,可能包含Throwable子句。

还要检查readFile()方法。在读取文件时大多数情况下看到的一个问题是缺少向每行添加换行符。不附加新行会导致代码的错误构造,尤其是在代码中存在注释时。您可以检查compilationUnit.getProblems()方法以检查任何此类问题。

答案 1 :(得分:0)

@UnniKris - 感谢您的回复。在将换行符写入StringBuilder之后,我更改了readFile()方法并包含了\n。这很有效。我的所有方法都被成功解析了。

我在这里发布了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;

}