jdk

Форк
0
/
UndefinedAccessFlagTest.java 
128 строк · 5.1 Кб
1
/*
2
 * Copyright (c) 2024, 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 8333748
26
 * @summary javap should not fail if reserved access flag bits are set to 1
27
 * @library /tools/lib
28
 * @modules jdk.jdeps/com.sun.tools.javap
29
 * @enablePreview
30
 * @run junit UndefinedAccessFlagTest
31
 */
32

33
import org.junit.jupiter.params.ParameterizedTest;
34
import org.junit.jupiter.params.provider.EnumSource;
35
import toolbox.JavapTask;
36
import toolbox.Task;
37
import toolbox.ToolBox;
38

39
import java.lang.classfile.AccessFlags;
40
import java.lang.classfile.ClassModel;
41
import java.lang.classfile.FieldModel;
42
import java.lang.classfile.MethodModel;
43
import java.lang.classfile.attribute.InnerClassInfo;
44
import java.lang.classfile.attribute.InnerClassesAttribute;
45
import java.nio.file.Files;
46
import java.nio.file.Path;
47

48
import static java.lang.classfile.ClassFile.*;
49
import static org.junit.jupiter.api.Assertions.assertTrue;
50

51
public class UndefinedAccessFlagTest {
52

53
    final ToolBox toolBox = new ToolBox();
54

55
    enum TestLocation {
56
        NONE(false), CLASS, FIELD, METHOD, INNER_CLASS(false);
57

58
        final boolean fails;
59
        TestLocation() { this(true); }
60
        TestLocation(boolean fails) { this.fails = fails; }
61
    }
62

63
    @ParameterizedTest
64
    @EnumSource(TestLocation.class)
65
    void test(TestLocation location) throws Throwable {
66
        var cf = of();
67
        ClassModel cm;
68
        try (var is = UndefinedAccessFlagTest.class.getResourceAsStream(
69
            "/UndefinedAccessFlagTest$SampleInnerClass.class"
70
        )) {
71
            cm = cf.parse(is.readAllBytes());
72
        }
73
        var bytes = cf.transformClass(cm, (cb, ce) -> {
74
            switch (ce) {
75
                case AccessFlags flags when location == TestLocation.CLASS -> cb
76
                    .withFlags(flags.flagsMask() | ACC_PRIVATE);
77
                case FieldModel f when location == TestLocation.FIELD -> cb
78
                    .transformField(f, (fb, fe) -> {
79
                        if (fe instanceof AccessFlags flags) {
80
                            fb.withFlags(flags.flagsMask() | ACC_SYNCHRONIZED);
81
                        } else {
82
                            fb.with(fe);
83
                        }
84
                    });
85
                case MethodModel m when location == TestLocation.METHOD -> cb
86
                    .transformMethod(m, (mb, me) -> {
87
                        if (me instanceof AccessFlags flags) {
88
                            mb.withFlags(flags.flagsMask() | ACC_INTERFACE);
89
                        } else {
90
                            mb.with(me);
91
                        }
92
                    });
93
                case InnerClassesAttribute attr when location == TestLocation.INNER_CLASS -> cb
94
                    .with(InnerClassesAttribute.of(attr.classes().stream()
95
                        .map(ic -> InnerClassInfo.of(ic.innerClass(), ic.outerClass(), ic.innerName(), ic.flagsMask() | 0x0020))
96
                        .toList()));
97
                default -> cb.with(ce);
98
            }
99
        });
100

101
        Files.write(Path.of("transformed.class"), bytes);
102

103
        var lines = new JavapTask(toolBox)
104
            .classes("transformed.class")
105
            .options("-c", "-p", "-v")
106
            .run(location.fails ? Task.Expect.FAIL : Task.Expect.SUCCESS)
107
            .writeAll()
108
            .getOutputLines(Task.OutputKind.DIRECT);
109

110
        // No termination when access flag error happens
111
        assertTrue(lines.stream().anyMatch(l -> l.contains("java.lang.String field;")));
112
        assertTrue(lines.stream().anyMatch(l -> l.contains("UndefinedAccessFlagTest$SampleInnerClass();")));
113
        assertTrue(lines.stream().anyMatch(l -> l.contains("void method();")));
114
        assertTrue(lines.stream().anyMatch(l -> l.contains("SampleInnerClass=class UndefinedAccessFlagTest$SampleInnerClass of class UndefinedAccessFlagTest")));
115

116
        // Remove non-error lines
117
        assertTrue(lines.removeIf(st -> !st.startsWith("Error:")));
118
        // Desired locations has errors
119
        assertTrue(location == TestLocation.NONE || !lines.isEmpty());
120
        // Access Flag errors only
121
        assertTrue(lines.stream().allMatch(l -> l.contains("Access Flags:")), () -> String.join("\n", lines));
122
    }
123

124
    static class SampleInnerClass {
125
        String field;
126
        void method() {}
127
    }
128
}
129

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

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

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

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