jdk

Форк
0
/
AttrRecoveryTest.java 
225 строк · 8.7 Кб
1
/*
2
 * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
 *
5
 * This code is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License version 2 only, as
7
 * published by the Free Software Foundation.
8
 *
9
 * This code is distributed in the hope that it will be useful, but WITHOUT
10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
 * version 2 for more details (a copy is included in the LICENSE file that
13
 * accompanied this code).
14
 *
15
 * You should have received a copy of the GNU General Public License version
16
 * 2 along with this work; if not, write to the Free Software Foundation,
17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
 *
19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
 * or visit www.oracle.com if you need additional information or have any
21
 * questions.
22
 */
23

24
/**
25
 * @test
26
 * @bug 8273039
27
 * @summary Verify error recovery in Attr
28
 * @library /tools/lib
29
 * @modules jdk.compiler/com.sun.tools.javac.api
30
 *          jdk.compiler/com.sun.tools.javac.main
31
 *          jdk.compiler/com.sun.tools.javac.util
32
 * @build toolbox.ToolBox toolbox.JavacTask
33
 * @run main AttrRecoveryTest
34
*/
35

36
import com.sun.source.tree.AnnotationTree;
37
import com.sun.source.tree.CompilationUnitTree;
38
import com.sun.source.tree.ErroneousTree;
39
import com.sun.source.tree.VariableTree;
40
import com.sun.source.util.TaskEvent;
41
import com.sun.source.util.TaskListener;
42
import com.sun.source.util.TreePath;
43
import com.sun.source.util.TreePathScanner;
44
import com.sun.source.util.Trees;
45
import java.nio.file.Files;
46
import java.nio.file.Path;
47
import java.nio.file.Paths;
48
import java.util.List;
49
import java.util.concurrent.atomic.AtomicInteger;
50
import javax.lang.model.element.Element;
51
import javax.lang.model.type.TypeMirror;
52

53
import toolbox.TestRunner;
54
import toolbox.JavacTask;
55
import toolbox.Task;
56
import toolbox.ToolBox;
57

58
public class AttrRecoveryTest extends TestRunner {
59

60
    ToolBox tb;
61

62
    public static void main(String... args) throws Exception {
63
        new AttrRecoveryTest().runTests();
64
    }
65

66
    AttrRecoveryTest() {
67
        super(System.err);
68
        tb = new ToolBox();
69
    }
70

71
    public void runTests() throws Exception {
72
        runTests(m -> new Object[] { Paths.get(m.getName()) });
73
    }
74

75
    @Test
76
    public void testModifiers(Path base) throws Exception {
77
        record TestCase(String name, String source, String expectedAnnotation, String... errors) {}
78
        TestCase[] tests = new TestCase[] {
79
            new TestCase("a",
80
                         """
81
                         public class Test {
82
                             Object i () { return int strictfp @Deprecated = 0; }
83
                         }
84
                         """,
85
                         "java.lang.Deprecated",
86
                         "Test.java:2:30: compiler.err.dot.class.expected",
87
                         "Test.java:2:51: compiler.err.expected4: class, interface, enum, record",
88
                         "Test.java:2:26: compiler.err.unexpected.type: kindname.value, kindname.class",
89
                         "3 errors"),
90
            new TestCase("b",
91
                         """
92
                         public class Test {
93
                             Object i () { return int strictfp = 0; }
94
                         }
95
                         """,
96
                         null,
97
                         "Test.java:2:30: compiler.err.dot.class.expected",
98
                         "Test.java:2:39: compiler.err.expected4: class, interface, enum, record",
99
                         "Test.java:2:26: compiler.err.unexpected.type: kindname.value, kindname.class",
100
                         "3 errors")
101
        };
102
        for (TestCase test : tests) {
103
            Path current = base.resolve("" + test.name);
104
            Path src = current.resolve("src");
105
            Path classes = current.resolve("classes");
106
            tb.writeJavaFiles(src,
107
                              test.source);
108

109
            Files.createDirectories(classes);
110

111
            var log =
112
                    new JavacTask(tb)
113
                        .options("-XDrawDiagnostics",
114
                                 "-XDshould-stop.at=FLOW",
115
                                 "-Xlint:-preview")
116
                        .outdir(classes)
117
                        .files(tb.findJavaFiles(src))
118
                        .callback(t -> {
119
                            t.addTaskListener(new TaskListener() {
120
                                CompilationUnitTree parsed;
121
                                @Override
122
                                public void finished(TaskEvent e) {
123
                                    switch (e.getKind()) {
124
                                        case PARSE -> parsed = e.getCompilationUnit();
125
                                        case ANALYZE ->
126
                                            checkAnnotationsValid(t, parsed, test.expectedAnnotation);
127
                                    }
128
                                }
129
                            });
130
                        })
131
                        .run(Task.Expect.FAIL, 1)
132
                        .writeAll()
133
                        .getOutputLines(Task.OutputKind.DIRECT);
134
            if (!List.of(test.errors).equals(log)) {
135
                throw new AssertionError("Incorrect errors, expected: " + List.of(test.errors) +
136
                                          ", actual: " + log);
137
            }
138
        }
139
    }
140

141
    private void checkAnnotationsValid(com.sun.source.util.JavacTask task,
142
                                       CompilationUnitTree cut,
143
                                       String expected) {
144
        boolean[] foundAnnotation = new boolean[1];
145
        Trees trees = Trees.instance(task);
146

147
        new TreePathScanner<Void, Void>() {
148
            @Override
149
            public Void visitAnnotation(AnnotationTree node, Void p) {
150
                TreePath typePath = new TreePath(getCurrentPath(), node.getAnnotationType());
151
                Element el = trees.getElement(typePath);
152
                if (el == null || !el.equals(task.getElements().getTypeElement(expected))) {
153
                    throw new AssertionError();
154
                }
155
                foundAnnotation[0] = true;
156
                return super.visitAnnotation(node, p);
157
            }
158

159
            @Override
160
            public Void visitErroneous(ErroneousTree node, Void p) {
161
                return scan(node.getErrorTrees(), p);
162
            }
163
        }.scan(cut, null);
164
        if (foundAnnotation[0] ^ (expected != null)) {
165
            throw new AssertionError();
166
        }
167
    }
168

169
    @Test
170
    public void testVarAssignment2Self(Path base) throws Exception {
171
        Path current = base;
172
        Path src = current.resolve("src");
173
        Path classes = current.resolve("classes");
174
        tb.writeJavaFiles(src,
175
                          """
176
                          public class Test {
177
                              void t() {
178
                                  var v = v;
179
                              }
180
                          }
181
                          """);
182

183
        Files.createDirectories(classes);
184

185
        AtomicInteger seenVariables = new AtomicInteger();
186
        TreePathScanner<Void, Trees> checkTypes = new TreePathScanner<>() {
187
            @Override
188
            public Void visitVariable(VariableTree node, Trees trees) {
189
                if (node.getName().contentEquals("v")) {
190
                    TypeMirror type = trees.getTypeMirror(getCurrentPath());
191
                    if (type == null) {
192
                        throw new AssertionError("Unexpected null type!");
193
                    }
194
                    seenVariables.incrementAndGet();
195
                }
196
                return super.visitVariable(node, trees);
197
            }
198
        };
199

200
        new JavacTask(tb)
201
            .options("-XDrawDiagnostics")
202
            .outdir(classes)
203
            .files(tb.findJavaFiles(src))
204
            .callback(t -> {
205
                t.addTaskListener(new TaskListener() {
206
                    CompilationUnitTree parsed;
207
                    @Override
208
                    public void finished(TaskEvent e) {
209
                        switch (e.getKind()) {
210
                            case PARSE -> parsed = e.getCompilationUnit();
211
                            case COMPILATION ->
212
                                checkTypes.scan(parsed, Trees.instance(t));
213
                        }
214
                    }
215
                });
216
            })
217
            .run(Task.Expect.FAIL)
218
            .writeAll()
219
            .getOutputLines(Task.OutputKind.DIRECT);
220

221
        if (seenVariables.get() != 1) {
222
            throw new AssertionError("Didn't see enough variables: " + seenVariables);
223
        }
224
    }
225
}
226

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.