# HG changeset patch # User jlahoda # Date 1554122777 -7200 # Node ID 72d5f7163f126cc6af40fe5311199e8fcbfcda86 # Parent ad0be596956b8e8c7330d2475fbc50c54e53b284 Adding ability to supply code as text instead of Trees on some places. diff -r ad0be596956b -r 72d5f7163f12 src/jdk.compiler/share/classes/com/sun/source/util/TreeBuilder.java --- a/src/jdk.compiler/share/classes/com/sun/source/util/TreeBuilder.java Mon Apr 01 11:44:31 2019 +0200 +++ b/src/jdk.compiler/share/classes/com/sun/source/util/TreeBuilder.java Mon Apr 01 14:46:17 2019 +0200 @@ -58,7 +58,13 @@ interface Class extends WithModifiers, WithJavadoc { //setters: Class superclass(Consumer sup); + default Class superclass(String sup) { + return superclass(t -> t.type(sup)); + } Class superinterface(Consumer sup); + default Class superinterface(String sup) { + return superinterface(t -> t.type(sup)); + } //type parameters? //adders: @@ -77,6 +83,9 @@ interface Variable extends WithModifiers, WithJavadoc { //setters: Variable init(Consumer init); + default Variable init(String init) { + return init(E -> E.expression(init)); + } } interface Parameter extends WithModifiers { @@ -93,7 +102,14 @@ //TODO: parameter overload type+name? Method parameter(Consumer type, Consumer parameter); - Method body(Consumer statements); + Method body(Consumer body); + + /** + * Must include the '{' '}'. + * @param body + * @return + */ + Method body(String body); //throws, default value } @@ -119,6 +135,7 @@ void _int(); void _float(); void _void(); + void type(String type); } interface TypeArguments { //??? @@ -149,6 +166,7 @@ void select(Consumer selected, String name); void ident(String qnames); void literal(Object value); + void expression(String expression); } interface StatementBase { @@ -158,6 +176,7 @@ S _return(Consumer expr); S expr(Consumer expr); S skip(); + S statement(String statement); } interface Statement extends StatementBase { diff -r ad0be596956b -r 72d5f7163f12 src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java Mon Apr 01 11:44:31 2019 +0200 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java Mon Apr 01 14:46:17 2019 +0200 @@ -182,6 +182,7 @@ private JavaFileManager fileManager; private ParserFactory parser; private Symtab syms; + private com.sun.tools.javac.main.JavaCompiler compiler; private final Map extraType2OriginalMap = new WeakHashMap<>(); @@ -230,6 +231,7 @@ docTreeMaker = DocTreeMaker.instance(context); parser = ParserFactory.instance(context); syms = Symtab.instance(context); + compiler = com.sun.tools.javac.main.JavaCompiler.instance(context); fileManager = context.get(JavaFileManager.class); JavacTask t = context.get(JavacTask.class); if (t instanceof JavacTaskImpl) @@ -1245,6 +1247,6 @@ } public TreeBuilder getTreeBuilder() { - return new TreeBuilderImpl(treeMaker, names); + return new TreeBuilderImpl(compiler, parser, treeMaker, names); } } diff -r ad0be596956b -r 72d5f7163f12 src/jdk.compiler/share/classes/com/sun/tools/javac/api/TreeBuilderImpl.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/TreeBuilderImpl.java Mon Apr 01 11:44:31 2019 +0200 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/TreeBuilderImpl.java Mon Apr 01 14:46:17 2019 +0200 @@ -23,7 +23,11 @@ * questions. */package com.sun.tools.javac.api; +import java.nio.CharBuffer; import java.util.function.Consumer; +import java.util.function.Function; + +import javax.tools.JavaFileObject; import com.sun.source.doctree.DocTree; import com.sun.source.tree.CompilationUnitTree; @@ -34,13 +38,18 @@ import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; -import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.tree.JCTree.Tag; import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.util.List; -import com.sun.tools.javac.util.Name; +import com.sun.tools.javac.main.JavaCompiler; +import com.sun.tools.javac.parser.Parser; +import com.sun.tools.javac.parser.ParserFactory; +import com.sun.tools.javac.tree.JCTree.JCBlock; +import com.sun.tools.javac.tree.JCTree.JCStatement; +import com.sun.tools.javac.util.JCDiagnostic; +import com.sun.tools.javac.util.Log.DiagnosticHandler; import com.sun.tools.javac.util.Names; /** @@ -49,10 +58,14 @@ */ public class TreeBuilderImpl implements TreeBuilder { + private final JavaCompiler compiler; + private final ParserFactory parserFactory; private final TreeMaker make; private final Names names; - public TreeBuilderImpl(TreeMaker make, Names names) { + public TreeBuilderImpl(JavaCompiler compiler, ParserFactory parserFactory, TreeMaker make, Names names) { + this.compiler = compiler; + this.parserFactory = parserFactory; this.make = make; this.names = names; } @@ -193,6 +206,11 @@ throw new UnsupportedOperationException("Not supported yet."); } + @Override + public void type(String typeSpec) { + type = parse(typeSpec, Parser::parseType); + } + } private final class TypeArgumentsImpl implements TypeArguments { @@ -262,6 +280,16 @@ } @Override + public Method body(String body) { + JCStatement parsedBody = parse(body, Parser::parseStatement); + if (!parsedBody.hasTag(Tag.BLOCK)) { + throw new IllegalArgumentException("Block not provided!"); + } + result.body = (JCBlock) parsedBody; + return this; + } + + @Override public Method modifiers(Consumer modifiers) { throw new UnsupportedOperationException("Not supported yet."); } @@ -371,6 +399,11 @@ throw new UnsupportedOperationException("Not supported yet."); } + @Override + public S statement(String statement) { + return addStatement(parse(statement, Parser::parseStatement)); + } + protected abstract S addStatement(JCStatement stat); } @@ -416,6 +449,12 @@ public void literal(Object value) { expr = make.Literal(value); } + + @Override + public void expression(String expression) { + expr = parse(expression, Parser::parseExpression); + } + } private final class QualifiedNameImpl implements QualifiedName { @@ -477,4 +516,31 @@ return type.type; } + + private T parse(String toParse, Function runParse) { + if (toParse == null || toParse.equals("")) + throw new IllegalArgumentException(); + JavaFileObject prev = compiler.log.useSource(null); + DiagnosticHandler h = null; + try { + h = new DiagnosticHandler() { + { + install(compiler.log); + } + @Override + public void report(JCDiagnostic err) { + if (err.getKind() == JCDiagnostic.Kind.ERROR) { + throw new IllegalArgumentException("Cannot parse input: " + err.getMessage(null)); + } + } + }; + CharBuffer buf = CharBuffer.wrap((toParse+"\u0000").toCharArray(), 0, toParse.length()); + Parser parser = parserFactory.newParser(buf, false, false, false); + return runParse.apply(parser); + } finally { + compiler.log.popDiagnosticHandler(h); + compiler.log.useSource(prev); + } + } + } diff -r ad0be596956b -r 72d5f7163f12 test/langtools/tools/javac/api/ast/ASTBuilder.java --- a/test/langtools/tools/javac/api/ast/ASTBuilder.java Mon Apr 01 11:44:31 2019 +0200 +++ b/test/langtools/tools/javac/api/ast/ASTBuilder.java Mon Apr 01 14:46:17 2019 +0200 @@ -79,6 +79,30 @@ " return 1;" + " }" + "}"); + runTest("class Test extends java.util.Map, Numer> {" + + "}", + U -> U._class("Test", C -> C.superclass("java.util.Map, Numer>"))); + runTest("class Test {" + + " int i = true ? 0 : 1;" + + "}", + U -> U._class("Test", C -> C.field("i", Type::_int, F -> F.init("true ? 0 : 1")))); + runTest("class Test {" + + " int test(int param) {" + + " if (param == 0) return 0;" + + " else return 1;" + + " }" + + "}", + U -> U._class("Test", C -> C.method("test", Type::_int, M -> M.parameter(Type::_int, P -> P.name("param")).body("{\n" + + " if (param == 0) return 0;\n" + + " else return 1;\n" + + " }")))); + try { + runTest("broken", + U -> U._class("Test", C -> C.superclass("java.util.Map<"))); + throw new AssertionError("The exceptec exception was not thrown."); + } catch (IllegalArgumentException ex) { + //OK + } } private static void runTest(String expectedCode, Consumer actualBuilder) throws Exception {