All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javacutil.src.org.checkerframework.javacutil.trees.TreeParser Maven / Gradle / Ivy

Go to download

The Checker Framework enhances Java’s type system to make it more powerful and useful. This lets software developers detect and prevent errors in their Java programs. The Checker Framework includes compiler plug-ins ("checkers") that find bugs or verify their absence. It also permits you to write your own compiler plug-ins.

There is a newer version: 3.42.0
Show newest version
package org.checkerframework.javacutil.trees;

import java.util.StringTokenizer;

import javax.annotation.processing.ProcessingEnvironment;

import com.sun.source.tree.ExpressionTree;
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Names;

/**
 * A Utility class for parsing Java expression snippets, and converting them
 * to proper Javac AST nodes.
 *
 * This is useful for parsing {@code EnsuresNonNull*},
 * and {@code KeyFor} values.
 *
 * Currently, it handles four tree types only:
 * 
    *
  • Identifier tree (e.g. {@code id})
  • *
  • Literal tree (e.g. 2, 3)
  • *
  • Method invocation tree (e.g. {@code method(2, 3)})
  • *
  • Member select tree (e.g. {@code Class.field}, {@code instance.method()}) *
  • Array access tree (e.g. {@code array[id]})
  • *
* * Notable limitation: Doesn't handle spaces, or non-method-argument * parenthesis. * * It's implemented via a Recursive-Descend parser. */ public class TreeParser { private static final String DELIMS = ".[](),"; private static final String SENTINAL = ""; private final TreeMaker maker; private final Names names; public TreeParser(ProcessingEnvironment env) { Context context = ((JavacProcessingEnvironment)env).getContext(); maker = TreeMaker.instance(context); names = Names.instance(context); } /** * Parses the snippet in the string as an internal Javac AST expression * node * * @param s the java snippet * @return the AST corresponding to the snippet */ public ExpressionTree parseTree(String s) { tokenizer = new StringTokenizer(s, DELIMS, true); token = tokenizer.nextToken(); try { return parseExpression(); } catch (Exception e) { throw new ParseError(e); } finally { tokenizer = null; token = null; } } StringTokenizer tokenizer = null; String token = null; private String nextToken() { token = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : SENTINAL; return token; } JCExpression fromToken(String token) { // Optimization if ("true".equals(token)) { return maker.Literal(true); } else if ("false".equals(token)) { return maker.Literal(false); } if (Character.isLetter(token.charAt(0))) { return maker.Ident(names.fromString(token)); } Object value = null; try { value = Integer.valueOf(token); } catch (Exception e2) { try { value = Double.valueOf(token); } catch (Exception ef) {}} assert value != null; return maker.Literal(value); } JCExpression parseExpression() { JCExpression tree = fromToken(token); while (tokenizer.hasMoreTokens()) { String delim = nextToken(); if (".".equals(delim)) { nextToken(); tree = maker.Select(tree, names.fromString(token)); } else if ("(".equals(delim)) { nextToken(); ListBuffer args = new ListBuffer<>(); while (!")".equals(token)) { JCExpression arg = parseExpression(); args.append(arg); if (",".equals(token)) { nextToken(); } } // For now, handle empty args only assert ")".equals(token); tree = maker.Apply(List.nil(), tree, args.toList()); } else if ("[".equals(token)) { nextToken(); JCExpression index = parseExpression(); assert "]".equals(token); tree = maker.Indexed(tree, index); } else { return tree; } } return tree; } class ParseError extends RuntimeException { private static final long serialVersionUID = 1887754619522101929L; ParseError(Throwable cause) { super(cause); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy