|
1 | 1 | /*
|
2 |
| - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
4 | 4 | *
|
5 | 5 | * This code is free software; you can redistribute it and/or modify it
|
|
23 | 23 |
|
24 | 24 | /*
|
25 | 25 | * @test
|
26 |
| - * @bug 8224922 |
| 26 | + * @bug 8224922 8365689 |
27 | 27 | * @summary Verify the behavior of the Elements.getFileObjectOf
|
28 | 28 | * @library /tools/lib
|
29 | 29 | * @modules jdk.compiler/com.sun.tools.javac.api
|
|
33 | 33 | * @run main TestFileObjectOf
|
34 | 34 | */
|
35 | 35 |
|
| 36 | +import com.sun.source.tree.IdentifierTree; |
| 37 | +import com.sun.source.tree.MemberSelectTree; |
36 | 38 | import com.sun.source.tree.VariableTree;
|
37 | 39 | import com.sun.source.util.TreePath;
|
38 | 40 | import java.nio.file.Path;
|
|
49 | 51 |
|
50 | 52 | import com.sun.source.util.TreePathScanner;
|
51 | 53 | import com.sun.source.util.Trees;
|
| 54 | +import javax.lang.model.util.ElementFilter; |
52 | 55 | import javax.tools.JavaFileObject;
|
53 | 56 | import toolbox.JarTask;
|
54 | 57 | import toolbox.JavacTask;
|
@@ -592,4 +595,156 @@ public SourceVersion getSupportedSourceVersion() {
|
592 | 595 |
|
593 | 596 | }
|
594 | 597 |
|
| 598 | + @Test //JDK-8365689 |
| 599 | + public void testUndefined(Path base) throws Exception { |
| 600 | + Path src = base.resolve("src"); |
| 601 | + tb.writeJavaFiles(src, |
| 602 | + """ |
| 603 | + module m { |
| 604 | + requires undefined1; //as module |
| 605 | + exports undefined2; //as package |
| 606 | + exports test; |
| 607 | + } |
| 608 | + """, |
| 609 | + """ |
| 610 | + package test; |
| 611 | + public class TestClass { |
| 612 | + void t() { |
| 613 | + undefined3.call(); |
| 614 | + this.undefined4(); |
| 615 | + } |
| 616 | + } |
| 617 | + """); |
| 618 | + Path classes = base.resolve("classes"); |
| 619 | + tb.createDirectories(classes); |
| 620 | + |
| 621 | + //from source, implicit: |
| 622 | + { |
| 623 | + List<String> log; |
| 624 | + |
| 625 | + log = new JavacTask(tb) |
| 626 | + .options("-XDshould-stop.at=FLOW", |
| 627 | + "-classpath", "", |
| 628 | + "-processorpath", System.getProperty("test.classes"), |
| 629 | + "-processor", UndefinedPrintFiles.class.getName(), |
| 630 | + "-sourcepath", src.toString()) |
| 631 | + .outdir(classes) |
| 632 | + .classes("java.lang.Object") |
| 633 | + .run(Task.Expect.FAIL) |
| 634 | + .writeAll() |
| 635 | + .getOutputLines(Task.OutputKind.STDOUT); |
| 636 | + |
| 637 | + List<String> expected = List.of( |
| 638 | + "undefined1: " + "<null>", |
| 639 | + "undefined2: " + "<null>", |
| 640 | + "undefined3: " + "<null>", |
| 641 | + "undefined4: " + "<null>" |
| 642 | + ); |
| 643 | + |
| 644 | + if (!expected.equals(log)) |
| 645 | + throw new AssertionError("expected output not found: " + log); |
| 646 | + } |
| 647 | + |
| 648 | + tb.cleanDirectory(classes); |
| 649 | + |
| 650 | + //from source, explicit: |
| 651 | + { |
| 652 | + List<String> log; |
| 653 | + |
| 654 | + log = new JavacTask(tb) |
| 655 | + .options("-XDshould-stop.at=FLOW", |
| 656 | + "-classpath", "", |
| 657 | + "-processorpath", System.getProperty("test.classes"), |
| 658 | + "-processor", UndefinedPrintFiles.class.getName()) |
| 659 | + .outdir(classes) |
| 660 | + .files(tb.findJavaFiles(src)) |
| 661 | + .run(Task.Expect.FAIL) |
| 662 | + .writeAll() |
| 663 | + .getOutputLines(Task.OutputKind.STDOUT); |
| 664 | + |
| 665 | + List<String> expected = List.of( |
| 666 | + "undefined1: " + "<null>", |
| 667 | + "undefined2: " + "<null>", |
| 668 | + "undefined3: " + "<null>", |
| 669 | + "undefined4: " + "<null>" |
| 670 | + ); |
| 671 | + |
| 672 | + if (!expected.equals(log)) |
| 673 | + throw new AssertionError("expected output not found: " + log); |
| 674 | + } |
| 675 | + } |
| 676 | + |
| 677 | + @SupportedAnnotationTypes("*") |
| 678 | + @SupportedOptions("fromClass") |
| 679 | + public static final class UndefinedPrintFiles extends AbstractProcessor { |
| 680 | + |
| 681 | + @Override |
| 682 | + public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { |
| 683 | + if (!roundEnv.processingOver()) |
| 684 | + return false; |
| 685 | + |
| 686 | + Elements elements = processingEnv.getElementUtils(); |
| 687 | + Trees trees = Trees.instance(processingEnv); |
| 688 | + |
| 689 | + Queue<Element> q = new ArrayDeque<>(); |
| 690 | + q.add(elements.getModuleElement("m")); |
| 691 | + |
| 692 | + while (!q.isEmpty()) { |
| 693 | + Element currentElement = q.remove(); |
| 694 | + |
| 695 | + switch (currentElement.getKind()) { |
| 696 | + case MODULE -> { |
| 697 | + ElementFilter.exportsIn(((ModuleElement) currentElement).getDirectives()) |
| 698 | + .stream() |
| 699 | + .map(ed -> ed.getPackage()) |
| 700 | + .forEach(q::add); |
| 701 | + } |
| 702 | + case PACKAGE -> { |
| 703 | + currentElement.getEnclosedElements() |
| 704 | + .stream() |
| 705 | + .sorted((e1, e2) -> e1.getSimpleName().toString().compareTo(e2.getSimpleName().toString())) |
| 706 | + .forEach(q::add); |
| 707 | + continue; |
| 708 | + } |
| 709 | + default -> {} |
| 710 | + } |
| 711 | + |
| 712 | + TreePath tp = trees.getPath(currentElement); |
| 713 | + |
| 714 | + new TreePathScanner<>() { |
| 715 | + @Override |
| 716 | + public Object visitIdentifier(IdentifierTree node, Object p) { |
| 717 | + if (node.getName().toString().startsWith("undefined")) { |
| 718 | + Element el = trees.getElement(getCurrentPath()); |
| 719 | + handleDeclaration(el); |
| 720 | + } |
| 721 | + return super.visitIdentifier(node, p); |
| 722 | + } |
| 723 | + |
| 724 | + @Override |
| 725 | + public Object visitMemberSelect(MemberSelectTree node, Object p) { |
| 726 | + if (node.getIdentifier().toString().startsWith("undefined")) { |
| 727 | + Element el = trees.getElement(getCurrentPath()); |
| 728 | + handleDeclaration(el); |
| 729 | + } |
| 730 | + return super.visitMemberSelect(node, p); |
| 731 | + } |
| 732 | + }.scan(tp, null); |
| 733 | + } |
| 734 | + |
| 735 | + return false; |
| 736 | + } |
| 737 | + |
| 738 | + void handleDeclaration(Element el) { |
| 739 | + Elements elements = processingEnv.getElementUtils(); |
| 740 | + JavaFileObject fileObjects = elements.getFileObjectOf(el); |
| 741 | + System.out.println(el.getSimpleName() + ": " + (fileObjects != null ? fileObjects.toUri().toString() : "<null>")); |
| 742 | + } |
| 743 | + |
| 744 | + @Override |
| 745 | + public SourceVersion getSupportedSourceVersion() { |
| 746 | + return SourceVersion.latestSupported(); |
| 747 | + } |
| 748 | + |
| 749 | + } |
595 | 750 | }
|
0 commit comments