| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent e794c75 commit 044a5a5
3 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -251,6 +251,9 @@ | |||
| 251 | 251 | --add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED | |
| 252 | 252 | --add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED | |
| 253 | 253 | --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED | |
| 254 | + --add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED | ||
| 255 | + --add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED | ||
| 256 | + --add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED | ||
| 254 | 257 | </test.jvm.flags> | |
| 255 | 258 | </properties> | |
| 256 | 259 | </profile> | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -15,37 +15,33 @@ | |||
| 15 | 15 | */ | |
| 16 | 16 | package com.google.testing.compile; | |
| 17 | 17 | ||
| 18 | - import static com.google.common.base.MoreObjects.firstNonNull; | ||
| 19 | - import static java.lang.Boolean.TRUE; | ||
| 20 | 18 | import static java.nio.charset.StandardCharsets.UTF_8; | |
| 21 | - import static java.util.function.Predicate.isEqual; | ||
| 22 | 19 | import static javax.tools.Diagnostic.Kind.ERROR; | |
| 23 | 20 | ||
| 24 | 21 | import com.google.common.base.Joiner; | |
| 25 | 22 | import com.google.common.collect.ImmutableList; | |
| 26 | 23 | import com.google.common.collect.ImmutableListMultimap; | |
| 27 | - import com.google.common.collect.ImmutableSet; | ||
| 28 | - import com.google.common.collect.Iterables; | ||
| 29 | 24 | import com.google.common.collect.Multimaps; | |
| 30 | 25 | import com.sun.source.tree.CompilationUnitTree; | |
| 31 | - import com.sun.source.tree.ErroneousTree; | ||
| 32 | - import com.sun.source.tree.Tree; | ||
| 33 | 26 | import com.sun.source.util.JavacTask; | |
| 34 | - import com.sun.source.util.TreeScanner; | ||
| 35 | 27 | import com.sun.source.util.Trees; | |
| 36 | - import com.sun.tools.javac.api.JavacTool; | ||
| 28 | + import com.sun.tools.javac.api.JavacTrees; | ||
| 29 | + import com.sun.tools.javac.file.JavacFileManager; | ||
| 30 | + import com.sun.tools.javac.parser.JavacParser; | ||
| 31 | + import com.sun.tools.javac.parser.ParserFactory; | ||
| 32 | + import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; | ||
| 37 | 33 | import com.sun.tools.javac.util.Context; | |
| 34 | + import com.sun.tools.javac.util.Log; | ||
| 38 | 35 | import java.io.IOException; | |
| 36 | + import java.util.ArrayList; | ||
| 39 | 37 | import java.util.List; | |
| 40 | - import java.util.Locale; | ||
| 41 | 38 | import javax.tools.Diagnostic; | |
| 42 | 39 | import javax.tools.DiagnosticCollector; | |
| 43 | - import javax.tools.JavaCompiler; | ||
| 40 | + import javax.tools.DiagnosticListener; | ||
| 44 | 41 | import javax.tools.JavaFileObject; | |
| 45 | - import javax.tools.ToolProvider; | ||
| 46 | 42 | ||
| 47 | 43 | /** Methods to parse Java source files. */ | |
| 48 | - public final class Parser { | ||
| 44 | + final class Parser { | ||
| 49 | 45 | ||
| 50 | 46 | /** | |
| 51 | 47 | * Parses {@code sources} into {@linkplain CompilationUnitTree compilation units}. This method | |
@@ -55,89 +51,42 @@ public final class Parser { | |||
| 55 | 51 | * @throws IllegalStateException if any parsing errors occur. | |
| 56 | 52 | */ | |
| 57 | 53 | static ParseResult parse(Iterable<? extends JavaFileObject> sources, String sourcesDescription) { | |
| 58 | - JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); | ||
| 59 | 54 | DiagnosticCollector<JavaFileObject> diagnosticCollector = new DiagnosticCollector<>(); | |
| 60 | - InMemoryJavaFileManager fileManager = | ||
| 61 | - new InMemoryJavaFileManager( | ||
| 62 | - compiler.getStandardFileManager(diagnosticCollector, Locale.getDefault(), UTF_8)); | ||
| 63 | 55 | Context context = new Context(); | |
| 64 | - JavacTask task = | ||
| 65 | - ((JavacTool) compiler) | ||
| 66 | - .getTask( | ||
| 67 | - null, // explicitly use the default because old javac logs some output on stderr | ||
| 68 | - fileManager, | ||
| 69 | - diagnosticCollector, | ||
| 70 | - ImmutableSet.<String>of(), | ||
| 71 | - ImmutableSet.<String>of(), | ||
| 72 | - sources, | ||
| 73 | - context); | ||
| 56 | + context.put(DiagnosticListener.class, diagnosticCollector); | ||
| 57 | + Log log = Log.instance(context); | ||
| 58 | + // The constructor registers the instance in the Context | ||
| 59 | + JavacFileManager unused = new JavacFileManager(context, true, UTF_8); | ||
| 60 | + ParserFactory parserFactory = ParserFactory.instance(context); | ||
| 74 | 61 | try { | |
| 75 | - Iterable<? extends CompilationUnitTree> parsedCompilationUnits = task.parse(); | ||
| 62 | + List<CompilationUnitTree> parsedCompilationUnits = new ArrayList<>(); | ||
| 63 | + for (JavaFileObject source : sources) { | ||
| 64 | + log.useSource(source); | ||
| 65 | + JavacParser parser = | ||
| 66 | + parserFactory.newParser( | ||
| 67 | + source.getCharContent(false), | ||
| 68 | + /* keepDocComments= */ true, | ||
| 69 | + /* keepEndPos= */ true, | ||
| 70 | + /* keepLineMap= */ true); | ||
| 71 | + JCCompilationUnit unit = parser.parseCompilationUnit(); | ||
| 72 | + unit.sourcefile = source; | ||
| 73 | + parsedCompilationUnits.add(unit); | ||
| 74 | + } | ||
| 76 | 75 | List<Diagnostic<? extends JavaFileObject>> diagnostics = diagnosticCollector.getDiagnostics(); | |
| 77 | - if (foundParseErrors(parsedCompilationUnits, diagnostics)) { | ||
| 76 | + if (foundParseErrors(diagnostics)) { | ||
| 78 | 77 | String msgPrefix = String.format("Error while parsing %s:\n", sourcesDescription); | |
| 79 | 78 | throw new IllegalStateException(msgPrefix + Joiner.on('\n').join(diagnostics)); | |
| 80 | 79 | } | |
| 81 | 80 | return new ParseResult( | |
| 82 | - sortDiagnosticsByKind(diagnostics), parsedCompilationUnits, Trees.instance(task)); | ||
| 81 | + sortDiagnosticsByKind(diagnostics), parsedCompilationUnits, JavacTrees.instance(context)); | ||
| 83 | 82 | } catch (IOException e) { | |
| 84 | 83 | throw new RuntimeException(e); | |
| 85 | - } finally { | ||
| 86 | - DummyJavaCompilerSubclass.closeCompiler(context); | ||
| 87 | 84 | } | |
| 88 | 85 | } | |
| 89 | 86 | ||
| 90 | - /** | ||
| 91 | - * Returns {@code true} if errors were found while parsing source files. | ||
| 92 | - * | ||
| 93 | - * <p>Normally, the parser reports error diagnostics, but in some cases there are no diagnostics; | ||
| 94 | - * instead the parse tree contains {@linkplain ErroneousTree "erroneous"} nodes. | ||
| 95 | - */ | ||
| 96 | - private static boolean foundParseErrors( | ||
| 97 | - Iterable<? extends CompilationUnitTree> parsedCompilationUnits, | ||
| 98 | - List<Diagnostic<? extends JavaFileObject>> diagnostics) { | ||
| 99 | - return diagnostics.stream().map(Diagnostic::getKind).anyMatch(isEqual(ERROR)) | ||
| 100 | - || Iterables.any(parsedCompilationUnits, Parser::hasErrorNode); | ||
| 101 | - } | ||
| 102 | - | ||
| 103 | - /** | ||
| 104 | - * Returns {@code true} if the tree contains at least one {@linkplain ErroneousTree "erroneous"} | ||
| 105 | - * node. | ||
| 106 | - */ | ||
| 107 | - private static boolean hasErrorNode(Tree tree) { | ||
| 108 | - return isTrue(HAS_ERRONEOUS_NODE.scan(tree, false)); | ||
| 109 | - } | ||
| 110 | - | ||
| 111 | - private static final TreeScanner<Boolean, Boolean> HAS_ERRONEOUS_NODE = | ||
| 112 | - new TreeScanner<Boolean, Boolean>() { | ||
| 113 | - @Override | ||
| 114 | - public Boolean visitErroneous(ErroneousTree node, Boolean p) { | ||
| 115 | - return true; | ||
| 116 | - } | ||
| 117 | - | ||
| 118 | - @Override | ||
| 119 | - public Boolean scan(Iterable<? extends Tree> nodes, Boolean p) { | ||
| 120 | - for (Tree node : firstNonNull(nodes, ImmutableList.<Tree>of())) { | ||
| 121 | - if (isTrue(scan(node, p))) { | ||
| 122 | - return true; | ||
| 123 | - } | ||
| 124 | - } | ||
| 125 | - return p; | ||
| 126 | - } | ||
| 127 | - | ||
| 128 | - @Override | ||
| 129 | - public Boolean scan(Tree tree, Boolean p) { | ||
| 130 | - return isTrue(p) ? p : super.scan(tree, p); | ||
| 131 | - } | ||
| 132 | - | ||
| 133 | - @Override | ||
| 134 | - public Boolean reduce(Boolean r1, Boolean r2) { | ||
| 135 | - return isTrue(r1) || isTrue(r2); | ||
| 136 | - } | ||
| 137 | - }; | ||
| 138 | - | ||
| 139 | - private static boolean isTrue(Boolean p) { | ||
| 140 | - return TRUE.equals(p); | ||
| 87 | + /** Returns {@code true} if errors were found while parsing source files. */ | ||
| 88 | + private static boolean foundParseErrors(List<Diagnostic<? extends JavaFileObject>> diagnostics) { | ||
| 89 | + return diagnostics.stream().anyMatch(d -> d.getKind().equals(ERROR)); | ||
| 141 | 90 | } | |
| 142 | 91 | ||
| 143 | 92 | private static ImmutableListMultimap<Diagnostic.Kind, Diagnostic<? extends JavaFileObject>> | |
@@ -184,20 +133,5 @@ Trees trees() { | |||
| 184 | 133 | } | |
| 185 | 134 | } | |
| 186 | 135 | ||
| 187 | - // JavaCompiler.compilerKey has protected access until Java 9, so this is a workaround. | ||
| 188 | - private static final class DummyJavaCompilerSubclass extends com.sun.tools.javac.main.JavaCompiler { | ||
| 189 | - private static void closeCompiler(Context context) { | ||
| 190 | - com.sun.tools.javac.main.JavaCompiler compiler = context.get(compilerKey); | ||
| 191 | - if (compiler != null) { | ||
| 192 | - compiler.close(); | ||
| 193 | - } | ||
| 194 | - } | ||
| 195 | - | ||
| 196 | - private DummyJavaCompilerSubclass() { | ||
| 197 | - // not instantiable | ||
| 198 | - super(null); | ||
| 199 | - } | ||
| 200 | - } | ||
| 201 | - | ||
| 202 | 136 | private Parser() {} | |
| 203 | 137 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,27 @@ | |||
| 1 | + package com.google.testing.compile; | ||
| 2 | + | ||
| 3 | + import static com.google.common.truth.Truth.assertThat; | ||
| 4 | + import static org.junit.Assert.assertThrows; | ||
| 5 | + | ||
| 6 | + import com.google.common.collect.ImmutableList; | ||
| 7 | + import javax.tools.JavaFileObject; | ||
| 8 | + import org.junit.Test; | ||
| 9 | + import org.junit.runner.RunWith; | ||
| 10 | + import org.junit.runners.JUnit4; | ||
| 11 | + | ||
| 12 | + @RunWith(JUnit4.class) | ||
| 13 | + public final class ParserTest { | ||
| 14 | + | ||
| 15 | + private static final JavaFileObject HELLO_WORLD_BROKEN = | ||
| 16 | + JavaFileObjects.forSourceLines( | ||
| 17 | + "test.HelloWorld", "package test;", "", "public class HelloWorld {", "}}"); | ||
| 18 | + | ||
| 19 | + @Test | ||
| 20 | + public void failsToParse() { | ||
| 21 | + IllegalStateException expected = | ||
| 22 | + assertThrows( | ||
| 23 | + IllegalStateException.class, | ||
| 24 | + () -> Parser.parse(ImmutableList.of(HELLO_WORLD_BROKEN), "hello world")); | ||
| 25 | + assertThat(expected).hasMessageThat().contains("HelloWorld.java:4: error"); | ||
| 26 | + } | ||
| 27 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments