undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com Patches, unit tests, benchmarks, whitepaper, and outreach briefs. Public domain — no copyright claimed. Use freely.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
391
test/jdk/java/lang/AbstractCompressExpandTest.java
Normal file
391
test/jdk/java/lang/AbstractCompressExpandTest.java
Normal file
|
|
@ -0,0 +1,391 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
import java.util.random.RandomGenerator;
|
||||
|
||||
public abstract class AbstractCompressExpandTest {
|
||||
|
||||
static int testCompress(int i, int mask) {
|
||||
int result = 0;
|
||||
int rpos = 0;
|
||||
while (mask != 0) {
|
||||
if ((mask & 1) != 0) {
|
||||
result |= (i & 1) << rpos;
|
||||
rpos++; // conditional increment
|
||||
}
|
||||
i >>>= 1; // unconditional shift-out
|
||||
mask >>>= 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static int testExpand(int i, int mask) {
|
||||
int result = 0;
|
||||
int rpos = 0;
|
||||
while (mask != 0) {
|
||||
if ((mask & 1) != 0) {
|
||||
result |= (i & 1) << rpos;
|
||||
i >>>= 1; // conditional shift-out
|
||||
}
|
||||
rpos++; // unconditional increment
|
||||
mask >>>= 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static long testCompress(long i, long mask) {
|
||||
long result = 0;
|
||||
int rpos = 0;
|
||||
while (mask != 0) {
|
||||
if ((mask & 1) != 0) {
|
||||
result |= (i & 1) << rpos++;
|
||||
}
|
||||
i >>>= 1;
|
||||
mask >>>= 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static long testExpand(long i, long mask) {
|
||||
long result = 0;
|
||||
int rpos = 0;
|
||||
while (mask != 0) {
|
||||
if ((mask & 1) != 0) {
|
||||
result |= (i & 1) << rpos;
|
||||
i >>>= 1;
|
||||
}
|
||||
rpos++;
|
||||
mask >>>= 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
abstract int actualCompress(int i, int mask);
|
||||
|
||||
abstract int actualExpand(int i, int mask);
|
||||
|
||||
abstract int expectedCompress(int i, int mask);
|
||||
|
||||
abstract int expectedExpand(int i, int mask);
|
||||
|
||||
abstract long actualCompress(long i, long mask);
|
||||
|
||||
abstract long actualExpand(long i, long mask);
|
||||
|
||||
abstract long expectedCompress(long i, long mask);
|
||||
|
||||
abstract long expectedExpand(long i, long mask);
|
||||
|
||||
static int SIZE = 1024;
|
||||
|
||||
<T> Supplier<T> supplierWithToString(Supplier<T> s, String name) {
|
||||
return new Supplier<>() {
|
||||
@Override
|
||||
public T get() {
|
||||
return s.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
Object[][] maskIntProvider() {
|
||||
RandomGenerator rg = RandomGenerator.getDefault();
|
||||
|
||||
return new Object[][]{
|
||||
{supplierWithToString(() -> rg.ints(SIZE).toArray(), "random masks")},
|
||||
{supplierWithToString(this::contiguousMasksInt, "contiguous masks")}
|
||||
};
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
Object[][] maskLongProvider() {
|
||||
RandomGenerator rg = RandomGenerator.getDefault();
|
||||
|
||||
return new Object[][]{
|
||||
{supplierWithToString(() -> rg.longs(SIZE).toArray(), "random masks")},
|
||||
{supplierWithToString(this::contiguousMasksLong, "contiguous masks")}
|
||||
};
|
||||
}
|
||||
|
||||
int[] contiguousMasksInt() {
|
||||
int size = 32 * (32 + 1) / 2 + 1; // 528 + 1
|
||||
int[] masks = new int[size];
|
||||
|
||||
int i = 0;
|
||||
masks[i++] = 0;
|
||||
for (int len = 1; len < 32; len++) {
|
||||
for (int pos = 0; pos <= 32 - len; pos++) {
|
||||
masks[i++] = ((1 << len) - 1) << pos;
|
||||
}
|
||||
}
|
||||
masks[i++] = -1;
|
||||
|
||||
assert i == masks.length;
|
||||
return masks;
|
||||
}
|
||||
|
||||
long[] contiguousMasksLong() {
|
||||
int size = 64 * (64 + 1) / 2 + 1; // 2080 + 1
|
||||
long[] masks = new long[size];
|
||||
|
||||
|
||||
int i = 0;
|
||||
masks[i++] = 0L;
|
||||
for (int len = 1; len < 64; len++) {
|
||||
for (int pos = 0; pos <= 64 - len; pos++) {
|
||||
masks[i++] = ((1L << len) - 1) << pos;
|
||||
}
|
||||
}
|
||||
masks[i++] = -1L;
|
||||
|
||||
assert i == masks.length;
|
||||
return masks;
|
||||
}
|
||||
|
||||
|
||||
@Test(dataProvider = "maskIntProvider")
|
||||
public void testCompressInt(Supplier<int[]> maskProvider) {
|
||||
RandomGenerator rg = RandomGenerator.getDefault();
|
||||
|
||||
int[] values = rg.ints(SIZE).toArray();
|
||||
int[] masks = maskProvider.get();
|
||||
|
||||
for (int i : values) {
|
||||
for (int m : masks) {
|
||||
int actual = actualCompress(i, m);
|
||||
int expected = expectedCompress(i, m);
|
||||
if (actual != expected) {
|
||||
print(i, m, actual, expected);
|
||||
}
|
||||
Assert.assertEquals(actual, expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "maskIntProvider")
|
||||
public void testExpandInt(Supplier<int[]> maskProvider) {
|
||||
RandomGenerator rg = RandomGenerator.getDefault();
|
||||
|
||||
int[] values = rg.ints(SIZE).toArray();
|
||||
int[] masks = maskProvider.get();
|
||||
|
||||
for (int i : values) {
|
||||
for (int m : masks) {
|
||||
int actual = actualExpand(i, m);
|
||||
int expected = expectedExpand(i, m);
|
||||
if (actual != expected) {
|
||||
print(i, m, actual, expected);
|
||||
}
|
||||
Assert.assertEquals(actual, expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "maskIntProvider")
|
||||
public void testCompressExpandInt(Supplier<int[]> maskProvider) {
|
||||
RandomGenerator rg = RandomGenerator.getDefault();
|
||||
|
||||
int[] values = rg.ints(SIZE).toArray();
|
||||
int[] masks = maskProvider.get();
|
||||
|
||||
for (int i : values) {
|
||||
for (int m : masks) {
|
||||
{
|
||||
int a = actualCompress(actualExpand(i, m), m);
|
||||
Assert.assertEquals(a, normalizeCompressedValue(i, m));
|
||||
|
||||
int b = actualCompress(actualExpand(i, ~m), ~m);
|
||||
Assert.assertEquals(b, normalizeCompressedValue(i, ~m));
|
||||
}
|
||||
|
||||
{
|
||||
int a = actualExpand(actualCompress(i, m), m);
|
||||
// Clear unset mask bits
|
||||
Assert.assertEquals(a, i & m);
|
||||
|
||||
int b = actualExpand(actualCompress(i, ~m), ~m);
|
||||
Assert.assertEquals(a & b, 0);
|
||||
Assert.assertEquals(a | b, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContiguousMasksInt() {
|
||||
RandomGenerator rg = RandomGenerator.getDefault();
|
||||
|
||||
int[] values = rg.ints(SIZE).toArray();
|
||||
|
||||
for (int i : values) {
|
||||
assertContiguousMask(i, 0, 0L);
|
||||
for (int len = 1; len < 32; len++) {
|
||||
for (int pos = 0; pos <= 32 - len; pos++) {
|
||||
int mask = ((1 << len) - 1) << pos;
|
||||
|
||||
assertContiguousMask(i, pos, mask);
|
||||
}
|
||||
}
|
||||
assertContiguousMask(i, 0, -1L);
|
||||
}
|
||||
}
|
||||
|
||||
void assertContiguousMask(int i, int pos, int mask) {
|
||||
Assert.assertEquals(actualCompress(i, mask), (i & mask) >>> pos);
|
||||
Assert.assertEquals(actualExpand(i, mask), (i << pos) & mask);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "maskLongProvider")
|
||||
public void testCompressLong(Supplier<long[]> maskProvider) {
|
||||
RandomGenerator rg = RandomGenerator.getDefault();
|
||||
|
||||
long[] values = rg.longs(SIZE).toArray();
|
||||
long[] masks = maskProvider.get();
|
||||
|
||||
for (long i : values) {
|
||||
for (long m : masks) {
|
||||
long actual = actualCompress(i, m);
|
||||
long expected = expectedCompress(i, m);
|
||||
if (actual != expected) {
|
||||
print(i, m, actual, expected);
|
||||
}
|
||||
Assert.assertEquals(actual, expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "maskLongProvider")
|
||||
public void testExpandLong(Supplier<long[]> maskProvider) {
|
||||
RandomGenerator rg = RandomGenerator.getDefault();
|
||||
|
||||
long[] values = rg.longs(SIZE).toArray();
|
||||
long[] masks = maskProvider.get();
|
||||
|
||||
for (long i : values) {
|
||||
for (long m : masks) {
|
||||
long actual = actualExpand(i, m);
|
||||
long expected = expectedExpand(i, m);
|
||||
if (actual != expected) {
|
||||
print(i, m, actual, expected);
|
||||
}
|
||||
Assert.assertEquals(actual, expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "maskLongProvider")
|
||||
public void testCompressExpandLong(Supplier<long[]> maskProvider) {
|
||||
RandomGenerator rg = RandomGenerator.getDefault();
|
||||
|
||||
long[] values = rg.longs(SIZE).toArray();
|
||||
long[] masks = maskProvider.get();
|
||||
|
||||
for (long i : values) {
|
||||
for (long m : masks) {
|
||||
{
|
||||
long a = actualCompress(actualExpand(i, m), m);
|
||||
Assert.assertEquals(a, normalizeCompressedValue(i, m));
|
||||
|
||||
long b = actualCompress(actualExpand(i, ~m), ~m);
|
||||
Assert.assertEquals(b, normalizeCompressedValue(i, ~m));
|
||||
}
|
||||
|
||||
{
|
||||
long a = actualExpand(actualCompress(i, m), m);
|
||||
// Clear unset mask bits
|
||||
Assert.assertEquals(a, i & m);
|
||||
|
||||
long b = actualExpand(actualCompress(i, ~m), ~m);
|
||||
Assert.assertEquals(a & b, 0);
|
||||
Assert.assertEquals(a | b, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContiguousMasksLong() {
|
||||
RandomGenerator rg = RandomGenerator.getDefault();
|
||||
|
||||
long[] values = rg.longs(SIZE).toArray();
|
||||
|
||||
for (long i : values) {
|
||||
assertContiguousMask(i, 0, 0L);
|
||||
for (int len = 1; len < 64; len++) {
|
||||
for (int pos = 0; pos <= 64 - len; pos++) {
|
||||
long mask = ((1L << len) - 1) << pos;
|
||||
|
||||
assertContiguousMask(i, pos, mask);
|
||||
}
|
||||
}
|
||||
assertContiguousMask(i, 0, -1L);
|
||||
}
|
||||
}
|
||||
|
||||
void assertContiguousMask(long i, int pos, long mask) {
|
||||
Assert.assertEquals(actualCompress(i, mask), (i & mask) >>> pos);
|
||||
Assert.assertEquals(actualExpand(i, mask), (i << pos) & mask);
|
||||
}
|
||||
|
||||
static int normalizeCompressedValue(int i, int mask) {
|
||||
int mbc = Integer.bitCount(mask);
|
||||
if (mbc != 32) {
|
||||
return i & ((1 << mbc) - 1);
|
||||
} else {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
static long normalizeCompressedValue(long i, long mask) {
|
||||
int mbc = Long.bitCount(mask);
|
||||
if (mbc != 64) {
|
||||
return i & ((1L << mbc) - 1);
|
||||
} else {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
static void print(int i, int m, int actual, int expected) {
|
||||
System.out.println(String.format("i = %s", Integer.toBinaryString(i)));
|
||||
System.out.println(String.format("m = %s", Integer.toBinaryString(m)));
|
||||
System.out.println(String.format("a = %s", Integer.toBinaryString(actual)));
|
||||
System.out.println(String.format("e = %s", Integer.toBinaryString(expected)));
|
||||
}
|
||||
|
||||
static void print(long i, long m, long actual, long expected) {
|
||||
System.out.println(String.format("i = %s", Long.toBinaryString(i)));
|
||||
System.out.println(String.format("m = %s", Long.toBinaryString(m)));
|
||||
System.out.println(String.format("a = %s", Long.toBinaryString(actual)));
|
||||
System.out.println(String.format("e = %s", Long.toBinaryString(expected)));
|
||||
}
|
||||
}
|
||||
394
test/jdk/java/lang/Appendable/Basic.java
Normal file
394
test/jdk/java/lang/Appendable/Basic.java
Normal file
|
|
@ -0,0 +1,394 @@
|
|||
/*
|
||||
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 5067405
|
||||
* @summary Basic test for classes which implement Appendable.
|
||||
*/
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.CharArrayWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
|
||||
interface BasicRunnable extends Runnable {
|
||||
void init(Appendable a, String csq, String exp);
|
||||
Appendable reset(Appendable csq);
|
||||
}
|
||||
|
||||
public class Basic {
|
||||
|
||||
private static final String s = "Beware the Jabberwock, my son!";
|
||||
private static CharArrayWriter gw = new CharArrayWriter();
|
||||
private static ByteArrayOutputStream gos = new ByteArrayOutputStream();
|
||||
|
||||
private static File newFile() {
|
||||
File f = null;
|
||||
try {
|
||||
f = File.createTempFile("append", ".txt");
|
||||
f.deleteOnExit();
|
||||
} catch (IOException x) {
|
||||
fail(x);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
private static File gf = newFile();
|
||||
|
||||
private static int fail = 0;
|
||||
private static int pass = 0;
|
||||
|
||||
private static Throwable first;
|
||||
|
||||
static void pass() {
|
||||
pass++;
|
||||
}
|
||||
|
||||
static void fail(Throwable ex) {
|
||||
if (first == null)
|
||||
first = ex;
|
||||
System.err.println("FAILED: unexpected exception");
|
||||
fail++;
|
||||
}
|
||||
|
||||
static void fail(String fs, Throwable ex) {
|
||||
String s = "'" + fs + "': " + ex.getClass().getName() + " not thrown";
|
||||
if (first == null)
|
||||
first = ex;
|
||||
System.err.println("FAILED: " + s);
|
||||
fail++;
|
||||
}
|
||||
|
||||
static void fail(String fs, String exp, String got) {
|
||||
String s = "'" + fs + "': Expected '" + exp + "', got '" + got + "'";
|
||||
if (first == null)
|
||||
first = new RuntimeException(s);
|
||||
System.err.println("FAILED: " + s);
|
||||
fail++;
|
||||
}
|
||||
|
||||
static void ck(String s, String exp, String got) {
|
||||
if (!exp.equals(got))
|
||||
fail(s, exp, got);
|
||||
else
|
||||
pass();
|
||||
}
|
||||
|
||||
private static BasicRunnable testBufferedWriter =
|
||||
new BasicRunnable() {
|
||||
private String csn, exp;
|
||||
public void init(Appendable bw, String csn, String exp) {
|
||||
try {
|
||||
((BufferedWriter)bw).flush();
|
||||
} catch (IOException x) {
|
||||
fail(x);
|
||||
}
|
||||
this.csn = csn;
|
||||
this.exp = exp;
|
||||
}
|
||||
public void run() {
|
||||
ck("BufferedWriter.append(" + csn + ")", exp, gw.toString());
|
||||
}
|
||||
public Appendable reset(Appendable bw) {
|
||||
gw.reset();
|
||||
return bw;
|
||||
}};
|
||||
|
||||
private static BasicRunnable testCharArrayWriter =
|
||||
new BasicRunnable() {
|
||||
private String csn, exp;
|
||||
private CharArrayWriter cw;
|
||||
public void init(Appendable cw, String csn, String exp) {
|
||||
this.cw = (CharArrayWriter)cw;
|
||||
this.csn = csn;
|
||||
this.exp = exp;
|
||||
}
|
||||
public void run() {
|
||||
ck("CharArrayWriter.append(" + csn + ")", exp, cw.toString());
|
||||
}
|
||||
public Appendable reset(Appendable cw) {
|
||||
((CharArrayWriter)cw).reset();
|
||||
return cw;
|
||||
}};
|
||||
|
||||
private static BasicRunnable testFileWriter =
|
||||
new BasicRunnable() {
|
||||
private String csn, exp;
|
||||
public void init(Appendable fw, String csn, String exp) {
|
||||
try {
|
||||
((FileWriter)fw).flush();
|
||||
} catch (IOException x) {
|
||||
fail(x);
|
||||
}
|
||||
this.csn = csn;
|
||||
this.exp = exp;
|
||||
}
|
||||
public void run() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
try {
|
||||
BufferedReader in = new BufferedReader(new FileReader(gf));
|
||||
String line;
|
||||
while (true) {
|
||||
if ((line = in.readLine()) == null)
|
||||
break;
|
||||
sb.append(line);
|
||||
}
|
||||
} catch (IOException x) {
|
||||
fail(x);
|
||||
}
|
||||
ck("FileWriter.append(" + csn + ")", exp, sb.toString());
|
||||
}
|
||||
public Appendable reset(Appendable fw) {
|
||||
try {
|
||||
fw = new FileWriter(gf);
|
||||
} catch (IOException x) {
|
||||
fail(x);
|
||||
}
|
||||
return fw;
|
||||
}};
|
||||
|
||||
private static BasicRunnable testOutputStreamWriter =
|
||||
new BasicRunnable() {
|
||||
private String csn, exp;
|
||||
public void init(Appendable osw, String csn, String exp) {
|
||||
try {
|
||||
((OutputStreamWriter)osw).flush();
|
||||
} catch (IOException x) {
|
||||
fail(x);
|
||||
}
|
||||
this.csn = csn;
|
||||
this.exp = exp;
|
||||
}
|
||||
public void run() {
|
||||
ck("OutputStreamWriter.append(" + csn + ")", exp, gos.toString());
|
||||
}
|
||||
public Appendable reset(Appendable osw) {
|
||||
gos.reset();
|
||||
return osw;
|
||||
}};
|
||||
|
||||
private static BasicRunnable testPrintWriter =
|
||||
new BasicRunnable() {
|
||||
private String csn, exp;
|
||||
public void init(Appendable pw, String csn, String exp) {
|
||||
((PrintWriter)pw).flush();
|
||||
this.csn = csn;
|
||||
this.exp = exp;
|
||||
}
|
||||
public void run() {
|
||||
ck("PrintWriter.append(" + csn + ")", exp, gw.toString());
|
||||
}
|
||||
public Appendable reset(Appendable pw) {
|
||||
gw.reset();
|
||||
return pw;
|
||||
}};
|
||||
|
||||
private static BasicRunnable testStringWriter =
|
||||
new BasicRunnable() {
|
||||
private String csn, exp;
|
||||
private StringWriter sw;
|
||||
public void init(Appendable sw, String csn, String exp) {
|
||||
this.sw = (StringWriter)sw;
|
||||
this.csn = csn;
|
||||
this.exp = exp;
|
||||
}
|
||||
public void run() {
|
||||
ck("StringWriter.append(" + csn + ")", exp, sw.toString());
|
||||
}
|
||||
public Appendable reset(Appendable sw) {
|
||||
return new StringWriter();
|
||||
}};
|
||||
|
||||
private static BasicRunnable testPrintStream =
|
||||
new BasicRunnable() {
|
||||
private String csn, exp;
|
||||
public void init(Appendable ps, String csn, String exp) {
|
||||
((PrintStream)ps).flush();
|
||||
this.csn = csn;
|
||||
this.exp = exp;
|
||||
}
|
||||
public void run() {
|
||||
ck("PrintStream.append(" + csn + ")", exp, gos.toString());
|
||||
}
|
||||
public Appendable reset(Appendable ps) {
|
||||
gos.reset();
|
||||
return ps;
|
||||
}};
|
||||
|
||||
private static BasicRunnable testCharBuffer =
|
||||
new BasicRunnable() {
|
||||
private String csn, exp;
|
||||
private CharBuffer cb;
|
||||
public void init(Appendable cb, String csn, String exp) {
|
||||
this.cb = (CharBuffer)cb;
|
||||
this.csn = csn;
|
||||
this.exp = exp;
|
||||
}
|
||||
public void run() {
|
||||
cb.limit(cb.position()).rewind();
|
||||
ck("CharBuffer.append(" + csn + ")", exp, cb.toString());
|
||||
}
|
||||
public Appendable reset(Appendable cb) {
|
||||
((CharBuffer)cb).clear();
|
||||
return cb;
|
||||
}};
|
||||
|
||||
private static BasicRunnable testStringBuffer =
|
||||
new BasicRunnable() {
|
||||
private String csn, exp;
|
||||
private StringBuffer sb;
|
||||
public void init(Appendable sb, String csn, String exp) {
|
||||
this.sb = (StringBuffer)sb;
|
||||
this.csn = csn;
|
||||
this.exp = exp;
|
||||
}
|
||||
public void run() {
|
||||
ck("StringBuffer.append(" + csn + ")", exp, sb.toString());
|
||||
}
|
||||
public Appendable reset(Appendable sb) {
|
||||
return new StringBuffer();
|
||||
}};
|
||||
|
||||
private static BasicRunnable testStringBuilder =
|
||||
new BasicRunnable() {
|
||||
private String csn, exp;
|
||||
private StringBuilder sb;
|
||||
public void init(Appendable sb, String csn, String exp) {
|
||||
this.sb = (StringBuilder)sb;
|
||||
this.csn = csn;
|
||||
this.exp = exp;
|
||||
}
|
||||
public void run() {
|
||||
ck("StringBuilder.append(" + csn + ")", exp, sb.toString());
|
||||
}
|
||||
public Appendable reset(Appendable sb) {
|
||||
return new StringBuilder();
|
||||
}};
|
||||
|
||||
private static void test(Appendable a, CharSequence csq, BasicRunnable thunk) {
|
||||
// appends that should always work
|
||||
int [][] sp = { { 0, 0 }, { 11, 11 }, { 11, 21 }, { 0, 7 },
|
||||
{ 0, s.length() }, { s.length(), s.length() },
|
||||
};
|
||||
for (int j = 0; j < sp.length; j++) {
|
||||
int start = sp[j][0];
|
||||
int end = sp[j][1];
|
||||
try {
|
||||
thunk.init(a.append(csq, start, end),
|
||||
csq.getClass().getName(),
|
||||
s.subSequence(start, end).toString());
|
||||
thunk.run();
|
||||
a = thunk.reset(a);
|
||||
} catch (IOException x) {
|
||||
fail(x);
|
||||
}
|
||||
}
|
||||
|
||||
// appends that should always throw IndexOutOfBoundsException
|
||||
int [][] sf = { { -1, 0 }, { 0, -1 }, { 11, 10 },
|
||||
{ 0, s.length() + 1},
|
||||
};
|
||||
for (int j = 0; j < sf.length; j++) {
|
||||
int start = sf[j][0];
|
||||
int end = sf[j][1];
|
||||
try {
|
||||
a.append(csq, start, end);
|
||||
fail("start = " + start + ", end = " + end,
|
||||
new IndexOutOfBoundsException());
|
||||
a = thunk.reset(a);
|
||||
} catch (IndexOutOfBoundsException x) {
|
||||
pass();
|
||||
} catch (IOException x) {
|
||||
fail(x);
|
||||
}
|
||||
}
|
||||
|
||||
// appends of null
|
||||
int start = 1;
|
||||
int end = 2;
|
||||
try {
|
||||
thunk.init(a.append(null, start, end), "null",
|
||||
"null".subSequence(start, end).toString());
|
||||
thunk.run();
|
||||
a = thunk.reset(a);
|
||||
} catch (IOException x) {
|
||||
fail(x);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String [] args) throws Exception {
|
||||
// CharSequences
|
||||
CharBuffer cb = CharBuffer.allocate(128).put(s);
|
||||
cb.limit(s.length()).rewind();
|
||||
CharBuffer dcb = ByteBuffer.allocateDirect(128).asCharBuffer().put(s);
|
||||
dcb.limit(s.length()).rewind();
|
||||
CharSequence [] ca = { s,
|
||||
new StringBuffer(s),
|
||||
new StringBuilder(s),
|
||||
cb,
|
||||
dcb,
|
||||
};
|
||||
|
||||
// Appendables/Writers
|
||||
Object [][] wa = { { new CharArrayWriter(), testCharArrayWriter },
|
||||
{ new BufferedWriter(gw), testBufferedWriter },
|
||||
// abstract, no implementing classes in jdk
|
||||
// { new FilterWriter(), testFilterWriter },
|
||||
{ new FileWriter(gf), testFileWriter },
|
||||
{ new OutputStreamWriter(gos), testOutputStreamWriter },
|
||||
// covered by previous two test cases
|
||||
// { new PipedWriter(gw), testPipedWriter },
|
||||
{ new PrintWriter(gw), testPrintWriter },
|
||||
{ new StringWriter(), testStringWriter },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ca.length; i++) {
|
||||
CharSequence a = ca[i];
|
||||
for (int j = 0; j < wa.length; j++)
|
||||
test((Writer)wa[j][0], a, (BasicRunnable)wa[j][1]);
|
||||
|
||||
// other Appendables
|
||||
test(new PrintStream(gos), a, testPrintStream);
|
||||
test(CharBuffer.allocate(128), a, testCharBuffer);
|
||||
test(ByteBuffer.allocateDirect(128).asCharBuffer(), a, testCharBuffer);
|
||||
test(new StringBuffer(), a, testStringBuffer);
|
||||
test(new StringBuilder(), a, testStringBuilder);
|
||||
}
|
||||
|
||||
if (fail != 0)
|
||||
throw new RuntimeException((fail + pass) + " tests: "
|
||||
+ fail + " failure(s), first", first);
|
||||
else
|
||||
System.out.println("all " + (fail + pass) + " tests passed");
|
||||
}
|
||||
}
|
||||
41
test/jdk/java/lang/AssertionError/Cause.java
Normal file
41
test/jdk/java/lang/AssertionError/Cause.java
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 4513384
|
||||
* @summary Object Constructor now sets cause if Object is an instance of Throwable.
|
||||
* @author Josh Bloch
|
||||
*/
|
||||
|
||||
public class Cause {
|
||||
public static void main(String[] args) throws Exception {
|
||||
Exception e = new Exception();
|
||||
AssertionError ae = new AssertionError(e);
|
||||
if (ae.getCause() != e)
|
||||
throw new Exception("Cause not set.");
|
||||
ae = new AssertionError("gosh it's late");
|
||||
if (ae.getCause() != null)
|
||||
throw new Exception("Cause set erroneously: " + ae.getCause());
|
||||
}
|
||||
}
|
||||
37
test/jdk/java/lang/Boolean/Factory.java
Normal file
37
test/jdk/java/lang/Boolean/Factory.java
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4262398
|
||||
* @summary Basic test for Boolean.valueOf(boolean b).
|
||||
*/
|
||||
|
||||
public class Factory {
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (Boolean.valueOf(true) != Boolean.TRUE)
|
||||
throw new Exception("Truth failure");
|
||||
if (Boolean.valueOf(false) != Boolean.FALSE)
|
||||
throw new Exception("Major fallacy");
|
||||
}
|
||||
}
|
||||
35
test/jdk/java/lang/Boolean/GetBoolean.java
Normal file
35
test/jdk/java/lang/Boolean/GetBoolean.java
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4252308
|
||||
* @summary test Boolean.getBoolean method with empty key
|
||||
*/
|
||||
|
||||
public class GetBoolean {
|
||||
public static void main(String[] args) {
|
||||
Boolean.getBoolean("");
|
||||
Boolean.getBoolean(null);
|
||||
}
|
||||
}
|
||||
55
test/jdk/java/lang/Boolean/MakeBooleanComparable.java
Normal file
55
test/jdk/java/lang/Boolean/MakeBooleanComparable.java
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4329937
|
||||
* @summary Basic test for making Boolean implement Comparable
|
||||
* @author Josh Bloch
|
||||
* @key randomness
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class MakeBooleanComparable {
|
||||
public static void main(String[] args) {
|
||||
Random rnd = new Random();
|
||||
List<Boolean> list = new ArrayList<>();
|
||||
int numFalse = 0;
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
boolean element = rnd.nextBoolean();
|
||||
if (!element)
|
||||
numFalse++;
|
||||
list.add(element); // Autoboxing!
|
||||
}
|
||||
|
||||
Collections.sort(list);
|
||||
|
||||
for (int i = 0; i < numFalse; i++)
|
||||
if (list.get(i).booleanValue()) // Autounboxing doesn't work yet!
|
||||
throw new RuntimeException("False positive: " + i);
|
||||
for (int i = numFalse; i < 1000; i++)
|
||||
if (!list.get(i).booleanValue()) // Autounboxing doesn't work yet!
|
||||
throw new RuntimeException("False negative: " + i);
|
||||
}
|
||||
}
|
||||
53
test/jdk/java/lang/Boolean/ParseBoolean.java
Normal file
53
test/jdk/java/lang/Boolean/ParseBoolean.java
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4253773
|
||||
* @summary test Boolean.parseBoolean
|
||||
*/
|
||||
|
||||
public class ParseBoolean {
|
||||
public static void main(String[] args) {
|
||||
checkTrue(Boolean.parseBoolean("TRUE"));
|
||||
checkTrue(Boolean.parseBoolean("true"));
|
||||
checkTrue(Boolean.parseBoolean("TrUe"));
|
||||
|
||||
checkFalse(Boolean.parseBoolean("false"));
|
||||
checkFalse(Boolean.parseBoolean("FALSE"));
|
||||
checkFalse(Boolean.parseBoolean("FaLse"));
|
||||
checkFalse(Boolean.parseBoolean(null));
|
||||
checkFalse(Boolean.parseBoolean("garbage"));
|
||||
checkFalse(Boolean.parseBoolean("TRUEE"));
|
||||
}
|
||||
|
||||
static void checkTrue(boolean b) {
|
||||
if (!b)
|
||||
throw new RuntimeException("test failed");
|
||||
}
|
||||
|
||||
static void checkFalse(boolean b) {
|
||||
if (b)
|
||||
throw new RuntimeException("test failed");
|
||||
}
|
||||
}
|
||||
96
test/jdk/java/lang/Byte/Decode.java
Normal file
96
test/jdk/java/lang/Byte/Decode.java
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4242173 5017980 6576055
|
||||
* @summary Test Byte.decode method
|
||||
*/
|
||||
|
||||
/**
|
||||
* There are six methods in java.lang.Byte which transform strings
|
||||
* into a byte or Byte value:
|
||||
*
|
||||
* public Byte(String s)
|
||||
* public static Byte decode(String nm)
|
||||
* public static byte parseByte(String s, int radix)
|
||||
* public static byte parseByte(String s)
|
||||
* public static Byte valueOf(String s, int radix)
|
||||
* public static Byte valueOf(String s)
|
||||
*
|
||||
* However, of these only decode has a nontrivial implementation
|
||||
* in that class.
|
||||
*/
|
||||
public class Decode {
|
||||
|
||||
private static void check(String val, byte expected) {
|
||||
byte n = (Byte.decode(val)).byteValue();
|
||||
if (n != expected)
|
||||
throw new RuntimeException("Byte.decode failed. String:" +
|
||||
val + " Result:" + n);
|
||||
}
|
||||
|
||||
private static void checkFailure(String val, String message) {
|
||||
try {
|
||||
byte n = (Byte.decode(val)).byteValue();
|
||||
throw new RuntimeException(message);
|
||||
} catch (NumberFormatException e) { /* Okay */}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
check(new String(""+Byte.MIN_VALUE), Byte.MIN_VALUE);
|
||||
check(new String(""+Byte.MAX_VALUE), Byte.MAX_VALUE);
|
||||
|
||||
check("10", (byte)10);
|
||||
check("0x10", (byte)16);
|
||||
check("0X10", (byte)16);
|
||||
check("010", (byte)8);
|
||||
check("#10", (byte)16);
|
||||
|
||||
check("+10", (byte)10);
|
||||
check("+0x10", (byte)16);
|
||||
check("+0X10", (byte)16);
|
||||
check("+010", (byte)8);
|
||||
check("+#10", (byte)16);
|
||||
|
||||
check("-10", (byte)-10);
|
||||
check("-0x10", (byte)-16);
|
||||
check("-0X10", (byte)-16);
|
||||
check("-010", (byte)-8);
|
||||
check("-#10", (byte)-16);
|
||||
|
||||
check(Integer.toString((int)Byte.MIN_VALUE), Byte.MIN_VALUE);
|
||||
check(Integer.toString((int)Byte.MAX_VALUE), Byte.MAX_VALUE);
|
||||
|
||||
checkFailure("0x-10", "Byte.decode allows negative sign in wrong position.");
|
||||
checkFailure("0x+10", "Byte.decode allows positive sign in wrong position.");
|
||||
|
||||
checkFailure("+", "Raw plus sign allowed.");
|
||||
checkFailure("-", "Raw minus sign allowed.");
|
||||
|
||||
checkFailure(Integer.toString((int)Byte.MIN_VALUE - 1), "Out of range");
|
||||
checkFailure(Integer.toString((int)Byte.MAX_VALUE + 1), "Out of range");
|
||||
|
||||
checkFailure("", "Empty String");
|
||||
}
|
||||
}
|
||||
143
test/jdk/java/lang/CharSequence/Comparison.java
Normal file
143
test/jdk/java/lang/CharSequence/Comparison.java
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.nio.CharBuffer;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8137326
|
||||
* @summary Test to verify the compare method for the CharSequence class.
|
||||
* @run testng Comparison
|
||||
*/
|
||||
public class Comparison {
|
||||
static char SEP = ':';
|
||||
|
||||
static String[][] books = {
|
||||
{"Biography", "Steve Jobs"},
|
||||
{"Biography", "Elon Musk: Tesla, SpaceX, and the Quest for a Fantastic Future"},
|
||||
{"Law", "Law 101: Everything You Need to Know About American Law, Fourth Edition"},
|
||||
{"Law", "The Tools of Argument: How the Best Lawyers Think, Argue, and Win"},
|
||||
{"History", "The History Book (Big Ideas Simply Explained)"},
|
||||
{"History", "A People's History of the United States"},
|
||||
};
|
||||
|
||||
/**
|
||||
* Verifies the compare method by comparing StringBuilder objects with String
|
||||
* objects.
|
||||
*/
|
||||
@Test
|
||||
public void compareWithString() {
|
||||
Set<StringBuilder> sbSet = constructSBSet();
|
||||
Set<String> sSet = constructStringSet();
|
||||
Iterator<StringBuilder> iSB = sbSet.iterator();
|
||||
Iterator<String> iS = sSet.iterator();
|
||||
while (iSB.hasNext()) {
|
||||
int result = CharSequence.compare(iSB.next(), iS.next());
|
||||
|
||||
Assert.assertTrue(result == 0, "Comparing item by item");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify comparison between two CharSequence implementations, including String,
|
||||
* StringBuffer and StringBuilder.
|
||||
*
|
||||
* Note: CharBuffer states that "A char buffer is not comparable to any other type of object."
|
||||
*/
|
||||
@Test
|
||||
public void testCompare() {
|
||||
StringBuilder sb1 = generateTestBuilder(65, 70, 97, 102);
|
||||
StringBuilder sb2 = generateTestBuilder(65, 70, 97, 102);
|
||||
StringBuilder sb3 = generateTestBuilder(65, 71, 97, 103);
|
||||
|
||||
Assert.assertTrue(CharSequence.compare(sb1, sb2) == 0, "Compare between StringBuilders");
|
||||
Assert.assertFalse(CharSequence.compare(sb1, sb3) == 0, "Compare between StringBuilders");
|
||||
|
||||
Assert.assertTrue(CharSequence.compare(sb1, sb2.toString()) == 0, "Compare between a StringBuilder and String");
|
||||
Assert.assertFalse(CharSequence.compare(sb1, sb3.toString()) == 0, "Compare between a StringBuilder and String");
|
||||
|
||||
StringBuffer buf1 = generateTestBuffer(65, 70, 97, 102);
|
||||
StringBuffer buf2 = generateTestBuffer(65, 70, 97, 102);
|
||||
StringBuffer buf3 = generateTestBuffer(65, 71, 97, 103);
|
||||
|
||||
Assert.assertTrue(CharSequence.compare(buf1, buf2) == 0, "Compare between StringBuffers");
|
||||
Assert.assertFalse(CharSequence.compare(buf1, buf3) == 0, "Compare between StringBuffers");
|
||||
|
||||
Assert.assertTrue(CharSequence.compare(sb1, buf2) == 0, "Compare between a StringBuilder and StringBuffer");
|
||||
Assert.assertFalse(CharSequence.compare(sb1, buf3) == 0, "Compare between a StringBuilder and StringBuffer");
|
||||
|
||||
CharSequence cs1 = (CharSequence)buf1;
|
||||
CharSequence cs2 = (CharSequence)sb1;
|
||||
@SuppressWarnings("unchecked")
|
||||
int result = ((Comparable<Object>)cs1).compareTo(buf2);
|
||||
Assert.assertTrue(result == 0, "Compare between a StringBuilder and StringBuffer");
|
||||
}
|
||||
|
||||
|
||||
private Set<String> constructStringSet() {
|
||||
Set<String> sSet = new TreeSet<>();
|
||||
for (String[] book : books) {
|
||||
sSet.add(book[0] + SEP + book[1]);
|
||||
}
|
||||
return sSet;
|
||||
}
|
||||
|
||||
private Set<StringBuilder> constructSBSet() {
|
||||
Set<StringBuilder> sbSet = new TreeSet<>();
|
||||
for (String[] book : books) {
|
||||
sbSet.add(new StringBuilder(book[0]).append(SEP).append(book[1]));
|
||||
}
|
||||
return sbSet;
|
||||
}
|
||||
|
||||
private static StringBuilder generateTestBuilder(int from1, int to1,
|
||||
int from2, int to2) {
|
||||
StringBuilder aBuffer = new StringBuilder(50);
|
||||
|
||||
for (int i = from1; i < to1; i++) {
|
||||
aBuffer.append((char)i);
|
||||
}
|
||||
for (int i = from2; i < to2; i++) {
|
||||
aBuffer.append((char)i);
|
||||
}
|
||||
return aBuffer;
|
||||
}
|
||||
|
||||
private static StringBuffer generateTestBuffer(int from1, int to1,
|
||||
int from2, int to2) {
|
||||
StringBuffer aBuffer = new StringBuffer(50);
|
||||
|
||||
for (int i = from1; i < to1; i++) {
|
||||
aBuffer.append((char)i);
|
||||
}
|
||||
for (int i = from2; i < to2; i++) {
|
||||
aBuffer.append((char)i);
|
||||
}
|
||||
return aBuffer;
|
||||
}
|
||||
}
|
||||
104
test/jdk/java/lang/CharSequence/Emptiness.java
Normal file
104
test/jdk/java/lang/CharSequence/Emptiness.java
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.CharBuffer;
|
||||
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8215401
|
||||
* @summary Test to verify the isEmpty method is behaviorally consistent
|
||||
* with length
|
||||
* @run testng Emptiness
|
||||
*/
|
||||
public class Emptiness {
|
||||
|
||||
@Test
|
||||
public void isEmpty() {
|
||||
checkEmpty(new StringBuilder());
|
||||
checkEmpty(new StringBuffer());
|
||||
checkEmpty("");
|
||||
checkEmpty(new CharSequence() {
|
||||
@Override public int length() { return 0; }
|
||||
@Override public char charAt(int index) { return 'f'; }
|
||||
@Override public CharSequence subSequence(int start, int end) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
});
|
||||
checkEmpty(CharBuffer.wrap(new char[0]));
|
||||
checkEmpty(CharBuffer.wrap(""));
|
||||
|
||||
// A CharBuffer being filled is empty when there's no room remaining
|
||||
// - or there's nothing in the buffer after a flip
|
||||
checkEmpty(ByteBuffer.allocate(0).asCharBuffer());
|
||||
checkEmpty(ByteBuffer.allocate(2).asCharBuffer().append('f'));
|
||||
checkEmpty(ByteBuffer.allocate(2).asCharBuffer().flip());
|
||||
|
||||
checkEmpty(ByteBuffer.allocateDirect(0).asCharBuffer());
|
||||
checkEmpty(ByteBuffer.allocateDirect(2).asCharBuffer().append('f'));
|
||||
checkEmpty(ByteBuffer.allocateDirect(2).asCharBuffer().flip());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isNotEmpty() {
|
||||
checkNotEmpty(new StringBuilder().append("foo"));
|
||||
checkNotEmpty(new StringBuffer().append("bar"));
|
||||
checkNotEmpty("baz");
|
||||
checkNotEmpty(new CharSequence() {
|
||||
@Override public int length() { return 1; }
|
||||
@Override public char charAt(int index) { return 'f'; }
|
||||
@Override public CharSequence subSequence(int start, int end) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
});
|
||||
checkNotEmpty(CharBuffer.wrap(new char[] { 'f' }));
|
||||
checkNotEmpty(CharBuffer.wrap("foo"));
|
||||
|
||||
// A CharBuffer being filled is non-empty when there's room remaining
|
||||
// - or when there's something in the buffer after a flip
|
||||
checkNotEmpty(ByteBuffer.allocate(2).asCharBuffer());
|
||||
checkNotEmpty(ByteBuffer.allocate(4).asCharBuffer().append('f'));
|
||||
checkNotEmpty(ByteBuffer.allocate(2).asCharBuffer().append('f').flip());
|
||||
|
||||
checkNotEmpty(ByteBuffer.allocateDirect(2).asCharBuffer());
|
||||
checkNotEmpty(ByteBuffer.allocateDirect(4).asCharBuffer().append('f'));
|
||||
checkNotEmpty(ByteBuffer.allocateDirect(2).asCharBuffer().append('f').flip());
|
||||
}
|
||||
|
||||
public void checkEmpty(CharSequence cs) {
|
||||
Assert.assertTrue(cs.isEmpty());
|
||||
Assert.assertTrue(consistentWithLength(cs));
|
||||
}
|
||||
|
||||
public void checkNotEmpty(CharSequence cs) {
|
||||
Assert.assertTrue(!cs.isEmpty());
|
||||
Assert.assertTrue(consistentWithLength(cs));
|
||||
}
|
||||
|
||||
public boolean consistentWithLength(CharSequence cs) {
|
||||
return cs.isEmpty() == (cs.length() == 0);
|
||||
}
|
||||
}
|
||||
109
test/jdk/java/lang/CharSequence/GetChars.java
Normal file
109
test/jdk/java/lang/CharSequence/GetChars.java
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8343110
|
||||
* @summary Check for expected behavior of default implementation of
|
||||
* CharSequence.getChars().
|
||||
* @run testng GetChars
|
||||
*/
|
||||
public class GetChars {
|
||||
private static CharSequence CS = new CharSequence() {
|
||||
@Override
|
||||
public int length() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char charAt(int index) {
|
||||
return "Test".charAt(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence subSequence(int start, int end) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
|
||||
@Test
|
||||
public void testExactCopy() {
|
||||
var dst = new char[4];
|
||||
CS.getChars(0, 4, dst, 0);
|
||||
Assert.assertEquals(dst, new char[] {'T', 'e', 's', 't'});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPartialCopy() {
|
||||
var dst = new char[2];
|
||||
CS.getChars(1, 3, dst, 0);
|
||||
Assert.assertEquals(dst, new char[] {'e', 's'});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPositionedCopy() {
|
||||
var dst = new char[] {1, 2, 3, 4, 5, 6};
|
||||
CS.getChars(0, 4, dst, 1);
|
||||
Assert.assertEquals(dst, new char[] {1, 'T', 'e', 's', 't', 6});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSrcBeginIsNegative() {
|
||||
Assert.assertThrows(IndexOutOfBoundsException.class,
|
||||
() -> CS.getChars(-1, 3, new char[4], 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDstBeginIsNegative() {
|
||||
Assert.assertThrows(IndexOutOfBoundsException.class,
|
||||
() -> CS.getChars(0, 4, new char[4], -1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSrcBeginIsGreaterThanSrcEnd() {
|
||||
Assert.assertThrows(IndexOutOfBoundsException.class,
|
||||
() -> CS.getChars(4, 0, new char[4], 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSrcEndIsGreaterThanSequenceLength() {
|
||||
Assert.assertThrows(IndexOutOfBoundsException.class,
|
||||
() -> CS.getChars(0, 5, new char[4], 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestedLengthIsGreaterThanDstLength() {
|
||||
Assert.assertThrows(IndexOutOfBoundsException.class,
|
||||
() -> CS.getChars(0, 4, new char[3], 0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDstIsNull() {
|
||||
Assert.assertThrows(NullPointerException.class,
|
||||
() -> CS.getChars(0, 4, null, 0));
|
||||
}
|
||||
|
||||
}
|
||||
73
test/jdk/java/lang/Character/Bug4404588.java
Normal file
73
test/jdk/java/lang/Character/Bug4404588.java
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary The characters FFFE and FFFF should not be in a UnicodeBlock. They
|
||||
* should be in a null block.
|
||||
* @bug 4404588
|
||||
* @author John O'Conner
|
||||
*/
|
||||
|
||||
public class Bug4404588 {
|
||||
|
||||
public Bug4404588() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Bug4404588 test = new Bug4404588();
|
||||
test.run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the correct data against what Character reports.
|
||||
*/
|
||||
void run() {
|
||||
Character ch;
|
||||
Character.UnicodeBlock block;
|
||||
|
||||
for(int x=0; x < charData.length; x++) {
|
||||
ch = (Character)charData[x][0];
|
||||
block = (Character.UnicodeBlock)charData[x][1];
|
||||
|
||||
if (Character.UnicodeBlock.of(ch.charValue()) != block) {
|
||||
System.err.println("Error: block = " + block);
|
||||
System.err.println("Character.UnicodeBlock.of(" +
|
||||
Integer.toHexString(ch.charValue()) +") = " +
|
||||
Character.UnicodeBlock.of(ch.charValue()));
|
||||
throw new RuntimeException("Blocks aren't equal.");
|
||||
}
|
||||
}
|
||||
System.out.println("Passed.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains the character data to test. The first object is the character.
|
||||
* The next object is the UnicodeBlock to which it should belong.
|
||||
*/
|
||||
Object[][] charData = {
|
||||
{ new Character('\uFFFE'), Character.UnicodeBlock.SPECIALS },
|
||||
{ new Character('\uFFFF'), Character.UnicodeBlock.SPECIALS },
|
||||
};
|
||||
}
|
||||
558
test/jdk/java/lang/Character/CharCheck.java
Normal file
558
test/jdk/java/lang/Character/CharCheck.java
Normal file
|
|
@ -0,0 +1,558 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alan Liu
|
||||
* @author John O'Conner
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
|
||||
|
||||
/**
|
||||
* This class either loads or dumps the character properties of all Unicode
|
||||
* characters out to a file. When loading, it compares the loaded data with
|
||||
* that obtained through the java.lang.Character API. This allows detection of
|
||||
* changes to the character properties between versions of the Java VM. A
|
||||
* typical usage would be to dump the properties under an early VM, and load
|
||||
* them under a later VM.
|
||||
*
|
||||
* Also: Check the current VM's character properties against those in a
|
||||
* Unicode database. The database should be of the format
|
||||
* available on ftp.unicode.org/Public/UNIDATA.
|
||||
*
|
||||
*/
|
||||
public class CharCheck {
|
||||
static int differences = 0;
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
|
||||
if (args.length != 2 && args.length != 3) usage();
|
||||
if (args[0].equals("dump"))
|
||||
dump(Integer.parseInt(args[1], 16), new ObjectOutputStream(new FileOutputStream(args[2])));
|
||||
else if (args[0].equals("load"))
|
||||
load(Integer.parseInt(args[1], 16), new ObjectInputStream(new FileInputStream(args[2])));
|
||||
else if (args[0].equals("check"))
|
||||
check(Integer.parseInt(args[1], 16), new File(args[2]));
|
||||
else if (args[0].equals("char"))
|
||||
showChar(Integer.parseInt(args[1],16));
|
||||
else if (args[0].equals("fchar"))
|
||||
showFileChar(args[1], Integer.parseInt(args[2],16));
|
||||
else usage();
|
||||
if (differences != 0) {
|
||||
throw new RuntimeException("There are differences between Character properties and the specification.");
|
||||
}
|
||||
}
|
||||
|
||||
static void usage() {
|
||||
System.err.println("Usage: java CharCheck <command>");
|
||||
System.err.println("where <command> is one of the following:");
|
||||
System.err.println("dump <plane> <file> - dumps the character properties of the given plane,");
|
||||
System.err.println(" read from the current VM, to the given file.");
|
||||
System.err.println("load <plane> <file> - loads the character properties from the given");
|
||||
System.err.println(" file and compares them to those of the given character plane");
|
||||
System.err.println(" in the current VM.");
|
||||
System.err.println("check <plane> <file> - compare the current VM's character properties");
|
||||
System.err.println(" in the given plane to those listed in the given file, ");
|
||||
System.err.println(" which should be in the format available on ");
|
||||
System.err.println(" ftp.unicode.org/Public/2.0-Update.");
|
||||
System.err.println("char <code> - show current VM properties of the given Unicode char.");
|
||||
System.err.println("fchar <file> <code> - show file properties of the given Unicode char.");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
static String getTypeName(int type) {
|
||||
return (type >= 0 && type < UnicodeSpec.generalCategoryList.length) ?
|
||||
(UnicodeSpec.generalCategoryList[type][UnicodeSpec.LONG] + '(' + type + ')') :
|
||||
("<Illegal type value " + type + ">");
|
||||
}
|
||||
|
||||
static int check(int plane, File specFile) throws Exception {
|
||||
|
||||
String version = System.getProperty("java.version");
|
||||
System.out.println("Current VM version " + version);
|
||||
int rangeLimit = (plane << 16) | 0xFFFF;
|
||||
String record;
|
||||
UnicodeSpec[] spec = UnicodeSpec.readSpecFile(specFile, plane);
|
||||
int rangeStart = 0x0000;
|
||||
boolean isRange = false;
|
||||
|
||||
lastCheck = (plane << 16) - 1;
|
||||
|
||||
for (int currentSpec = 0; currentSpec < spec.length; currentSpec++) {
|
||||
int c = spec[currentSpec].getCodePoint();
|
||||
if (isRange) {
|
||||
// Must see end of range now
|
||||
if (spec[currentSpec].getName().endsWith("Last>")) {
|
||||
for (int d=rangeStart; d<=c; d++) {
|
||||
checkOneChar(d, spec[currentSpec]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// No good -- First without Last
|
||||
System.out.println("BAD FILE: First without last at '" + escape(rangeStart) + "'");
|
||||
}
|
||||
isRange = false;
|
||||
}
|
||||
else {
|
||||
// Look for a First, Last pair: This is a pair of entries like the following:
|
||||
// 4E00;<CJK Ideograph, First>;Lo;0;L;;;;;N;;;;;
|
||||
// 9FA5;<CJK Ideograph, Last>;Lo;0;L;;;;;N;;;;;
|
||||
if (spec[currentSpec].getName().endsWith("First>")) {
|
||||
rangeStart = c;
|
||||
isRange = true;
|
||||
}
|
||||
else {
|
||||
checkOneChar(c, spec[currentSpec]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check undefined chars at the end of the range
|
||||
|
||||
while (lastCheck < rangeLimit) checkOneCharDefined(++lastCheck, "?", false);
|
||||
|
||||
System.out.println("Total differences: "+differences);
|
||||
return differences;
|
||||
}
|
||||
|
||||
static int lastCheck = -1;
|
||||
|
||||
static final void checkOneCharDefined(int c, String name, boolean fileDefined) {
|
||||
if (Character.isDefined(c) != fileDefined)
|
||||
showDifference(c, name, "isDefined", ""+(!fileDefined), ""+fileDefined);
|
||||
}
|
||||
|
||||
// In GenerateCharacter, the following ranges are handled specially.
|
||||
// Each is the start of a 26-character range with values 10..35.
|
||||
static final char NUMERIC_EXCEPTION[] = { '\u0041', '\u0061', '\uFF21', '\uFF41' };
|
||||
|
||||
static void checkOneChar(int c, UnicodeSpec charSpec) {
|
||||
// Handle intervening ranges -- we assume that we will be called in monotonically
|
||||
// increasing order. If the last char we checked is more than one before this
|
||||
// char, then check the intervening range -- it should all be undefined.
|
||||
int lowerLimit = (c & 0xFF0000);
|
||||
if (lastCheck >= lowerLimit && (lastCheck+1) != c) {
|
||||
for (int i=lastCheck+1; i<c; ++i)
|
||||
checkOneCharDefined(i, "?", false);
|
||||
}
|
||||
|
||||
lastCheck = c;
|
||||
|
||||
// isDefined should be true
|
||||
checkOneCharDefined(c, charSpec.getName(), true);
|
||||
|
||||
// Check lower, upper, and titlecase conversion
|
||||
int upper = Character.toUpperCase(c);
|
||||
int lower = Character.toLowerCase(c);
|
||||
int title = Character.toTitleCase(c);
|
||||
int upperDB = charSpec.hasUpperMap() ? charSpec.getUpperMap() : c;
|
||||
int lowerDB = charSpec.hasLowerMap() ? charSpec.getLowerMap() : c;
|
||||
int titleDB = charSpec.hasTitleMap() ? charSpec.getTitleMap() : c;
|
||||
if (upper != upperDB) showDifference(c, charSpec.getName(), "upper", hex6(upper), hex6(upperDB));
|
||||
if (lower != lowerDB) showDifference(c, charSpec.getName(), "lower", hex6(lower), hex6(lowerDB));
|
||||
if (title != titleDB) showDifference(c, charSpec.getName(), "title", hex6(title), hex6(titleDB));
|
||||
|
||||
// Check the character general category (type)
|
||||
int type = Character.getType(c);
|
||||
int typeDB = charSpec.getGeneralCategory();
|
||||
if (type != typeDB) {
|
||||
showDifference(c, charSpec.getName(), "type",
|
||||
UnicodeSpec.generalCategoryList[type][UnicodeSpec.SHORT],
|
||||
UnicodeSpec.generalCategoryList[typeDB][UnicodeSpec.SHORT]);
|
||||
}
|
||||
|
||||
// Check the mirrored property
|
||||
boolean isMirrored = Character.isMirrored(c);
|
||||
boolean isMirroredDB = charSpec.isMirrored();
|
||||
if (isMirrored != isMirroredDB) {
|
||||
showDifference(c, charSpec.getName(), "isMirrored", ""+isMirrored, ""+isMirroredDB);
|
||||
}
|
||||
|
||||
// Check the directionality property
|
||||
byte directionality = Character.getDirectionality(c);
|
||||
byte directionalityDB = charSpec.getBidiCategory();
|
||||
if (directionality != directionalityDB) {
|
||||
showDifference(c, charSpec.getName(), "directionality", ""+directionality, ""+directionalityDB);
|
||||
}
|
||||
|
||||
// Check the decimal digit property
|
||||
int decimalDigit = Character.digit(c, 10);
|
||||
int decimalDigitDB = -1;
|
||||
if (charSpec.getGeneralCategory() == UnicodeSpec.DECIMAL_DIGIT_NUMBER) {
|
||||
decimalDigitDB = charSpec.getDecimalValue();
|
||||
}
|
||||
if (decimalDigit != decimalDigitDB)
|
||||
showDifference(c, charSpec.getName(), "decimal digit", ""+decimalDigit, ""+decimalDigitDB);
|
||||
|
||||
// Check the numeric property
|
||||
int numericValue = Character.getNumericValue(c);
|
||||
int numericValueDB;
|
||||
if (charSpec.getNumericValue().length() == 0) {
|
||||
numericValueDB = -1;
|
||||
// Handle exceptions where Character deviates from the UCS spec
|
||||
for (int k=0; k<NUMERIC_EXCEPTION.length; ++k) {
|
||||
if (c >= NUMERIC_EXCEPTION[k] && c < (char)(NUMERIC_EXCEPTION[k]+26)) {
|
||||
numericValueDB = c - NUMERIC_EXCEPTION[k] + 10;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
String strValue = charSpec.getNumericValue();
|
||||
int parsedNumericValue;
|
||||
if (strValue.equals("10000000000")
|
||||
|| strValue.equals("1000000000000")) {
|
||||
System.out.println("Skipping strValue: " + strValue
|
||||
+ " for " + charSpec.getName()
|
||||
+ "(0x" + Integer.toHexString(c) + ")");
|
||||
parsedNumericValue = -2;
|
||||
} else {
|
||||
parsedNumericValue = strValue.indexOf('/') < 0 ?
|
||||
Integer.parseInt(strValue) : -2;
|
||||
}
|
||||
numericValueDB = parsedNumericValue < 0 ? -2 : parsedNumericValue;
|
||||
}
|
||||
if (numericValue != numericValueDB)
|
||||
showDifference(c, charSpec.getName(), "numeric value", ""+numericValue, ""+numericValueDB);
|
||||
}
|
||||
|
||||
static void showDifference(int c, String name, String property, String vmValue, String dbValue) {
|
||||
System.out.println(escape("Mismatch at '" + hex6(c) + "' (" + name+ "): " +
|
||||
property + "=" + vmValue + ", db=" + dbValue));
|
||||
++differences;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a record containing ';'-separated fields, return the fieldno-th
|
||||
* field. The first field is field 0.
|
||||
*/
|
||||
static String getField(String record, int fieldno) {
|
||||
int i=0;
|
||||
int j=record.indexOf(';');
|
||||
while (fieldno > 0) {
|
||||
i=j+1;
|
||||
j=record.indexOf(';', i);
|
||||
}
|
||||
return record.substring(i, j);
|
||||
}
|
||||
|
||||
static final int FIELD_COUNT = 15;
|
||||
|
||||
/**
|
||||
* Given a record containing ';'-separated fields, return an array of
|
||||
* the fields. It is assumed that there are FIELD_COUNT fields per record.
|
||||
*/
|
||||
static void getFields(String record, String[] fields) {
|
||||
int i=0;
|
||||
int j=record.indexOf(';');
|
||||
fields[0] = record.substring(i, j);
|
||||
for (int n=1; n<FIELD_COUNT; ++n) {
|
||||
i=j+1;
|
||||
j=record.indexOf(';', i);
|
||||
fields[n] = (j<0) ? record.substring(i) : record.substring(i, j);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a record containing ';'-separated fields, return an array of
|
||||
* the fields. It is assumed that there are FIELD_COUNT fields per record.
|
||||
*/
|
||||
static String[] getFields(String record) {
|
||||
String[] fields = new String[FIELD_COUNT];
|
||||
getFields(record, fields);
|
||||
return fields;
|
||||
}
|
||||
|
||||
static void dump(int plane, ObjectOutputStream out) throws Exception {
|
||||
String version = System.getProperty("java.version");
|
||||
System.out.println("Writing file version " + version);
|
||||
out.writeObject(version);
|
||||
|
||||
long[] data = new long[0x20000];
|
||||
long[] onechar = new long[2];
|
||||
int j=0;
|
||||
int begin = plane<<16;
|
||||
int end = begin + 0xFFFF;
|
||||
for (int i = begin; i <= end; ++i) {
|
||||
getPackedCharacterData(i, onechar);
|
||||
data[j++] = onechar[0];
|
||||
data[j++] = onechar[1];
|
||||
}
|
||||
out.writeObject(data);
|
||||
}
|
||||
|
||||
static long[] loadData(ObjectInputStream in) throws Exception {
|
||||
String version = System.getProperty("java.version");
|
||||
String inVersion = (String)in.readObject();
|
||||
System.out.println("Reading file version " + inVersion);
|
||||
System.out.println("Current version " + version);
|
||||
|
||||
long[] data = (long[])in.readObject();
|
||||
if (data.length != 0x20000) {
|
||||
System.out.println("BAD ARRAY LENGTH: " + data.length);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
static int load(int plane, ObjectInputStream in) throws Exception {
|
||||
long[] data = CharCheck.loadData(in);
|
||||
CharCheck.checkData(data, plane);
|
||||
return differences;
|
||||
}
|
||||
|
||||
|
||||
static int checkData(long[] data, int plane) {
|
||||
long[] onechar = new long[2];
|
||||
|
||||
for (int i=0; i<0x10000; ++i) {
|
||||
int c = (plane << 16) | i;
|
||||
getPackedCharacterData(c, onechar);
|
||||
if (data[2*i] != onechar[0] || data[2*i+1] != onechar[1]) {
|
||||
long[] filechar = { data[2*i], data[2*i+1] };
|
||||
showDifference(c, onechar, filechar);
|
||||
}
|
||||
}
|
||||
System.out.println("Total differences: " + differences);
|
||||
return differences;
|
||||
}
|
||||
|
||||
static String hex6(long n) {
|
||||
String q = Long.toHexString(n).toUpperCase();
|
||||
return "000000".substring(Math.min(6, q.length())) + q;
|
||||
}
|
||||
|
||||
static void showChar(int c) {
|
||||
long[] chardata = new long[2];
|
||||
getPackedCharacterData(c, chardata);
|
||||
System.out.println("Current VM properties for '" + hex6(c) + "': " +
|
||||
hex6(chardata[1]) + ' ' + hex6(chardata[0]));
|
||||
String[] data = unpackCharacterData(chardata);
|
||||
for (int i=0; i<data.length; ++i)
|
||||
System.out.println(" " + escape(data[i]));
|
||||
}
|
||||
|
||||
static void showFileChar(String fileName, int c) throws Exception {
|
||||
ObjectInputStream in = new ObjectInputStream(new FileInputStream(fileName));
|
||||
String inVersion = (String)in.readObject();
|
||||
System.out.println("Reading file version " + inVersion);
|
||||
|
||||
long[] data = (long[])in.readObject();
|
||||
if (data.length != 0x20000) {
|
||||
System.out.println("BAD ARRAY LENGTH: " + data.length);
|
||||
}
|
||||
int offset = c & 0xFFFF;
|
||||
long[] chardata = { data[2*offset], data[2*offset+1] };
|
||||
String[] datap = unpackCharacterData(chardata);
|
||||
System.out.println(escape("File properties for '" + hex6(c)+ "':"));
|
||||
for (int i=0; i<datap.length; ++i)
|
||||
System.out.println(" " + escape(datap[i]));
|
||||
}
|
||||
|
||||
/**
|
||||
* The packed character data encapsulates all the information obtainable
|
||||
* about a character in a single numeric value.
|
||||
*
|
||||
* data[0]:
|
||||
*
|
||||
* 5 bits for getType()
|
||||
* 6 bits for digit() -- add one
|
||||
* 6 bits for getNumericValue() -- add two
|
||||
* 15 bits for isXxx()
|
||||
*
|
||||
* 21 bits for toUpperCase()
|
||||
*
|
||||
*
|
||||
* data[1]:
|
||||
* 21 bits for toLowerCase()
|
||||
* 21 bits for toTitleCase()
|
||||
*/
|
||||
static void getPackedCharacterData(int c, long[] data) {
|
||||
data[0] =
|
||||
(long)Character.getType(c) |
|
||||
((long)(Character.digit(c, Character.MAX_RADIX) + 1) << 5) |
|
||||
((long)(Character.getNumericValue(c) + 2) << 11) |
|
||||
(Character.isDefined(c) ? (1L<<17) : 0L) |
|
||||
(Character.isDigit(c) ? (1L<<18) : 0L) |
|
||||
(Character.isIdentifierIgnorable(c) ? (1L<<19) : 0L) |
|
||||
(Character.isISOControl(c) ? (1L<<20) : 0L) |
|
||||
(Character.isJavaIdentifierPart(c) ? (1L<<21) : 0L) |
|
||||
(Character.isJavaIdentifierStart(c) ? (1L<<22) : 0L) |
|
||||
(Character.isLetter(c) ? (1L<<23) : 0L) |
|
||||
(Character.isLetterOrDigit(c) ? (1L<<24) : 0L) |
|
||||
(Character.isLowerCase(c) ? (1L<<25) : 0L) |
|
||||
(Character.isSpaceChar(c) ? (1L<<26) : 0L) |
|
||||
(Character.isTitleCase(c) ? (1L<<27) : 0L) |
|
||||
(Character.isUnicodeIdentifierPart(c) ? (1L<<28) : 0L) |
|
||||
(Character.isUnicodeIdentifierStart(c) ? (1L<<29) : 0L) |
|
||||
(Character.isUpperCase(c) ? (1L<<30) : 0L) |
|
||||
(Character.isWhitespace(c) ? (1L<<31) : 0L) |
|
||||
((long)Character.toUpperCase(c) << 32);
|
||||
data[1] = (long)Character.toLowerCase(c) |
|
||||
((long)Character.toTitleCase(c) << 21);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a long, set the bits at the given offset and length to the given value.
|
||||
*/
|
||||
static long setBits(long data, int offset, int length, long value) {
|
||||
long himask = -1L << (offset+length);
|
||||
long lomask = ~(-1L << offset);
|
||||
long lengthmask = ~(-1L << length);
|
||||
return (data & (himask | lomask)) | ((value & lengthmask) << offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given packed character data, change the attribute
|
||||
* toLower
|
||||
*/
|
||||
static void setToLower(long[] data, int value) {
|
||||
data[0] = setBits(data[0], 48, 16, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given packed character data, change the attribute
|
||||
* toUpper
|
||||
*/
|
||||
static void setToUpper(long[] data, int value) {
|
||||
data[0] = setBits(data[0], 32, 16, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given packed character data, change the attribute
|
||||
* toTitle
|
||||
*/
|
||||
static void setToTitle(long[] data, int value) {
|
||||
data[1] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given packed character data, change the attribute
|
||||
* getType
|
||||
*/
|
||||
static void setGetType(long[] data, int value) {
|
||||
data[0] = setBits(data[0], 0, 5, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given packed character data, change the attribute
|
||||
* isDefined
|
||||
*/
|
||||
static void setIsDefined(long[] data, boolean value) {
|
||||
data[0] = setBits(data[0], 17, 1, value?1:0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given packed character data, change the attribute
|
||||
* isJavaIdentifierPart
|
||||
*/
|
||||
static void setIsJavaIdentifierPart(long[] data, boolean value) {
|
||||
data[0] = setBits(data[0], 21, 1, value?1:0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given packed character data, change the attribute
|
||||
* isJavaIdentifierStart
|
||||
*/
|
||||
static void setIsJavaIdentifierStart(long[] data, boolean value) {
|
||||
data[0] = setBits(data[0], 22, 1, value?1:0);
|
||||
}
|
||||
|
||||
static String[] unpackCharacterData(long[] dataL) {
|
||||
long data = dataL[0];
|
||||
String[] result = {
|
||||
"type=" + getTypeName((int)(data&0x1F)),
|
||||
"digit=" + (((data>>5)&0x3F)-1),
|
||||
"numeric=" + (((data>>11)&0x3F)-2),
|
||||
"isDefined=" + (((data>>17)&1)==1),
|
||||
"isDigit=" + (((data>>18)&1)==1),
|
||||
"isIdentifierIgnorable=" + (((data>>19)&1)==1),
|
||||
"isISOControl=" + (((data>>20)&1)==1),
|
||||
"isJavaIdentifierPart=" + (((data>>21)&1)==1),
|
||||
"isJavaIdentifierStart=" + (((data>>22)&1)==1),
|
||||
"isLetter=" + (((data>>23)&1)==1),
|
||||
"isLetterOrDigit=" + (((data>>24)&1)==1),
|
||||
"isLowerCase=" + (((data>>25)&1)==1),
|
||||
"isSpaceChar=" + (((data>>26)&1)==1),
|
||||
"isTitleCase=" + (((data>>27)&1)==1),
|
||||
"isUnicodeIdentifierPart=" + (((data>>28)&1)==1),
|
||||
"isUnicodeIdentifierStart=" + (((data>>29)&1)==1),
|
||||
"isUpperCase=" + (((data>>30)&1)==1),
|
||||
"isWhitespace=" + (((data>>31)&1)==1),
|
||||
"toUpper=" + hex6(((int)(data>>32) & 0X1FFFFF)),
|
||||
"toLower=" + hex6((int)(dataL[1] & 0x1FFFFF)),
|
||||
"toTitle=" + hex6(((int)(dataL[1] >> 21) & 0x1FFFFF))
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
static String[] getCharacterData(int c) {
|
||||
long[] data = new long[2];
|
||||
getPackedCharacterData(c, data);
|
||||
return unpackCharacterData(data);
|
||||
}
|
||||
|
||||
static void showDifference(int c, long[] currentData, long[] fileData) {
|
||||
System.out.println("Difference at " + hex6(c));
|
||||
String[] current = unpackCharacterData(currentData);
|
||||
String[] file = unpackCharacterData(fileData);
|
||||
for (int i=0; i<current.length; ++i) {
|
||||
if (!current[i].equals(file[i])) {
|
||||
System.out.println(escape(" current " + current[i] +
|
||||
", file " + file[i]));
|
||||
}
|
||||
}
|
||||
++differences;
|
||||
}
|
||||
|
||||
static String escape(String s) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
for (int i=0; i<s.length(); ++i) {
|
||||
char c = s.charAt(i);
|
||||
if (c >= 0x20 && c <= 0x7F) buf.append(c);
|
||||
else {
|
||||
buf.append("\\u");
|
||||
String h = "000" + Integer.toHexString(c);
|
||||
if (h.length() > 4) h = h.substring(h.length() - 4);
|
||||
buf.append(h);
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
static String escape(int c) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
if (c >= 0x20 && c <= 0x7F) buf.append(c);
|
||||
else {
|
||||
buf.append("\\u");
|
||||
String h = "000" + Integer.toHexString(c);
|
||||
if (h.length() > 4) h = h.substring(h.length() - 4);
|
||||
buf.append(h);
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//eof
|
||||
308
test/jdk/java/lang/Character/CharPropTest.java
Normal file
308
test/jdk/java/lang/Character/CharPropTest.java
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8202771 8221431 8229831 8296246
|
||||
* @summary Check j.l.Character.isDigit/isLetter/isLetterOrDigit/isSpaceChar
|
||||
* /isWhitespace/isTitleCase/isISOControl/isIdentifierIgnorable
|
||||
* /isJavaIdentifierStart/isJavaIdentifierPart/isUnicodeIdentifierStart
|
||||
* /isUnicodeIdentifierPart
|
||||
* @library /lib/testlibrary/java/lang
|
||||
* @run main CharPropTest
|
||||
*/
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class CharPropTest {
|
||||
private static int diffs = 0;
|
||||
private static int rangeStart = 0x0000;
|
||||
private static boolean isRange = false;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
try (Stream<String> lines = Files.lines(UCDFiles.UNICODE_DATA)) {
|
||||
lines.map(String::trim)
|
||||
.filter(line -> line.length() != 0 && line.charAt(0) != '#')
|
||||
.forEach(line -> handleOneLine(line));
|
||||
|
||||
if (diffs != 0) {
|
||||
throw new RuntimeException("Total differences: " + diffs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void handleOneLine(String line) {
|
||||
String[] fields = line.split(";");
|
||||
int currentCp = Integer.parseInt(fields[0], 16);
|
||||
String name = fields[1];
|
||||
String category = fields[2];
|
||||
|
||||
// Except single code point, also handle ranges like the following:
|
||||
// 3400;<CJK Ideograph Extension A, First>;Lo;0;L;;;;;N;;;;;
|
||||
// 4DB5;<CJK Ideograph Extension A, Last>;Lo;0;L;;;;;N;;;;
|
||||
if (isRange) {
|
||||
if (name.endsWith("Last>")) {
|
||||
for (int cp = rangeStart; cp <= currentCp; cp++) {
|
||||
testCodePoint(cp, category);
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Not a valid range, first range <"
|
||||
+ Integer.toHexString(rangeStart) + "> without last.");
|
||||
}
|
||||
isRange = false;
|
||||
} else {
|
||||
if (name.endsWith("First>")) {
|
||||
rangeStart = currentCp;
|
||||
isRange = true;
|
||||
} else {
|
||||
testCodePoint(currentCp, category);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void testCodePoint(int codePoint, String category) {
|
||||
isDigitTest(codePoint, category);
|
||||
isLetterTest(codePoint, category);
|
||||
isLetterOrDigitTest(codePoint, category);
|
||||
|
||||
isSpaceCharTest(codePoint, category);
|
||||
isWhitespaceTest(codePoint, category);
|
||||
|
||||
isTitleCaseTest(codePoint, category);
|
||||
|
||||
isISOControlTest(codePoint);
|
||||
|
||||
isIdentifierIgnorableTest(codePoint, category);
|
||||
isJavaIdentifierStartTest(codePoint, category);
|
||||
isJavaIdentifierPartTest(codePoint, category);
|
||||
isUnicodeIdentifierStartTest(codePoint, category);
|
||||
isUnicodeIdentifierPartTest(codePoint, category);
|
||||
}
|
||||
|
||||
private static void isDigitTest(int codePoint, String category) {
|
||||
boolean actual = Character.isDigit(codePoint);
|
||||
boolean expected = category.equals("Nd");
|
||||
if (actual != expected) {
|
||||
printDiff(codePoint, "isDigit", actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
private static void isLetterTest(int codePoint, String category) {
|
||||
boolean actual = Character.isLetter(codePoint);
|
||||
boolean expected = isLetter(category);
|
||||
if (actual != expected) {
|
||||
printDiff(codePoint, "isLetter", actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
private static void isLetterOrDigitTest(int codePoint, String category) {
|
||||
boolean actual = Character.isLetterOrDigit(codePoint);
|
||||
boolean expected = isLetter(category) || category.equals("Nd");
|
||||
if (actual != expected) {
|
||||
printDiff(codePoint, "isLetterOrDigit", actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
private static void isSpaceCharTest(int codePoint, String category) {
|
||||
boolean actual = Character.isSpaceChar(codePoint);
|
||||
boolean expected = isSpaceChar(category);
|
||||
if (actual != expected) {
|
||||
printDiff(codePoint, "isSpaceChar", actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
private static void isWhitespaceTest(int codePoint, String category) {
|
||||
boolean actual = Character.isWhitespace(codePoint);
|
||||
boolean expected = isWhitespace(codePoint, category);
|
||||
if (actual != expected) {
|
||||
printDiff(codePoint, "isWhitespace", actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
private static void isTitleCaseTest(int codePoint, String category) {
|
||||
boolean actual = Character.isTitleCase(codePoint);
|
||||
boolean expected = category.equals("Lt");
|
||||
if (actual != expected) {
|
||||
printDiff(codePoint, "isTitleCase", actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
private static void isISOControlTest(int codePoint) {
|
||||
boolean actual = Character.isISOControl(codePoint);
|
||||
boolean expected = isISOControl(codePoint);
|
||||
if (actual != expected) {
|
||||
printDiff(codePoint, "isISOControl", actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
private static void isIdentifierIgnorableTest(int codePoint, String category) {
|
||||
boolean actual = Character.isIdentifierIgnorable(codePoint);
|
||||
boolean expected = isIdentifierIgnorable(codePoint, category);
|
||||
if (actual != expected) {
|
||||
printDiff(codePoint, "isIdentifierIgnorable", actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
private static void isJavaIdentifierStartTest(int codePoint, String category) {
|
||||
boolean actual = Character.isJavaIdentifierStart(codePoint);
|
||||
boolean expected = isJavaIdentifierStart(category);
|
||||
if (actual != expected) {
|
||||
printDiff(codePoint, "isJavaIdentifierStart", actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
private static void isJavaIdentifierPartTest(int codePoint, String category) {
|
||||
boolean actual = Character.isJavaIdentifierPart(codePoint);
|
||||
boolean expected = isJavaIdentifierPart(codePoint, category);
|
||||
if (actual != expected) {
|
||||
printDiff(codePoint, "isJavaIdentifierPart", actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
private static void isUnicodeIdentifierStartTest(int codePoint, String category) {
|
||||
boolean actual = Character.isUnicodeIdentifierStart(codePoint);
|
||||
boolean expected = isUnicodeIdentifierStart(codePoint, category);
|
||||
if (actual != expected) {
|
||||
printDiff(codePoint, "isUnicodeIdentifierStart", actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
private static void isUnicodeIdentifierPartTest(int codePoint, String category) {
|
||||
boolean actual = Character.isUnicodeIdentifierPart(codePoint);
|
||||
boolean expected = isUnicodeIdentifierPart(codePoint, category);
|
||||
if (actual != expected) {
|
||||
printDiff(codePoint, "isUnicodeIdentifierPart", actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isLetter(String category) {
|
||||
return category.equals("Lu") || category.equals("Ll")
|
||||
|| category.equals("Lt") || category.equals("Lm")
|
||||
|| category.equals("Lo");
|
||||
}
|
||||
|
||||
private static boolean isSpaceChar(String category) {
|
||||
return category.equals("Zs") || category.equals("Zl")
|
||||
|| category.equals("Zp");
|
||||
}
|
||||
|
||||
private static boolean isWhitespace(int codePoint, String category) {
|
||||
if (isSpaceChar(category) && codePoint != Integer.parseInt("00A0", 16)
|
||||
&& codePoint != Integer.parseInt("2007", 16)
|
||||
&& codePoint != Integer.parseInt("202F", 16)) {
|
||||
return true;
|
||||
} else {
|
||||
if (codePoint == Integer.parseInt("0009", 16)
|
||||
|| codePoint == Integer.parseInt("000A", 16)
|
||||
|| codePoint == Integer.parseInt("000B", 16)
|
||||
|| codePoint == Integer.parseInt("000C", 16)
|
||||
|| codePoint == Integer.parseInt("000D", 16)
|
||||
|| codePoint == Integer.parseInt("001C", 16)
|
||||
|| codePoint == Integer.parseInt("001D", 16)
|
||||
|| codePoint == Integer.parseInt("001E", 16)
|
||||
|| codePoint == Integer.parseInt("001F", 16)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isISOControl(int codePoint) {
|
||||
return (codePoint > 0x00 && codePoint < 0x1f)
|
||||
|| (codePoint > 0x7f && codePoint < 0x9f)
|
||||
|| (codePoint == 0x00 || codePoint == 0x1f || codePoint == 0x7f || codePoint == 0x9f);
|
||||
}
|
||||
|
||||
private static boolean isIdentifierIgnorable(int codePoint, String category) {
|
||||
if (category.equals("Cf")) {
|
||||
return true;
|
||||
} else {
|
||||
int a1 = Integer.parseInt("0000", 16);
|
||||
int a2 = Integer.parseInt("0008", 16);
|
||||
int b1 = Integer.parseInt("000E", 16);
|
||||
int b2 = Integer.parseInt("001B", 16);
|
||||
int c1 = Integer.parseInt("007F", 16);
|
||||
int c2 = Integer.parseInt("009F", 16);
|
||||
|
||||
if ((codePoint > a1 && codePoint < a2) || (codePoint > b1 && codePoint < b2)
|
||||
|| (codePoint > c1 && codePoint < c2) || (codePoint == a1 || codePoint == a2
|
||||
|| codePoint == b1 || codePoint == b2 || codePoint == c1 || codePoint == c2)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isJavaIdentifierStart(String category) {
|
||||
return isLetter(category) || category.equals("Nl") || category.equals("Sc")
|
||||
|| category.equals("Pc");
|
||||
}
|
||||
|
||||
private static boolean isJavaIdentifierPart(int codePoint, String category) {
|
||||
return isLetter(category) || category.equals("Sc") || category.equals("Pc")
|
||||
|| category.equals("Nd") || category.equals("Nl")
|
||||
|| category.equals("Mc") || category.equals("Mn")
|
||||
|| isIdentifierIgnorable(codePoint, category);
|
||||
}
|
||||
|
||||
private static boolean isUnicodeIdentifierStart(int codePoint, String category) {
|
||||
return isLetter(category) || category.equals("Nl")
|
||||
|| isOtherIDStart(codePoint);
|
||||
}
|
||||
|
||||
private static boolean isUnicodeIdentifierPart(int codePoint, String category) {
|
||||
return isLetter(category) || category.equals("Pc") || category.equals("Nd")
|
||||
|| category.equals("Nl") || category.equals("Mc") || category.equals("Mn")
|
||||
|| isIdentifierIgnorable(codePoint, category)
|
||||
|| isOtherIDStart(codePoint)
|
||||
|| isOtherIDContinue(codePoint);
|
||||
}
|
||||
|
||||
private static boolean isOtherIDStart(int codePoint) {
|
||||
return codePoint == 0x1885 ||
|
||||
codePoint == 0x1886 ||
|
||||
codePoint == 0x2118 ||
|
||||
codePoint == 0x212E ||
|
||||
codePoint == 0x309B ||
|
||||
codePoint == 0x309C;
|
||||
}
|
||||
|
||||
private static boolean isOtherIDContinue(int codePoint) {
|
||||
return codePoint == 0x00B7 ||
|
||||
codePoint == 0x0387 ||
|
||||
(codePoint >= 0x1369 && codePoint <= 0x1371) ||
|
||||
codePoint == 0x19DA ||
|
||||
codePoint == 0x200C ||
|
||||
codePoint == 0x200D ||
|
||||
codePoint == 0x30FB ||
|
||||
codePoint == 0xFF65;
|
||||
}
|
||||
|
||||
private static void printDiff(int codePoint, String method, boolean actual, boolean expected) {
|
||||
System.out.println("Not equal at codePoint <" + Integer.toHexString(codePoint)
|
||||
+ ">, method: " + method
|
||||
+ ", actual: " + actual + ", expected: " + expected);
|
||||
diffs++;
|
||||
}
|
||||
}
|
||||
54
test/jdk/java/lang/Character/CharacterName.java
Normal file
54
test/jdk/java/lang/Character/CharacterName.java
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8147531
|
||||
* @summary Check j.l.Character.getName and codePointOf
|
||||
*/
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class CharacterName {
|
||||
|
||||
public static void main(String[] args) {
|
||||
for (int cp = 0; cp < Character.MAX_CODE_POINT; cp++) {
|
||||
if (!Character.isValidCodePoint(cp)) {
|
||||
try {
|
||||
Character.getName(cp);
|
||||
} catch (IllegalArgumentException x) {
|
||||
continue;
|
||||
}
|
||||
throw new RuntimeException("Invalid failed: " + cp);
|
||||
} else if (Character.getType(cp) == Character.UNASSIGNED) {
|
||||
if (Character.getName(cp) != null)
|
||||
throw new RuntimeException("Unsigned failed: " + cp);
|
||||
} else {
|
||||
String name = Character.getName(cp);
|
||||
if (cp != Character.codePointOf(name) ||
|
||||
cp != Character.codePointOf(name.toLowerCase(Locale.ENGLISH)))
|
||||
throw new RuntimeException("Roundtrip failed: " + cp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
144
test/jdk/java/lang/Character/CheckProp.java
Normal file
144
test/jdk/java/lang/Character/CheckProp.java
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 7037261 7070436 7198195 8032446 8072600 8221431 8229831
|
||||
* @summary Check j.l.Character.isLowerCase/isUppercase/isAlphabetic/isIdeographic/
|
||||
* isUnicodeIdentifierStart/isUnicodeIdentifierPart
|
||||
* @library /lib/testlibrary/java/lang
|
||||
*/
|
||||
|
||||
import java.util.regex.*;
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import static java.lang.Character.*;
|
||||
|
||||
public class CheckProp {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Map<String, List<Integer>> propMap = new LinkedHashMap<>();
|
||||
List.of(UCDFiles.PROP_LIST.toFile(), UCDFiles.DERIVED_PROPS.toFile()).stream()
|
||||
.forEach(f -> readPropMap(propMap, f));
|
||||
|
||||
Integer[] otherLowercase = propMap.get("Other_Lowercase").toArray(new Integer[0]);
|
||||
Integer[] otherUppercase = propMap.get("Other_Uppercase").toArray(new Integer[0]);
|
||||
Integer[] otherAlphabetic = propMap.get("Other_Alphabetic").toArray(new Integer[0]);
|
||||
Integer[] ideographic = propMap.get("Ideographic").toArray(new Integer[0]);
|
||||
Integer[] IDStart = propMap.get("ID_Start").toArray(new Integer[0]);
|
||||
Integer[] IDContinue = propMap.get("ID_Continue").toArray(new Integer[0]);
|
||||
|
||||
int fails = 0;
|
||||
for (int cp = MIN_CODE_POINT; cp < MAX_CODE_POINT; cp++) {
|
||||
int type = getType(cp);
|
||||
if (isLowerCase(cp) !=
|
||||
(type == LOWERCASE_LETTER ||
|
||||
Arrays.binarySearch(otherLowercase, cp) >= 0))
|
||||
{
|
||||
fails++;
|
||||
System.err.printf("Wrong isLowerCase(U+%04x)\n", cp);
|
||||
}
|
||||
if (isUpperCase(cp) !=
|
||||
(type == UPPERCASE_LETTER ||
|
||||
Arrays.binarySearch(otherUppercase, cp) >= 0))
|
||||
{
|
||||
fails++;
|
||||
System.err.printf("Wrong isUpperCase(U+%04x)\n", cp);
|
||||
}
|
||||
if (isAlphabetic(cp) !=
|
||||
(type == UPPERCASE_LETTER || type == LOWERCASE_LETTER ||
|
||||
type == TITLECASE_LETTER || type == MODIFIER_LETTER ||
|
||||
type == OTHER_LETTER || type == OTHER_LETTER ||
|
||||
type == LETTER_NUMBER ||
|
||||
Arrays.binarySearch(otherAlphabetic, cp) >=0))
|
||||
{
|
||||
fails++;
|
||||
System.err.printf("Wrong isAlphabetic(U+%04x)\n", cp);
|
||||
}
|
||||
if (isIdeographic(cp) !=
|
||||
(Arrays.binarySearch(ideographic, cp) >= 0))
|
||||
{
|
||||
fails++;
|
||||
System.err.printf("Wrong isIdeographic(U+%04x)\n", cp);
|
||||
}
|
||||
if (isUnicodeIdentifierStart(cp) !=
|
||||
(cp == 0x2E2F ||
|
||||
Arrays.binarySearch(IDStart, cp) >= 0))
|
||||
{
|
||||
fails++;
|
||||
System.err.printf("Wrong isUnicodeIdentifierStart(U+%04x)\n", cp);
|
||||
}
|
||||
if (isUnicodeIdentifierPart(cp) !=
|
||||
(isIdentifierIgnorable(cp) ||
|
||||
cp == 0x2E2F ||
|
||||
Arrays.binarySearch(IDContinue, cp) >= 0))
|
||||
{
|
||||
fails++;
|
||||
System.err.printf("Wrong isUnicodeIdentifierPart(U+%04x)\n", cp);
|
||||
}
|
||||
}
|
||||
if (fails != 0)
|
||||
throw new RuntimeException("CheckProp failed=" + fails);
|
||||
}
|
||||
|
||||
private static void readPropMap(Map<String, List<Integer>> propMap, File fPropList) {
|
||||
try {
|
||||
BufferedReader sbfr = new BufferedReader(new FileReader(fPropList));
|
||||
Matcher m = Pattern.compile("(\\p{XDigit}+)(?:\\.{2}(\\p{XDigit}+))?\\s*;\\s+(\\w+)\\s+#.*").matcher("");
|
||||
|
||||
String line = null;
|
||||
int lineNo = 0;
|
||||
while ((line = sbfr.readLine()) != null) {
|
||||
lineNo++;
|
||||
if (line.length() <= 1 || line.charAt(0) == '#') {
|
||||
continue;
|
||||
}
|
||||
m.reset(line);
|
||||
if (m.matches()) {
|
||||
int start = Integer.parseInt(m.group(1), 16);
|
||||
int end = (m.group(2)==null)?start
|
||||
:Integer.parseInt(m.group(2), 16);
|
||||
String name = m.group(3);
|
||||
|
||||
List<Integer> list = propMap.get(name);
|
||||
if (list == null) {
|
||||
list = new ArrayList<Integer>();
|
||||
propMap.put(name, list);
|
||||
}
|
||||
while (start <= end)
|
||||
list.add(start++);
|
||||
} else {
|
||||
System.out.printf("Warning: Unrecognized line %d <%s>%n", lineNo, line);
|
||||
}
|
||||
}
|
||||
sbfr.close();
|
||||
} catch (IOException ioe) {
|
||||
throw new UncheckedIOException(ioe);
|
||||
}
|
||||
|
||||
//for (String name: propMap.keySet()) {
|
||||
// System.out.printf("%s %d%n", name, propMap.get(name).size());
|
||||
//}
|
||||
}
|
||||
}
|
||||
159
test/jdk/java/lang/Character/CheckScript.java
Normal file
159
test/jdk/java/lang/Character/CheckScript.java
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6945564 6959267 7033561 7070436 7198195 8032446 8072600 8221431
|
||||
* @summary Check that the j.l.Character.UnicodeScript
|
||||
* @library /lib/testlibrary/java/lang
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.regex.*;
|
||||
import java.lang.Character.UnicodeScript;
|
||||
|
||||
public class CheckScript {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
File fScripts;
|
||||
File fAliases;
|
||||
if (args.length == 0) {
|
||||
fScripts = UCDFiles.SCRIPTS.toFile();
|
||||
fAliases = UCDFiles.PROPERTY_VALUE_ALIASES.toFile();
|
||||
} else if (args.length == 2) {
|
||||
fScripts = new File(args[0]);
|
||||
fAliases = new File(args[1]);
|
||||
} else {
|
||||
System.out.println("java CharacterScript Scripts.txt PropertyValueAliases.txt");
|
||||
throw new RuntimeException("Datafile name should be specified.");
|
||||
}
|
||||
|
||||
Matcher m = Pattern.compile("(\\p{XDigit}+)(?:\\.{2}(\\p{XDigit}+))?\\s+;\\s+(\\w+)\\s+#.*").matcher("");
|
||||
String line = null;
|
||||
HashMap<String,ArrayList<Integer>> scripts = new HashMap<>();
|
||||
try (BufferedReader sbfr = new BufferedReader(new FileReader(fScripts))) {
|
||||
while ((line = sbfr.readLine()) != null) {
|
||||
if (line.length() <= 1 || line.charAt(0) == '#') {
|
||||
continue;
|
||||
}
|
||||
m.reset(line);
|
||||
if (m.matches()) {
|
||||
int start = Integer.parseInt(m.group(1), 16);
|
||||
int end = (m.group(2)==null)?start
|
||||
:Integer.parseInt(m.group(2), 16);
|
||||
String name = m.group(3).toLowerCase(Locale.ENGLISH);
|
||||
ArrayList<Integer> ranges = scripts.get(name);
|
||||
if (ranges == null) {
|
||||
ranges = new ArrayList<Integer>();
|
||||
scripts.put(name, ranges);
|
||||
}
|
||||
ranges.add(start);
|
||||
ranges.add(end);
|
||||
}
|
||||
}
|
||||
}
|
||||
// check all defined ranges
|
||||
Integer[] ZEROSIZEARRAY = new Integer[0];
|
||||
for (String name : scripts.keySet()) {
|
||||
System.out.println("Checking " + name + "...");
|
||||
Integer[] ranges = scripts.get(name).toArray(ZEROSIZEARRAY);
|
||||
Character.UnicodeScript expected =
|
||||
Character.UnicodeScript.forName(name);
|
||||
|
||||
int off = 0;
|
||||
while (off < ranges.length) {
|
||||
int start = ranges[off++];
|
||||
int end = ranges[off++];
|
||||
for (int cp = start; cp <= end; cp++) {
|
||||
Character.UnicodeScript script =
|
||||
Character.UnicodeScript.of(cp);
|
||||
if (script != expected) {
|
||||
throw new RuntimeException(
|
||||
"UnicodeScript failed: cp=" +
|
||||
Integer.toHexString(cp) +
|
||||
", of(cp)=<" + script + "> but <" +
|
||||
expected + "> is expected");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// check all codepoints
|
||||
for (int cp = 0; cp < Character.MAX_CODE_POINT; cp++) {
|
||||
Character.UnicodeScript script = Character.UnicodeScript.of(cp);
|
||||
if (script == Character.UnicodeScript.UNKNOWN) {
|
||||
if (Character.getType(cp) != Character.UNASSIGNED &&
|
||||
Character.getType(cp) != Character.SURROGATE &&
|
||||
Character.getType(cp) != Character.PRIVATE_USE)
|
||||
throw new RuntimeException(
|
||||
"UnicodeScript failed: cp=" +
|
||||
Integer.toHexString(cp) +
|
||||
", of(cp)=<" + script + "> but UNKNOWN is expected");
|
||||
} else {
|
||||
Integer[] ranges =
|
||||
scripts.get(script.name().toLowerCase(Locale.ENGLISH))
|
||||
.toArray(ZEROSIZEARRAY);
|
||||
int off = 0;
|
||||
boolean found = false;
|
||||
while (off < ranges.length) {
|
||||
int start = ranges[off++];
|
||||
int end = ranges[off++];
|
||||
if (cp >= start && cp <= end)
|
||||
found = true;
|
||||
}
|
||||
if (!found) {
|
||||
throw new RuntimeException(
|
||||
"UnicodeScript failed: cp=" +
|
||||
Integer.toHexString(cp) +
|
||||
", of(cp)=<" + script +
|
||||
"> but NOT in ranges of this script");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
// check all aliases
|
||||
m = Pattern.compile("sc\\s*;\\s*(\\p{Alpha}{4})\\s*;\\s*([\\p{Alpha}|_]+)\\s*.*").matcher("");
|
||||
line = null;
|
||||
try (BufferedReader sbfr = new BufferedReader(new FileReader(fAliases))) {
|
||||
while ((line = sbfr.readLine()) != null) {
|
||||
if (line.length() <= 1 || line.charAt(0) == '#') {
|
||||
continue;
|
||||
}
|
||||
m.reset(line);
|
||||
if (m.matches()) {
|
||||
String alias = m.group(1);
|
||||
String name = m.group(2);
|
||||
// HRKT -> Katakana_Or_Hiragana not supported
|
||||
if ("HRKT".equals(alias.toUpperCase(Locale.ENGLISH)))
|
||||
continue;
|
||||
if (Character.UnicodeScript.forName(alias) !=
|
||||
Character.UnicodeScript.forName(name)) {
|
||||
throw new RuntimeException(
|
||||
"UnicodeScript failed: alias<" + alias +
|
||||
"> does not map to <" + name + ">");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
85
test/jdk/java/lang/Character/CheckUnicode.java
Normal file
85
test/jdk/java/lang/Character/CheckUnicode.java
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 4114080 6565620 6959267 7070436 7198195 8032446 8072600 8221431
|
||||
* @summary Make sure the attributes of Unicode characters, as
|
||||
* returned by the Character API, are as expected. Do this by
|
||||
* comparing them to a baseline file together with a list of
|
||||
* known diffs.
|
||||
* @library /lib/testlibrary/java/lang
|
||||
* @build UnicodeSpec CharCheck
|
||||
* @run main CheckUnicode
|
||||
* @author Alan Liu
|
||||
* @author John O'Conner
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class CheckUnicode {
|
||||
public static void main(String args[]) throws Exception {
|
||||
|
||||
// 1. Check that the current 12.1 spec file is handled by the current
|
||||
// version of Character.
|
||||
File unicodeSpec = UCDFiles.UNICODE_DATA.toFile();
|
||||
for (int x = 0; x < 16; ++x) {
|
||||
int diffs = CharCheck.check(x, unicodeSpec);
|
||||
if (diffs != 0) {
|
||||
throw new RuntimeException("Unicode properties have changed " +
|
||||
"in an unexpected way");
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Check that Java identifiers are recognized correctly.
|
||||
// test a few characters that are good id starts
|
||||
char[] idStartChar = {'$', '\u20AC', 'a', 'A', 'z', 'Z', '_', '\u0E3F',
|
||||
'\u1004', '\u10A0', '\u3400', '\u4E00', '\uAC00' };
|
||||
for (int x = 0; x < idStartChar.length; x++) {
|
||||
if (Character.isJavaIdentifierStart(idStartChar[x]) != true) {
|
||||
throw new RuntimeException("Java id start characters are not recognized.");
|
||||
}
|
||||
}
|
||||
|
||||
// test a few characters that are good id parts
|
||||
char[] idPartChar = {'0', '9', '\u0000', '\u0008', '\u000E', '\u007F'};
|
||||
for (int x=0; x< idStartChar.length; x++) {
|
||||
if (Character.isJavaIdentifierPart(idStartChar[x]) != true) {
|
||||
throw new RuntimeException("Java id part characters are not recognized.");
|
||||
}
|
||||
}
|
||||
for (int x=0; x<idPartChar.length; x++) {
|
||||
if (Character.isJavaIdentifierPart(idPartChar[x]) != true) {
|
||||
throw new RuntimeException("Java id part characters are not recognized.");
|
||||
}
|
||||
}
|
||||
|
||||
// now do some negative checks
|
||||
for (int x=0; x< idPartChar.length; x++) {
|
||||
if (Character.isJavaIdentifierStart(idPartChar[x]) != false) {
|
||||
throw new RuntimeException("These Java id part characters" +
|
||||
"should not be start characters.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
70
test/jdk/java/lang/Character/DumpCharProperties.java
Normal file
70
test/jdk/java/lang/Character/DumpCharProperties.java
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Martin Buchholz
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
import static java.lang.Character.*;
|
||||
|
||||
public class DumpCharProperties {
|
||||
final static Locale turkish = Locale.of("tr");
|
||||
|
||||
static String charProps(int i) {
|
||||
String s = new String(new int[]{i},0,1);
|
||||
return String.format
|
||||
("%b %b %b %b %b %b %b %b %b %b %b %b %d %d %d %d %d %b %b %d %d %b %d %d",
|
||||
isLowerCase(i),
|
||||
isUpperCase(i),
|
||||
isTitleCase(i),
|
||||
isDigit(i),
|
||||
isDefined(i),
|
||||
isLetter(i),
|
||||
isLetterOrDigit(i),
|
||||
isJavaIdentifierStart(i),
|
||||
isJavaIdentifierPart(i),
|
||||
isUnicodeIdentifierStart(i),
|
||||
isUnicodeIdentifierPart(i),
|
||||
isIdentifierIgnorable(i),
|
||||
toLowerCase(i),
|
||||
toUpperCase(i),
|
||||
toTitleCase(i),
|
||||
digit(i, 16),
|
||||
getNumericValue(i),
|
||||
isSpaceChar(i),
|
||||
isWhitespace(i),
|
||||
getType(i),
|
||||
getDirectionality(i),
|
||||
isMirrored(i),
|
||||
(int) s.toUpperCase(Locale.GERMAN).charAt(0),
|
||||
(int) s.toUpperCase(turkish).charAt(0));
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
for (int i = 0; i < 17*0x10000; i++) {
|
||||
System.out.println(charProps(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
91
test/jdk/java/lang/Character/Latin1CaseConversion.java
Normal file
91
test/jdk/java/lang/Character/Latin1CaseConversion.java
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8302877
|
||||
* @summary Provides exhaustive verification of Character.toUpperCase and Character.toLowerCase
|
||||
* for all code points in the latin1 range 0-255.
|
||||
* @run junit Latin1CaseConversion
|
||||
*/
|
||||
public class Latin1CaseConversion {
|
||||
|
||||
@Test
|
||||
public void shouldUpperCaseAndLowerCaseLatin1() {
|
||||
for (int c = 0; c < 256; c++) {
|
||||
int upper = Character.toUpperCase(c);
|
||||
int lower = Character.toLowerCase(c);
|
||||
|
||||
if (c < 0x41) { // Before A
|
||||
assertUnchanged(upper, lower, c);
|
||||
} else if (c <= 0x5A) { // A-Z
|
||||
assertEquals(c, upper);
|
||||
assertEquals(c + 32, lower);
|
||||
} else if (c < 0x61) { // Between Z and a
|
||||
assertUnchanged(upper, lower, c);
|
||||
} else if (c <= 0x7A) { // a-z
|
||||
assertEquals(c - 32, upper);
|
||||
assertEquals(c, lower);
|
||||
} else if (c < 0xB5) { // Between z and Micro Sign
|
||||
assertUnchanged(upper, lower, c);
|
||||
} else if (c == 0xB5) { // Special case for Micro Sign
|
||||
assertEquals(0x39C, upper);
|
||||
assertEquals(c, lower);
|
||||
} else if (c < 0xC0) { // Between my and A-grave
|
||||
assertUnchanged(upper, lower, c);
|
||||
} else if (c < 0xD7) { // A-grave - O with Diaeresis
|
||||
assertEquals(c, upper);
|
||||
assertEquals(c + 32, lower);
|
||||
} else if (c == 0xD7) { // Multiplication
|
||||
assertUnchanged(upper, lower, c);
|
||||
} else if (c <= 0xDE) { // O with slash - Thorn
|
||||
assertEquals(c, upper);
|
||||
assertEquals(c + 32, lower);
|
||||
} else if (c == 0xDF) { // Sharp s
|
||||
assertUnchanged(upper, lower, c);
|
||||
} else if (c < 0xF7) { // a-grave - divsion
|
||||
assertEquals(c - 32, upper);
|
||||
assertEquals(c, lower);
|
||||
} else if (c == 0xF7) { // Division
|
||||
assertUnchanged(upper, lower, c);
|
||||
} else if (c < 0xFF) { // o with slash - thorn
|
||||
assertEquals(c - 32, upper);
|
||||
assertEquals(c, lower);
|
||||
} else if (c == 0XFF) { // Special case for y with Diaeresis
|
||||
assertEquals(0x178, upper);
|
||||
assertEquals(c, lower);
|
||||
} else {
|
||||
fail("Uncovered code point: " + Integer.toHexString(c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertUnchanged(int upper, int lower, int c) {
|
||||
assertEquals(c, upper);
|
||||
assertEquals(c, lower);
|
||||
}
|
||||
}
|
||||
68
test/jdk/java/lang/Character/Latin1Digit.java
Normal file
68
test/jdk/java/lang/Character/Latin1Digit.java
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8196740
|
||||
* @summary Check j.l.Character.digit(int,int) for Latin1 characters
|
||||
*/
|
||||
|
||||
public class Latin1Digit {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
for (int ch = 0; ch < 256; ++ch) {
|
||||
for (int radix = -256; radix <= 256; ++radix) {
|
||||
test(ch, radix);
|
||||
}
|
||||
test(ch, Integer.MIN_VALUE);
|
||||
test(ch, Integer.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void test(int ch, int radix) throws Exception {
|
||||
int d1 = Character.digit(ch, radix);
|
||||
int d2 = canonicalDigit(ch, radix);
|
||||
if (d1 != d2) {
|
||||
throw new Exception("Wrong result for char="
|
||||
+ ch + " (" + (char)ch + "), radix="
|
||||
+ radix + "; " + d1 + " != " + d2);
|
||||
}
|
||||
}
|
||||
|
||||
// canonical version of Character.digit(int,int) for Latin1
|
||||
static int canonicalDigit(int ch, int radix) {
|
||||
if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
|
||||
return -1;
|
||||
}
|
||||
if (ch >= '0' && ch <= '9' && ch < (radix + '0')) {
|
||||
return ch - '0';
|
||||
}
|
||||
if (ch >= 'A' && ch <= 'Z' && ch < (radix + 'A' - 10)) {
|
||||
return ch - 'A' + 10;
|
||||
}
|
||||
if (ch >= 'a' && ch <= 'z' && ch < (radix + 'a' - 10)) {
|
||||
return ch - 'a' + 10;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
893
test/jdk/java/lang/Character/Supplementary.java
Normal file
893
test/jdk/java/lang/Character/Supplementary.java
Normal file
|
|
@ -0,0 +1,893 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4533872 4985214 4985217 4993841 5017268 5017280 8298033
|
||||
* @summary Unit tests for supplementary character support (JSR-204)
|
||||
* @compile Supplementary.java
|
||||
* @run main/timeout=600 Supplementary
|
||||
*/
|
||||
|
||||
public class Supplementary {
|
||||
private static final char MIN_HIGH = '\uD800';
|
||||
private static final char MAX_HIGH = '\uDBFF';
|
||||
private static final char MIN_LOW = MAX_HIGH + 1;
|
||||
private static final char MAX_LOW = '\uDFFF';
|
||||
private static final int MIN_CODE_POINT = 0x000000;
|
||||
private static final int MIN_SUPPLEMENTARY = 0x010000;
|
||||
private static final int MAX_SUPPLEMENTARY = 0x10ffff;
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Do not change the order of test method calls since there
|
||||
// are some interdependencies.
|
||||
|
||||
testConstants();
|
||||
|
||||
test00();
|
||||
|
||||
// Store all Unicode code points, except for surrogate code
|
||||
// points, in cu[] through the loops below. Then, use the data
|
||||
// for code point/code unit conversion and other tests later.
|
||||
char[] cu = new char[(MAX_SUPPLEMENTARY+1) * 2];
|
||||
int length = test01(cu);
|
||||
|
||||
String str = new String(cu, 0, length);
|
||||
cu = null;
|
||||
test02(str);
|
||||
test03(str.toCharArray());
|
||||
test04(str);
|
||||
test05(str);
|
||||
|
||||
// Test for toString(int)
|
||||
test06();
|
||||
|
||||
// Test unpaired surrogates
|
||||
testUnpaired();
|
||||
|
||||
// Test exceptions
|
||||
testExceptions00();
|
||||
testExceptions01(str);
|
||||
testExceptions02(str.toCharArray());
|
||||
}
|
||||
|
||||
static void testConstants() {
|
||||
if (Character.MIN_HIGH_SURROGATE != MIN_HIGH) {
|
||||
constantError("MIN_HIGH_SURROGATE", Character.MIN_HIGH_SURROGATE, MIN_HIGH);
|
||||
}
|
||||
if (Character.MAX_HIGH_SURROGATE != MAX_HIGH) {
|
||||
constantError("MAX_HIGH_SURROGATE", Character.MAX_HIGH_SURROGATE, MAX_HIGH);
|
||||
}
|
||||
if (Character.MIN_LOW_SURROGATE != MIN_LOW) {
|
||||
constantError("MIN_LOW_SURROGATE", Character.MIN_LOW_SURROGATE, MIN_LOW);
|
||||
}
|
||||
if (Character.MAX_LOW_SURROGATE != MAX_LOW) {
|
||||
constantError("MAX_LOW_SURROGATE", Character.MAX_LOW_SURROGATE, MAX_LOW);
|
||||
}
|
||||
if (Character.MIN_SURROGATE != MIN_HIGH) {
|
||||
constantError("MIN_SURROGATE", Character.MIN_SURROGATE, MIN_HIGH);
|
||||
}
|
||||
if (Character.MAX_SURROGATE != MAX_LOW) {
|
||||
constantError("MAX_SURROGATE", Character.MAX_SURROGATE, MAX_LOW);
|
||||
}
|
||||
if (Character.MIN_SUPPLEMENTARY_CODE_POINT != MIN_SUPPLEMENTARY) {
|
||||
constantError("MIN_SUPPLEMENTARY_CODE_POINT",
|
||||
Character.MIN_SUPPLEMENTARY_CODE_POINT, MIN_SUPPLEMENTARY);
|
||||
}
|
||||
if (Character.MIN_CODE_POINT != MIN_CODE_POINT) {
|
||||
constantError("MIN_CODE_POINT", Character.MIN_CODE_POINT, MIN_CODE_POINT);
|
||||
}
|
||||
if (Character.MAX_CODE_POINT != MAX_SUPPLEMENTARY) {
|
||||
constantError("MAX_CODE_POINT", Character.MAX_CODE_POINT, MAX_SUPPLEMENTARY);
|
||||
}
|
||||
}
|
||||
|
||||
static void constantError(String name, int value, int expectedValue) {
|
||||
throw new RuntimeException("Character." + name + " has a wrong value: got "
|
||||
+ toHexString(value)
|
||||
+ ", expected " + toHexString(expectedValue));
|
||||
}
|
||||
|
||||
/*
|
||||
* Test isValidCodePoint(int)
|
||||
* isSupplementaryCodePoint(int)
|
||||
* charCount(int)
|
||||
*/
|
||||
static void test00() {
|
||||
for (int cp = -MAX_SUPPLEMENTARY; cp <= MAX_SUPPLEMENTARY*2; cp++) {
|
||||
boolean isValid = cp >= 0 && cp <= MAX_SUPPLEMENTARY;
|
||||
if (Character.isValidCodePoint(cp) != isValid) {
|
||||
throw new RuntimeException("isValidCodePoint failed with "
|
||||
+ toHexString(cp));
|
||||
}
|
||||
boolean isSupplementary = cp >= MIN_SUPPLEMENTARY && cp <= MAX_SUPPLEMENTARY;
|
||||
if (Character.isSupplementaryCodePoint(cp) != isSupplementary) {
|
||||
throw new RuntimeException("isSupplementaryCodePoint failed with "
|
||||
+ toHexString(cp));
|
||||
}
|
||||
int len = Character.charCount(cp);
|
||||
if (isValid) {
|
||||
if ((isSupplementary && len != 2)
|
||||
|| (!isSupplementary && len != 1)) {
|
||||
throw new RuntimeException("wrong character length "+len+" for "
|
||||
+ toHexString(cp));
|
||||
}
|
||||
} else if (len != 1 && len != 2) {
|
||||
throw new RuntimeException("wrong character length "+len+" for "
|
||||
+ toHexString(cp));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test toChar(int)
|
||||
* toChar(int, char[], int)
|
||||
* isHighSurrogate(char)
|
||||
* isLowSurrogate(char)
|
||||
* isSurrogatePair(int, int)
|
||||
*
|
||||
* While testing those methods, this method generates all Unicode
|
||||
* code points (except for surrogate code points) and store them
|
||||
* in cu.
|
||||
*
|
||||
* @return the number of code units generated in cu
|
||||
*/
|
||||
static int test01(char[] cu) {
|
||||
int index = 0;
|
||||
// Test toChar(int)
|
||||
// toChar(int, char[], int)
|
||||
// isHighSurrogate(char)
|
||||
// isLowSurrogate(char)
|
||||
// with BMP code points
|
||||
for (int i = 0; i <= Character.MAX_VALUE; i++) {
|
||||
char[] u = Character.toChars(i);
|
||||
if (u.length != 1 || u[0] != i) {
|
||||
throw new RuntimeException("wrong toChars(int) result for BMP: "
|
||||
+ toHexString("u", u));
|
||||
}
|
||||
int n = Character.toChars(i, cu, index);
|
||||
if (n != 1 || cu[index] != i) {
|
||||
throw new RuntimeException("wrong toChars(int, char[], int) result for BMP:"
|
||||
+ " len=" + n
|
||||
+ ", cu["+index+"]="+toHexString(cu[index]));
|
||||
}
|
||||
boolean isHigh = i >= MIN_HIGH && i <= MAX_HIGH;
|
||||
if (Character.isHighSurrogate((char) i) != isHigh) {
|
||||
throw new RuntimeException("wrong high-surrogate test for "
|
||||
+ toHexString(i));
|
||||
}
|
||||
boolean isLow = i >= MIN_LOW && i <= MAX_LOW;
|
||||
if (Character.isLowSurrogate((char)i) != isLow) {
|
||||
throw new RuntimeException("wrong low-surrogate test for "
|
||||
+ toHexString(i));
|
||||
}
|
||||
if (!isHigh && !isLow) {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
// Test isSurrogatePair with all surrogate pairs
|
||||
// Test toChars(int)
|
||||
// toChars(int, char[], int)
|
||||
// with all supplementary characters
|
||||
int supplementary = MIN_SUPPLEMENTARY;
|
||||
for (int i = Character.MAX_VALUE/2; i <= Character.MAX_VALUE; i++) {
|
||||
char hi = (char) i;
|
||||
boolean isHigh = Character.isHighSurrogate(hi);
|
||||
|
||||
for (int j = Character.MAX_VALUE/2; j <= Character.MAX_VALUE; j++) {
|
||||
char lo = (char) j;
|
||||
boolean isLow = Character.isLowSurrogate(lo);
|
||||
boolean isSurrogatePair = isHigh && isLow;
|
||||
if (Character.isSurrogatePair(hi, lo) != isSurrogatePair) {
|
||||
throw new RuntimeException("wrong surrogate pair test for hi="
|
||||
+ toHexString(hi)
|
||||
+ ", lo="+toHexString(lo));
|
||||
}
|
||||
if (isSurrogatePair) {
|
||||
int cp = Character.toCodePoint(hi, lo);
|
||||
if (cp != supplementary) {
|
||||
throw new RuntimeException("wrong code point: got "
|
||||
+ toHexString(cp)
|
||||
+ ", expected="
|
||||
+ toHexString(supplementary));
|
||||
}
|
||||
char[] u = Character.toChars(cp);
|
||||
if (u.length != 2 || u[0] != hi || u[1] != lo) {
|
||||
throw new RuntimeException("wrong toChars(int) result for supplementary: "+
|
||||
toHexString("u", u));
|
||||
}
|
||||
int n = Character.toChars(cp, cu, index);
|
||||
if (n != 2 || cu[index] != hi || cu[index+1] != lo) {
|
||||
throw new RuntimeException("wrong toChars(int, char[], int) result "
|
||||
+ "for supplementary: len=" + n
|
||||
+ ", cu["+index+"]=" + toHexString(cu[index])
|
||||
+ ", cu["+(index+1)+"]=" + toHexString(cu[index+1]));
|
||||
}
|
||||
index += n;
|
||||
supplementary++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (supplementary != MAX_SUPPLEMENTARY + 1) {
|
||||
throw new RuntimeException("wrong supplementary count (supplementary="
|
||||
+ toHexString(supplementary)+")");
|
||||
}
|
||||
|
||||
int nCodeUnits = Character.MAX_VALUE + 1 - (MAX_LOW - MIN_HIGH + 1)
|
||||
+ ((MAX_SUPPLEMENTARY - MIN_SUPPLEMENTARY + 1) * 2);
|
||||
if (index != nCodeUnits) {
|
||||
throw new RuntimeException("wrong number of code units: " + index
|
||||
+ ", expected " + nCodeUnits);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test codePointAt(CharSequence, int)
|
||||
* codePointBefore(CharSequence, int)
|
||||
*/
|
||||
static void test02(CharSequence cs) {
|
||||
int cp = 0;
|
||||
int ch;
|
||||
for (int i = 0; i < cs.length(); i += Character.charCount(ch)) {
|
||||
ch = Character.codePointAt(cs, i);
|
||||
if (ch != cp) {
|
||||
throw new RuntimeException("wrong codePointAt(CharSequence, "+i+") value: got "
|
||||
+ toHexString(ch)
|
||||
+ ", expected "+toHexString(cp));
|
||||
}
|
||||
cp++;
|
||||
// Skip surrogates
|
||||
if (cp == MIN_HIGH) {
|
||||
cp = MAX_LOW + 1;
|
||||
}
|
||||
}
|
||||
|
||||
cp--;
|
||||
for (int i = cs.length(); i > 0; i -= Character.charCount(ch)) {
|
||||
ch = Character.codePointBefore(cs, i);
|
||||
if (ch != cp) {
|
||||
throw new RuntimeException("codePointBefore(CharSequence, "+i+") returned "
|
||||
+ toHexString(ch)
|
||||
+ ", expected " + toHexString(cp));
|
||||
}
|
||||
cp--;
|
||||
// Skip surrogates
|
||||
if (cp == MAX_LOW) {
|
||||
cp = MIN_HIGH - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test codePointAt(char[], int)
|
||||
* codePointAt(char[], int, int)
|
||||
* codePointBefore(char[], int)
|
||||
* codePointBefore(char[], int, int)
|
||||
*/
|
||||
static void test03(char[] a) {
|
||||
int cp = 0;
|
||||
int ch;
|
||||
for (int i = 0; i < a.length; i += Character.charCount(ch)) {
|
||||
ch = Character.codePointAt(a, i);
|
||||
if (ch != cp) {
|
||||
throw new RuntimeException("codePointAt(char[], "+i+") returned "
|
||||
+ toHexString(ch)
|
||||
+ ", expected "+toHexString(cp));
|
||||
}
|
||||
int x = Character.codePointAt(a, i, i+1);
|
||||
if (x != a[i]) {
|
||||
throw new RuntimeException(String.format(
|
||||
"codePointAt(char[], %d, %d) returned 0x%04x, expected 0x%04x\n",
|
||||
i, i+1, x, (int)a[i]));
|
||||
}
|
||||
cp++;
|
||||
// Skip surrogates
|
||||
if (cp == MIN_HIGH) {
|
||||
cp = MAX_LOW + 1;
|
||||
}
|
||||
}
|
||||
|
||||
cp--;
|
||||
for (int i = a.length; i > 0; i -= Character.charCount(ch)) {
|
||||
ch = Character.codePointBefore(a, i);
|
||||
if (ch != cp) {
|
||||
throw new RuntimeException("codePointBefore(char[], "+i+") returned "
|
||||
+ toHexString(ch)
|
||||
+ ", expected " + toHexString(cp));
|
||||
}
|
||||
int x = Character.codePointBefore(a, i, i-1);
|
||||
if (x != a[i-1]) {
|
||||
throw new RuntimeException(String.format(
|
||||
"codePointAt(char[], %d, %d) returned 0x%04x, expected 0x%04x\n",
|
||||
i, i-1, x, (int)a[i-1]));
|
||||
}
|
||||
cp--;
|
||||
// Skip surrogates
|
||||
if (cp == MAX_LOW) {
|
||||
cp = MIN_HIGH - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test codePointCount(CharSequence, int, int)
|
||||
* codePointCount(char[], int, int, int, int)
|
||||
*/
|
||||
static void test04(String str) {
|
||||
int length = str.length();
|
||||
char[] a = str.toCharArray();
|
||||
|
||||
for (int i = 0; i <= length; i += 99, length -= 29999) {
|
||||
int n = Character.codePointCount(str, i, length);
|
||||
int m = codePointCount(str.substring(i, length));
|
||||
checkCodePointCount(str, n, m);
|
||||
n = Character.codePointCount(a, i, length - i);
|
||||
checkCodePointCount(a, n, m);
|
||||
}
|
||||
|
||||
// test special cases
|
||||
length = str.length();
|
||||
int n = Character.codePointCount(str, 0, 0);
|
||||
checkCodePointCount(str, n, 0);
|
||||
n = Character.codePointCount(str, length, length);
|
||||
checkCodePointCount(str, n, 0);
|
||||
n = Character.codePointCount(a, 0, 0);
|
||||
checkCodePointCount(a, n, 0);
|
||||
n = Character.codePointCount(a, length, 0);
|
||||
checkCodePointCount(a, n, 0);
|
||||
}
|
||||
|
||||
// This method assumes that Character.codePointAt() and
|
||||
// Character.charCount() work correctly.
|
||||
private static int codePointCount(CharSequence seq) {
|
||||
int n = 0, len;
|
||||
for (int i = 0; i < seq.length(); i += len) {
|
||||
int codepoint = Character.codePointAt(seq, i);
|
||||
n++;
|
||||
len = Character.charCount(codepoint);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
private static void checkCodePointCount(Object data, int n, int expected) {
|
||||
String type = getType(data);
|
||||
if (n != expected) {
|
||||
throw new RuntimeException("codePointCount(" + type + "...) returned " + n
|
||||
+ ", expected " + expected);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test offsetByCodePoints(CharSequence, int, int)
|
||||
* offsetByCodePoints(char[], int, int, int, int)
|
||||
*
|
||||
* This test case assumes that Character.codePointCount()s work
|
||||
* correctly.
|
||||
*/
|
||||
static void test05(String str) {
|
||||
int length = str.length();
|
||||
char[] a = str.toCharArray();
|
||||
|
||||
for (int i = 0; i <= length; i += 99, length -= 29999) {
|
||||
int nCodePoints = Character.codePointCount(a, i, length - i);
|
||||
int index;
|
||||
|
||||
// offsetByCodePoints(CharSequence, int, int)
|
||||
|
||||
int expectedHighIndex = length;
|
||||
// For forward CharSequence scan, we need to adjust the
|
||||
// expected index in case the last char in the text range
|
||||
// is a high surrogate and forms a valid supplementary
|
||||
// code point with the next char.
|
||||
if (length < a.length) {
|
||||
int cp = Character.codePointAt(a, length - 1);
|
||||
if (Character.isSupplementaryCodePoint(cp)) {
|
||||
expectedHighIndex++;
|
||||
}
|
||||
}
|
||||
index = Character.offsetByCodePoints(str, i, nCodePoints);
|
||||
checkNewIndex(str, nCodePoints, index, expectedHighIndex);
|
||||
int expectedLowIndex = i;
|
||||
if (i > 0) {
|
||||
int cp = Character.codePointBefore(a, i + 1);
|
||||
if (Character.isSupplementaryCodePoint(cp)) {
|
||||
expectedLowIndex--;
|
||||
}
|
||||
}
|
||||
index = Character.offsetByCodePoints(str, length, -nCodePoints);
|
||||
checkNewIndex(str, -nCodePoints, index, expectedLowIndex);
|
||||
|
||||
// offsetByCodePoints(char[], int, int, int, int)
|
||||
|
||||
int start = Math.max(0, i-1);
|
||||
int limit = Math.min(a.length, length+1);
|
||||
index = Character.offsetByCodePoints(a, start, limit - start,
|
||||
i, nCodePoints);
|
||||
checkNewIndex(a, nCodePoints, index, expectedHighIndex);
|
||||
if (length != expectedHighIndex) {
|
||||
index = Character.offsetByCodePoints(a, start, length - start,
|
||||
i, nCodePoints);
|
||||
checkNewIndex(a, nCodePoints, index, length);
|
||||
}
|
||||
index = Character.offsetByCodePoints(a, start, limit - start,
|
||||
length, -nCodePoints);
|
||||
checkNewIndex(a, -nCodePoints, index, expectedLowIndex);
|
||||
if (i != expectedLowIndex) {
|
||||
index = Character.offsetByCodePoints(a, i, limit - i,
|
||||
length, -nCodePoints);
|
||||
checkNewIndex(a, -nCodePoints, index, i);
|
||||
}
|
||||
}
|
||||
|
||||
// test special cases for 0-length text ranges.
|
||||
length = str.length();
|
||||
int index = Character.offsetByCodePoints(str, 0, 0);
|
||||
checkNewIndex(str, 0, index, 0);
|
||||
index = Character.offsetByCodePoints(str, length, 0);
|
||||
checkNewIndex(str, 0, index, length);
|
||||
index = Character.offsetByCodePoints(a, 0, 0, 0, 0);
|
||||
checkNewIndex(a, 0, index, 0);
|
||||
index = Character.offsetByCodePoints(a, 0, length, 0, 0);
|
||||
checkNewIndex(a, 0, index, 0);
|
||||
index = Character.offsetByCodePoints(a, 0, length, length, 0);
|
||||
checkNewIndex(a, 0, index, length);
|
||||
index = Character.offsetByCodePoints(a, length, 0, length, 0);
|
||||
checkNewIndex(a, 0, index, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test toString(int)
|
||||
*
|
||||
* This test case assumes that Character.toChars()/String(char[]) work
|
||||
* correctly.
|
||||
*/
|
||||
static void test06() {
|
||||
for (int cp = Character.MIN_CODE_POINT; cp <= Character.MAX_CODE_POINT; cp++) {
|
||||
String result = Character.toString(cp);
|
||||
String expected = new String(Character.toChars(cp));
|
||||
if (!result.equals(expected)) {
|
||||
throw new RuntimeException("Wrong string is created. code point: " +
|
||||
cp + ", result: " + result + ", expected: " + expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkNewIndex(Object data, int offset, int result, int expected) {
|
||||
String type = getType(data);
|
||||
String offsetType = (offset > 0) ? "positive" : (offset < 0) ? "negative" : "0";
|
||||
if (result != expected) {
|
||||
throw new RuntimeException("offsetByCodePoints(" + type + ", ...) ["
|
||||
+ offsetType + " offset]"
|
||||
+ " returned " + result
|
||||
+ ", expected " + expected);
|
||||
}
|
||||
}
|
||||
|
||||
// Test codePointAt(CharSequence, int)
|
||||
// codePointBefore(CharSequence, int)
|
||||
// codePointAt(char[], int)
|
||||
// codePointBefore(char[], int)
|
||||
// toChar(int)
|
||||
// toChar(int, char[], int)
|
||||
// with unpaired surrogates
|
||||
static void testUnpaired() {
|
||||
testCodePoint("\uD800", new int[] { 0xD800 });
|
||||
testCodePoint("\uDC00", new int[] { 0xDC00 });
|
||||
testCodePoint("a\uD800", new int[] { 'a', 0xD800 });
|
||||
testCodePoint("a\uDC00", new int[] { 'a', 0xDC00 });
|
||||
testCodePoint("\uD800a", new int[] { 0xD800, 'a' });
|
||||
testCodePoint("\uDBFFa", new int[] { 0xDBFF, 'a' });
|
||||
testCodePoint("a\uD800\uD801", new int[] { 'a', 0xD800, 0xD801 });
|
||||
testCodePoint("a\uD800x\uDC00", new int[] { 'a', 0xD800, 'x', 0xDC00 });
|
||||
testCodePoint("\uDC00\uD800", new int[] { 0xDC00, 0xD800 });
|
||||
testCodePoint("\uD800\uDC00\uDC00", new int[] { 0x10000, 0xDC00 });
|
||||
testCodePoint("\uD800\uD800\uDC00", new int[] { 0xD800, 0x10000 });
|
||||
testCodePoint("\uD800\uD800\uD800\uD800\uDC00\uDC00\uDC00\uDC00",
|
||||
new int[] { 0xD800, 0xD800, 0xD800, 0x10000, 0xDC00, 0xDC00, 0xDC00});
|
||||
}
|
||||
|
||||
static void testCodePoint(String str, int[] codepoints) {
|
||||
int c;
|
||||
// Test Character.codePointAt/Before(CharSequence, int)
|
||||
int j = 0;
|
||||
for (int i = 0; i < str.length(); i += Character.charCount(c)) {
|
||||
c = Character.codePointAt(str, i);
|
||||
if (c != codepoints[j++]) {
|
||||
throw new RuntimeException("codePointAt(CharSequence, " + i + ") returned "
|
||||
+ toHexString(c)
|
||||
+ ", expected " + toHexString(codepoints[j-1]));
|
||||
}
|
||||
}
|
||||
if (j != codepoints.length) {
|
||||
throw new RuntimeException("j != codepoints.length after codePointAt(CharSequence, int)"
|
||||
+ " (j=" + j + ")"
|
||||
+ ", expected: " + codepoints.length);
|
||||
}
|
||||
|
||||
j = codepoints.length;
|
||||
for (int i = str.length(); i > 0 ; i -= Character.charCount(c)) {
|
||||
c = Character.codePointBefore(str, i);
|
||||
if (c != codepoints[--j]) {
|
||||
throw new RuntimeException("codePointBefore(CharSequence, " + i + ") returned "
|
||||
+ toHexString(c)
|
||||
+ ", expected " + toHexString(codepoints[j]));
|
||||
}
|
||||
}
|
||||
if (j != 0) {
|
||||
throw new RuntimeException("j != 0 after codePointBefore(CharSequence, int)"
|
||||
+ " (j=" + j + ")");
|
||||
}
|
||||
|
||||
// Test Character.codePointAt/Before(char[], int)
|
||||
char[] a = str.toCharArray();
|
||||
j = 0;
|
||||
for (int i = 0; i < a.length; i += Character.charCount(c)) {
|
||||
c = Character.codePointAt(a, i);
|
||||
if (c != codepoints[j++]) {
|
||||
throw new RuntimeException("codePointAt(char[], " + i + ") returned "
|
||||
+ toHexString(c)
|
||||
+ ", expected " + toHexString(codepoints[j-1]));
|
||||
}
|
||||
}
|
||||
if (j != codepoints.length) {
|
||||
throw new RuntimeException("j != codepoints.length after codePointAt(char[], int)"
|
||||
+ " (j=" + j + ")"
|
||||
+ ", expected: " + codepoints.length);
|
||||
}
|
||||
|
||||
j = codepoints.length;
|
||||
for (int i = a.length; i > 0 ; i -= Character.charCount(c)) {
|
||||
c = Character.codePointBefore(a, i);
|
||||
if (c != codepoints[--j]) {
|
||||
throw new RuntimeException("codePointBefore(char[], " + i + ") returned "
|
||||
+ toHexString(c)
|
||||
+ ", expected " + toHexString(codepoints[j]));
|
||||
}
|
||||
}
|
||||
if (j != 0) {
|
||||
throw new RuntimeException("j != 0 after codePointBefore(char[], int)"
|
||||
+ " (j=" + j + ")");
|
||||
}
|
||||
|
||||
// Test toChar(int)
|
||||
j = 0;
|
||||
for (int i = 0; i < codepoints.length; i++) {
|
||||
a = Character.toChars(codepoints[i]);
|
||||
for (int k = 0; k < a.length; k++) {
|
||||
if (str.charAt(j++) != a[k]) {
|
||||
throw new RuntimeException("toChars(int) returned " + toHexString("result", a)
|
||||
+ " from codepoint=" + toHexString(codepoints[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test toChars(int, char[], int)
|
||||
a = new char[codepoints.length * 2];
|
||||
j = 0;
|
||||
for (int i = 0; i < codepoints.length; i++) {
|
||||
int n = Character.toChars(codepoints[i], a, j);
|
||||
j += n;
|
||||
}
|
||||
String s = new String(a, 0, j);
|
||||
if (!str.equals(s)) {
|
||||
throw new RuntimeException("toChars(int, char[], int) returned "
|
||||
+ toHexString("dst", s.toCharArray())
|
||||
+ ", expected " + toHexString("data", str.toCharArray()));
|
||||
}
|
||||
}
|
||||
|
||||
// Test toChar(int)
|
||||
// toChar(int, char[], int)
|
||||
// toString(int)
|
||||
// for exceptions
|
||||
static void testExceptions00() {
|
||||
callToChars1(-1, IllegalArgumentException.class);
|
||||
callToChars1(MAX_SUPPLEMENTARY + 1, IllegalArgumentException.class);
|
||||
|
||||
callToChars3(MAX_SUPPLEMENTARY, null, 0, NullPointerException.class);
|
||||
callToChars3(-MIN_SUPPLEMENTARY, new char[2], 0, IllegalArgumentException.class);
|
||||
callToChars3(MAX_SUPPLEMENTARY + 1, new char[2], 0, IllegalArgumentException.class);
|
||||
callToChars3('A', new char[0], 0, IndexOutOfBoundsException.class);
|
||||
callToChars3('A', new char[1], -1, IndexOutOfBoundsException.class);
|
||||
callToChars3('A', new char[1], 1, IndexOutOfBoundsException.class);
|
||||
callToChars3(MIN_SUPPLEMENTARY, new char[0], 0, IndexOutOfBoundsException.class);
|
||||
callToChars3(MIN_SUPPLEMENTARY, new char[1], 0, IndexOutOfBoundsException.class);
|
||||
callToChars3(MIN_SUPPLEMENTARY, new char[2], -1, IndexOutOfBoundsException.class);
|
||||
callToChars3(MIN_SUPPLEMENTARY, new char[2], 1, IndexOutOfBoundsException.class);
|
||||
|
||||
callToString(Character.MIN_CODE_POINT - 1, IllegalArgumentException.class);
|
||||
callToString(Character.MAX_CODE_POINT + 1, IllegalArgumentException.class);
|
||||
}
|
||||
|
||||
static final boolean At = true, Before = false;
|
||||
|
||||
/**
|
||||
* Test codePointAt(CharSequence, int)
|
||||
* codePointBefore(CharSequence, int)
|
||||
* codePointCount(CharSequence, int, int)
|
||||
* offsetByCodePoints(CharSequence, int, int)
|
||||
* for exceptions
|
||||
*/
|
||||
static void testExceptions01(CharSequence cs) {
|
||||
CharSequence nullSeq = null;
|
||||
// codePointAt
|
||||
callCodePoint(At, nullSeq, 0, NullPointerException.class);
|
||||
callCodePoint(At, cs, -1, IndexOutOfBoundsException.class);
|
||||
callCodePoint(At, cs, cs.length(), IndexOutOfBoundsException.class);
|
||||
callCodePoint(At, cs, cs.length()*3, IndexOutOfBoundsException.class);
|
||||
|
||||
// codePointBefore
|
||||
callCodePoint(Before, nullSeq, 0, NullPointerException.class);
|
||||
callCodePoint(Before, cs, -1, IndexOutOfBoundsException.class);
|
||||
callCodePoint(Before, cs, 0, IndexOutOfBoundsException.class);
|
||||
callCodePoint(Before, cs, cs.length()+1, IndexOutOfBoundsException.class);
|
||||
|
||||
// codePointCount
|
||||
callCodePointCount(nullSeq, 0, 0, NullPointerException.class);
|
||||
callCodePointCount(cs, -1, 1, IndexOutOfBoundsException.class);
|
||||
callCodePointCount(cs, 0, cs.length()+1, IndexOutOfBoundsException.class);
|
||||
callCodePointCount(cs, 3, 1, IndexOutOfBoundsException.class);
|
||||
|
||||
// offsetByCodePoints
|
||||
callOffsetByCodePoints(nullSeq, 0, 0, NullPointerException.class);
|
||||
callOffsetByCodePoints(cs, -1, 1, IndexOutOfBoundsException.class);
|
||||
callOffsetByCodePoints(cs, cs.length()+1, 1, IndexOutOfBoundsException.class);
|
||||
callOffsetByCodePoints(cs, 0, cs.length()*2, IndexOutOfBoundsException.class);
|
||||
callOffsetByCodePoints(cs, cs.length(), 1, IndexOutOfBoundsException.class);
|
||||
callOffsetByCodePoints(cs, 0, -1, IndexOutOfBoundsException.class);
|
||||
callOffsetByCodePoints(cs, cs.length(), -cs.length()*2,
|
||||
IndexOutOfBoundsException.class);
|
||||
callOffsetByCodePoints(cs, cs.length(), Integer.MIN_VALUE,
|
||||
IndexOutOfBoundsException.class);
|
||||
callOffsetByCodePoints(cs, 0, Integer.MAX_VALUE, IndexOutOfBoundsException.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test codePointAt(char[], int)
|
||||
* codePointAt(char[], int, int)
|
||||
* codePointBefore(char[], int)
|
||||
* codePointBefore(char[], int, int)
|
||||
* codePointCount(char[], int, int)
|
||||
* offsetByCodePoints(char[], int, int, int, int)
|
||||
* for exceptions
|
||||
*/
|
||||
static void testExceptions02(char[] a) {
|
||||
char[] nullArray = null;
|
||||
callCodePoint(At, nullArray, 0, NullPointerException.class);
|
||||
callCodePoint(At, a, -1, IndexOutOfBoundsException.class);
|
||||
callCodePoint(At, a, a.length, IndexOutOfBoundsException.class);
|
||||
callCodePoint(At, a, a.length*3, IndexOutOfBoundsException.class);
|
||||
callCodePoint(Before, nullArray, 0, NullPointerException.class);
|
||||
callCodePoint(Before, a, -1, IndexOutOfBoundsException.class);
|
||||
callCodePoint(Before, a, 0, IndexOutOfBoundsException.class);
|
||||
callCodePoint(Before, a, a.length+1, IndexOutOfBoundsException.class);
|
||||
|
||||
// tests for the methods with limit
|
||||
callCodePoint(At, nullArray, 0, 1, NullPointerException.class);
|
||||
callCodePoint(At, a, 0, -1, IndexOutOfBoundsException.class);
|
||||
callCodePoint(At, a, 0, 0, IndexOutOfBoundsException.class);
|
||||
callCodePoint(At, a, 0, a.length+1, IndexOutOfBoundsException.class);
|
||||
callCodePoint(At, a, 2, 1, IndexOutOfBoundsException.class);
|
||||
callCodePoint(At, a, -1, 1, IndexOutOfBoundsException.class);
|
||||
callCodePoint(At, a, a.length, 1, IndexOutOfBoundsException.class);
|
||||
callCodePoint(At, a, a.length*3, 1, IndexOutOfBoundsException.class);
|
||||
callCodePoint(Before, nullArray, 1, 0, NullPointerException.class);
|
||||
callCodePoint(Before, a, 2, -1, IndexOutOfBoundsException.class);
|
||||
callCodePoint(Before, a, 2, 2, IndexOutOfBoundsException.class);
|
||||
callCodePoint(Before, a, 2, 3, IndexOutOfBoundsException.class);
|
||||
callCodePoint(Before, a, 2, a.length, IndexOutOfBoundsException.class);
|
||||
callCodePoint(Before, a, -1, -1, IndexOutOfBoundsException.class);
|
||||
callCodePoint(Before, a, 0, 0, IndexOutOfBoundsException.class);
|
||||
callCodePoint(Before, a, a.length+1, a.length-1, IndexOutOfBoundsException.class);
|
||||
|
||||
// codePointCount
|
||||
callCodePointCount(nullArray, 0, 0, NullPointerException.class);
|
||||
callCodePointCount(a, -1, 1, IndexOutOfBoundsException.class);
|
||||
callCodePointCount(a, 0, -1, IndexOutOfBoundsException.class);
|
||||
callCodePointCount(a, 0, a.length+1, IndexOutOfBoundsException.class);
|
||||
callCodePointCount(a, 1, a.length, IndexOutOfBoundsException.class);
|
||||
callCodePointCount(a, a.length, 1, IndexOutOfBoundsException.class);
|
||||
callCodePointCount(a, a.length+1, -1, IndexOutOfBoundsException.class);
|
||||
|
||||
// offsetByCodePoints
|
||||
callOffsetByCodePoints(nullArray, 0, 0, 0, 0, NullPointerException.class);
|
||||
callOffsetByCodePoints(a, -1, a.length, 1, 1, IndexOutOfBoundsException.class);
|
||||
callOffsetByCodePoints(a, 0, a.length+1, 1, 1, IndexOutOfBoundsException.class);
|
||||
callOffsetByCodePoints(a, 10, a.length, 1, 1, IndexOutOfBoundsException.class);
|
||||
callOffsetByCodePoints(a, 10, a.length-10, 1, 1, IndexOutOfBoundsException.class);
|
||||
callOffsetByCodePoints(a, 10, 10, 21, 1, IndexOutOfBoundsException.class);
|
||||
callOffsetByCodePoints(a, 20, -10, 15, 1, IndexOutOfBoundsException.class);
|
||||
callOffsetByCodePoints(a, 10, 10, 15, 20, IndexOutOfBoundsException.class);
|
||||
callOffsetByCodePoints(a, 10, 10, 15, -20, IndexOutOfBoundsException.class);
|
||||
callOffsetByCodePoints(a, 0, a.length, -1, 1, IndexOutOfBoundsException.class);
|
||||
callOffsetByCodePoints(a, 0, a.length, a.length+1, 1, IndexOutOfBoundsException.class);
|
||||
callOffsetByCodePoints(a, 0, a.length, 0, a.length*2, IndexOutOfBoundsException.class);
|
||||
callOffsetByCodePoints(a, 0, a.length, a.length, 1, IndexOutOfBoundsException.class);
|
||||
callOffsetByCodePoints(a, 0, a.length, 0, -1, IndexOutOfBoundsException.class);
|
||||
callOffsetByCodePoints(a, 0, a.length, a.length, -a.length*2,
|
||||
IndexOutOfBoundsException.class);
|
||||
callOffsetByCodePoints(a, 0, a.length, a.length, Integer.MIN_VALUE,
|
||||
IndexOutOfBoundsException.class);
|
||||
callOffsetByCodePoints(a, 0, a.length, 0, Integer.MAX_VALUE,
|
||||
IndexOutOfBoundsException.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the 1-arg toChars(int) for exceptions
|
||||
*/
|
||||
private static void callToChars1(int codePoint, Class expectedException) {
|
||||
try {
|
||||
char[] a = Character.toChars(codePoint);
|
||||
} catch (Exception e) {
|
||||
if (expectedException.isInstance(e)) {
|
||||
return;
|
||||
}
|
||||
throw new RuntimeException("Unspecified exception", e);
|
||||
}
|
||||
throw new RuntimeException("toChars(int) didn't throw " + expectedException.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the 3-arg toChars(int, char[], int) for exceptions
|
||||
*/
|
||||
private static void callToChars3(int codePoint, char[] dst, int index,
|
||||
Class expectedException) {
|
||||
try {
|
||||
int n = Character.toChars(codePoint, dst, index);
|
||||
} catch (Exception e) {
|
||||
if (expectedException.isInstance(e)) {
|
||||
return;
|
||||
}
|
||||
throw new RuntimeException("Unspecified exception", e);
|
||||
}
|
||||
throw new RuntimeException("toChars(int,char[],int) didn't throw "
|
||||
+ expectedException.getName());
|
||||
}
|
||||
|
||||
private static void callCodePoint(boolean isAt, CharSequence cs, int index,
|
||||
Class expectedException) {
|
||||
try {
|
||||
int c = isAt ? Character.codePointAt(cs, index)
|
||||
: Character.codePointBefore(cs, index);
|
||||
} catch (Exception e) {
|
||||
if (expectedException.isInstance(e)) {
|
||||
return;
|
||||
}
|
||||
throw new RuntimeException("Unspecified exception", e);
|
||||
}
|
||||
throw new RuntimeException("codePoint" + (isAt ? "At" : "Before")
|
||||
+ " didn't throw " + expectedException.getName());
|
||||
}
|
||||
|
||||
private static void callCodePoint(boolean isAt, char[] a, int index,
|
||||
Class expectedException) {
|
||||
try {
|
||||
int c = isAt ? Character.codePointAt(a, index)
|
||||
: Character.codePointBefore(a, index);
|
||||
} catch (Exception e) {
|
||||
if (expectedException.isInstance(e)) {
|
||||
return;
|
||||
}
|
||||
throw new RuntimeException("Unspecified exception", e);
|
||||
}
|
||||
throw new RuntimeException("codePoint" + (isAt ? "At" : "Before")
|
||||
+ " didn't throw " + expectedException.getName());
|
||||
}
|
||||
|
||||
private static void callCodePoint(boolean isAt, char[] a, int index, int limit,
|
||||
Class<? extends Exception> expectedException) {
|
||||
try {
|
||||
int c = isAt ? Character.codePointAt(a, index, limit)
|
||||
: Character.codePointBefore(a, index, limit);
|
||||
} catch (Exception e) {
|
||||
if (expectedException == e.getClass()) {
|
||||
return;
|
||||
}
|
||||
throw new RuntimeException("Unspecified exception", e);
|
||||
}
|
||||
throw new RuntimeException("codePoint" + (isAt ? "At" : "Before")
|
||||
+ " didn't throw " + expectedException.getName());
|
||||
}
|
||||
|
||||
private static void callCodePointCount(Object data, int beginIndex, int endIndex,
|
||||
Class expectedException) {
|
||||
String type = getType(data);
|
||||
try {
|
||||
int n = (data instanceof CharSequence) ?
|
||||
Character.codePointCount((CharSequence) data, beginIndex, endIndex)
|
||||
: Character.codePointCount((char[]) data, beginIndex, endIndex);
|
||||
} catch (Exception e) {
|
||||
if (expectedException.isInstance(e)) {
|
||||
return;
|
||||
}
|
||||
throw new RuntimeException("Unspecified exception", e);
|
||||
}
|
||||
throw new RuntimeException("codePointCount(" + type + "...) didn't throw "
|
||||
+ expectedException.getName());
|
||||
}
|
||||
|
||||
private static void callOffsetByCodePoints(CharSequence seq, int index, int offset,
|
||||
Class expectedException) {
|
||||
try {
|
||||
int n = Character.offsetByCodePoints(seq, index, offset);
|
||||
} catch (Exception e) {
|
||||
if (expectedException.isInstance(e)) {
|
||||
return;
|
||||
}
|
||||
throw new RuntimeException("Unspecified exception", e);
|
||||
}
|
||||
throw new RuntimeException("offsetCodePointCounts(CharSequnce...) didn't throw "
|
||||
+ expectedException.getName());
|
||||
}
|
||||
|
||||
|
||||
private static void callOffsetByCodePoints(char[] a, int start, int count,
|
||||
int index, int offset,
|
||||
Class expectedException) {
|
||||
try {
|
||||
int n = Character.offsetByCodePoints(a, start, count, index, offset);
|
||||
} catch (Exception e) {
|
||||
if (expectedException.isInstance(e)) {
|
||||
return;
|
||||
}
|
||||
throw new RuntimeException("Unspecified exception", e);
|
||||
}
|
||||
throw new RuntimeException("offsetCodePointCounts(char[]...) didn't throw "
|
||||
+ expectedException.getName());
|
||||
}
|
||||
|
||||
private static void callToString(int codePoint, Class expectedException) {
|
||||
try {
|
||||
String s = Character.toString(codePoint);
|
||||
} catch (Exception e) {
|
||||
if (expectedException.isInstance(e)) {
|
||||
return;
|
||||
}
|
||||
throw new RuntimeException("Unspecified exception", e);
|
||||
}
|
||||
throw new RuntimeException("toString(int) didn't throw "
|
||||
+ expectedException.getName());
|
||||
}
|
||||
|
||||
private static String getType(Object data) {
|
||||
return (data instanceof CharSequence) ? "CharSequence" : "char[]";
|
||||
}
|
||||
|
||||
private static String toHexString(int c) {
|
||||
return "0x" + Integer.toHexString(c);
|
||||
}
|
||||
|
||||
private static String toHexString(String name, char[] a) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(name).append('[').append(i).append("]=");
|
||||
sb.append(toHexString(a[i]));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
138
test/jdk/java/lang/Character/TestEmojiProperties.java
Normal file
138
test/jdk/java/lang/Character/TestEmojiProperties.java
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8303018
|
||||
* @summary Check j.l.Character.isEmoji/isEmojiPresentation/isEmojiModifier
|
||||
* isEmojiModifierBase/isEmojiComponent/isExtendedPictographic
|
||||
* @library /lib/testlibrary/java/lang
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.lang.Character.MAX_CODE_POINT;
|
||||
import static java.lang.Character.MIN_CODE_POINT;
|
||||
import static java.lang.Character.isEmoji;
|
||||
import static java.lang.Character.isEmojiPresentation;
|
||||
import static java.lang.Character.isEmojiModifier;
|
||||
import static java.lang.Character.isEmojiModifierBase;
|
||||
import static java.lang.Character.isEmojiComponent;
|
||||
import static java.lang.Character.isExtendedPictographic;
|
||||
|
||||
public class TestEmojiProperties {
|
||||
// Masks representing Emoji properties (16-bit `B` table masks in
|
||||
// CharacterData.java)
|
||||
private static final int EMOJI = 0x0040;
|
||||
private static final int EMOJI_PRESENTATION = 0x0080;
|
||||
private static final int EMOJI_MODIFIER = 0x0100;
|
||||
private static final int EMOJI_MODIFIER_BASE = 0x0200;
|
||||
private static final int EMOJI_COMPONENT = 0x0400;
|
||||
private static final int EXTENDED_PICTOGRAPHIC = 0x0800;
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
var emojiProps = Files.readAllLines(UCDFiles.EMOJI_DATA).stream()
|
||||
.map(line -> line.split("#", 2)[0])
|
||||
.filter(Predicate.not(String::isBlank))
|
||||
.map(line -> line.split("[ \t]*;[ \t]*", 2))
|
||||
.flatMap(map -> {
|
||||
var range = map[0].split("\\.\\.", 2);
|
||||
var start = Integer.valueOf(range[0], 16);
|
||||
return range.length == 1 ?
|
||||
Stream.of(new AbstractMap.SimpleEntry<>(start, convertType(map[1].trim()))) :
|
||||
IntStream.rangeClosed(start,
|
||||
Integer.valueOf(range[1], 16))
|
||||
.mapToObj(cp -> new AbstractMap.SimpleEntry<>(cp, convertType(map[1].trim())));
|
||||
})
|
||||
.collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue, (v1, v2) -> v1 | v2));
|
||||
|
||||
final var fails = new Integer[1];
|
||||
fails[0] = 0;
|
||||
IntStream.rangeClosed(MIN_CODE_POINT, MAX_CODE_POINT).forEach(cp -> {
|
||||
var props = emojiProps.getOrDefault(cp, 0L);
|
||||
if ((props & EMOJI) != 0 ^ isEmoji(cp)) {
|
||||
System.err.printf("""
|
||||
isEmoji(0x%x) failed. Returned: %b
|
||||
""", cp, isEmoji(cp));
|
||||
fails[0] ++;
|
||||
}
|
||||
|
||||
if ((props & EMOJI_PRESENTATION) != 0 ^ isEmojiPresentation(cp)) {
|
||||
System.err.printf("""
|
||||
isEmojiPresentation(0x%x) failed. Returned: %b
|
||||
""", cp, isEmojiPresentation(cp));
|
||||
fails[0] ++;
|
||||
}
|
||||
|
||||
if ((props & EMOJI_MODIFIER) != 0 ^ isEmojiModifier(cp)) {
|
||||
System.err.printf("""
|
||||
isEmojiModifier(0x%x) failed. Returned: %b
|
||||
""", cp, isEmojiModifier(cp));
|
||||
fails[0] ++;
|
||||
}
|
||||
|
||||
if ((props & EMOJI_MODIFIER_BASE) != 0 ^ isEmojiModifierBase(cp)) {
|
||||
System.err.printf("""
|
||||
isEmojiModifierBase(0x%x) failed. Returned: %b
|
||||
""", cp, isEmojiModifierBase(cp));
|
||||
fails[0] ++;
|
||||
}
|
||||
|
||||
if ((props & EMOJI_COMPONENT) != 0 ^ isEmojiComponent(cp)) {
|
||||
System.err.printf("""
|
||||
isEmojiComponent(0x%x) failed. Returned: %b
|
||||
""", cp, isEmojiComponent(cp));
|
||||
fails[0] ++;
|
||||
}
|
||||
|
||||
if ((props & EXTENDED_PICTOGRAPHIC) != 0 ^ isExtendedPictographic(cp)) {
|
||||
System.err.printf("""
|
||||
isExtendedPictographic(0x%x) failed. Returned: %b
|
||||
""", cp, isExtendedPictographic(cp));
|
||||
fails[0] ++;
|
||||
}
|
||||
});
|
||||
if (fails[0] != 0) {
|
||||
throw new RuntimeException("TestEmojiProperties failed=" + fails);
|
||||
}
|
||||
}
|
||||
|
||||
private static long convertType(String type) {
|
||||
return switch (type) {
|
||||
case "Emoji" -> EMOJI;
|
||||
case "Emoji_Presentation" -> EMOJI_PRESENTATION;
|
||||
case "Emoji_Modifier" -> EMOJI_MODIFIER;
|
||||
case "Emoji_Modifier_Base" -> EMOJI_MODIFIER_BASE;
|
||||
case "Emoji_Component" -> EMOJI_COMPONENT;
|
||||
case "Extended_Pictographic" -> EXTENDED_PICTOGRAPHIC;
|
||||
default -> throw new InternalError();
|
||||
};
|
||||
}
|
||||
}
|
||||
97
test/jdk/java/lang/Character/TestNegativeCodepoint.java
Normal file
97
test/jdk/java/lang/Character/TestNegativeCodepoint.java
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4899380
|
||||
* @summary Character.is<Property>(int codePoint) methods should return false
|
||||
* for negative codepoint values. The to<CaseMap> methods should return
|
||||
* the original codePoint for invalid codePoint ranges.
|
||||
* @author John O'Conner
|
||||
*/
|
||||
|
||||
public class TestNegativeCodepoint {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
int[] invalidCodePoints = { -1, -'a', 0x110000};
|
||||
for (int x = 0; x < invalidCodePoints.length; ++x) {
|
||||
int cp = invalidCodePoints[x];
|
||||
|
||||
System.out.println("Testing codepoint: " + cp);
|
||||
// test all of the is<Property> methods
|
||||
if (Character.isLowerCase(cp) ||
|
||||
Character.isUpperCase(cp) ||
|
||||
Character.isTitleCase(cp) ||
|
||||
Character.isISOControl(cp) ||
|
||||
Character.isLetterOrDigit(cp) ||
|
||||
Character.isLetter(cp) ||
|
||||
Character.isDigit(cp) ||
|
||||
Character.isDefined(cp) ||
|
||||
Character.isJavaIdentifierStart(cp) ||
|
||||
Character.isJavaIdentifierPart(cp) ||
|
||||
Character.isUnicodeIdentifierStart(cp) ||
|
||||
Character.isUnicodeIdentifierPart(cp) ||
|
||||
Character.isIdentifierIgnorable(cp) ||
|
||||
Character.isSpaceChar(cp) ||
|
||||
Character.isWhitespace(cp) ||
|
||||
Character.isMirrored(cp) ||
|
||||
|
||||
// test the case mappings
|
||||
Character.toLowerCase(cp) != cp ||
|
||||
Character.toUpperCase(cp) != cp ||
|
||||
Character.toTitleCase(cp) != cp ||
|
||||
|
||||
// test directionality of invalid codepoints
|
||||
Character.getDirectionality(cp) != Character.DIRECTIONALITY_UNDEFINED ||
|
||||
|
||||
// test type
|
||||
Character.getType(cp) != Character.UNASSIGNED ||
|
||||
|
||||
// test numeric and digit values
|
||||
Character.getNumericValue(cp) != -1 ||
|
||||
Character.digit(cp, 10) != -1 ) {
|
||||
|
||||
System.out.println("Failed.");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
// test block value
|
||||
Character.UnicodeBlock block = null;
|
||||
try {
|
||||
block = Character.UnicodeBlock.of(cp);
|
||||
// if we haven't already thrown an exception because of the illegal
|
||||
// arguments, then we need to throw one because of an error in the of() method
|
||||
System.out.println("Failed.");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
catch(IllegalArgumentException e) {
|
||||
// Since we're testing illegal values, we
|
||||
// expect to land here every time. If not,
|
||||
// our test has failed
|
||||
}
|
||||
|
||||
}
|
||||
System.out.println("Passed.");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4427146
|
||||
* @summary Undefined char values should have DIRECTIONALITY_UNDEFINED.
|
||||
* @author John O'Conner
|
||||
*/
|
||||
|
||||
public class TestUndefinedDirectionality {
|
||||
|
||||
public static void main(String[] args) {
|
||||
int failures = 0;
|
||||
for (int ch=0x0000;ch <= 0xFFFF; ch++) {
|
||||
if (!Character.isDefined((char)ch)) {
|
||||
byte direction = Character.getDirectionality((char)ch);
|
||||
if (direction != Character.DIRECTIONALITY_UNDEFINED) {
|
||||
System.err.println("Fail: \\u" + Integer.toString(ch, 16));
|
||||
failures++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (failures != 0) {
|
||||
throw new RuntimeException("TestUndefinedDirectionality: failed.");
|
||||
} else {
|
||||
System.out.println("Passed.");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4453719
|
||||
* @author John O'Conner
|
||||
* @summary Undefined char values cannot be Java identifier starts or parts.
|
||||
*/
|
||||
|
||||
public class TestUndefinedIdentifierStartPart {
|
||||
static int endValue = 0xFFFF;
|
||||
|
||||
public static void main(String[] args) {
|
||||
for (int ch=0x0000; ch <= endValue; ch++) {
|
||||
if (!Character.isDefined((char)ch) &&
|
||||
(Character.isJavaIdentifierStart((char)ch) ||
|
||||
Character.isJavaIdentifierPart((char)ch) ||
|
||||
Character.isUnicodeIdentifierStart((char)ch) ||
|
||||
Character.isUnicodeIdentifierPart((char)ch))) {
|
||||
throw new RuntimeException("Char value " + Integer.toHexString((char)ch));
|
||||
}
|
||||
}
|
||||
System.out.println("Passed");
|
||||
}
|
||||
}
|
||||
46
test/jdk/java/lang/Character/TestUndefinedIgnorable.java
Normal file
46
test/jdk/java/lang/Character/TestUndefinedIgnorable.java
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4453719
|
||||
* @author John O'Conner
|
||||
* @summary Undefined character values should not be ignorable identifiers.
|
||||
*/
|
||||
|
||||
public class TestUndefinedIgnorable {
|
||||
static int endValue = 0xFFFF;
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
for (int ch=0x0000; ch <= endValue; ch++) {
|
||||
if (!Character.isDefined((char)ch) &&
|
||||
Character.isIdentifierIgnorable((char)ch)) {
|
||||
throw new RuntimeException("Char value " + Integer.toHexString((char)ch));
|
||||
}
|
||||
}
|
||||
System.out.println("Passed.");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
42
test/jdk/java/lang/Character/TestUndefinedMirrored.java
Normal file
42
test/jdk/java/lang/Character/TestUndefinedMirrored.java
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4453720
|
||||
* @author John O'Conner
|
||||
* @summary Undefined char values should not have mirrored property.
|
||||
*/
|
||||
|
||||
public class TestUndefinedMirrored {
|
||||
static int endValue = 0xFFFF;
|
||||
|
||||
public static void main(String[] args) {
|
||||
for (int ch = 0x0000; ch <= endValue; ch++) {
|
||||
if (!Character.isDefined((char)ch) && Character.isMirrored((char)ch)) {
|
||||
throw new RuntimeException("Char value " + Integer.toHexString((char)ch));
|
||||
}
|
||||
}
|
||||
System.out.println("Passed.");
|
||||
}
|
||||
}
|
||||
46
test/jdk/java/lang/Character/TestUndefinedNumeric.java
Normal file
46
test/jdk/java/lang/Character/TestUndefinedNumeric.java
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4453721
|
||||
* @author John O'Conner
|
||||
* @summary Unassigned char values should have no numeric properties.
|
||||
*/
|
||||
|
||||
public class TestUndefinedNumeric {
|
||||
static int endValue = 0xFFFF;
|
||||
|
||||
public static void main(String[] args) {
|
||||
for (int ch = 0x0000; ch <= 0xFFFF; ch++) {
|
||||
if (!Character.isDefined((char)ch) &&
|
||||
Character.getNumericValue((char)ch) != -1) {
|
||||
throw new RuntimeException("Char value " + Integer.toHexString((char)ch));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
System.out.println("Passed.");
|
||||
|
||||
}
|
||||
}
|
||||
42
test/jdk/java/lang/Character/TestUndefinedTitleCase.java
Normal file
42
test/jdk/java/lang/Character/TestUndefinedTitleCase.java
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @author John O'Conner
|
||||
* @bug 4453730
|
||||
* @summary Undefined character code points do not have titlecase mappings. The
|
||||
* toTitleCase method should return the argument code value.
|
||||
*/
|
||||
public class TestUndefinedTitleCase {
|
||||
static int endCharValue = 0xFFFF;
|
||||
|
||||
public static void main(String[] args) {
|
||||
for(int ch=0x0000; ch <= endCharValue; ch++) {
|
||||
if (!Character.isDefined((char)ch) && Character.toTitleCase((char)ch) != (char)ch) {
|
||||
throw new RuntimeException("Char value " + Integer.toHexString((char)ch));
|
||||
}
|
||||
}
|
||||
System.out.println("Passed");
|
||||
}
|
||||
}
|
||||
46
test/jdk/java/lang/Character/TestWhiteSpace.java
Normal file
46
test/jdk/java/lang/Character/TestWhiteSpace.java
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4427146
|
||||
* @summary Some char values that are Unicode spaces are non-breaking. These
|
||||
* should not be Java whitespaces.
|
||||
* @author John O'Conner
|
||||
*/
|
||||
|
||||
public class TestWhiteSpace {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// These values should NOT be whitespace
|
||||
char[] whiteSpace = {'\u00A0', '\u2007', '\u202F'};
|
||||
|
||||
for (int x=0;x<whiteSpace.length;x++) {
|
||||
if (Character.isWhitespace(whiteSpace[x])) {
|
||||
throw new RuntimeException("Invalid whitespace: \\u" +
|
||||
Integer.toString((int)whiteSpace[x], 16));
|
||||
}
|
||||
}
|
||||
System.out.println("Passed.");
|
||||
}
|
||||
}
|
||||
346
test/jdk/java/lang/Character/UnicodeBlock/CheckBlocks.java
Normal file
346
test/jdk/java/lang/Character/UnicodeBlock/CheckBlocks.java
Normal file
|
|
@ -0,0 +1,346 @@
|
|||
/*
|
||||
* Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4830803 4886934 6565620 6959267 7070436 7198195 8032446 8072600 8202771
|
||||
* 8221431
|
||||
* @summary Check that the UnicodeBlock forName() method works as expected
|
||||
* and block ranges are correct for all Unicode characters.
|
||||
* @library /lib/testlibrary/java/lang
|
||||
* @run main CheckBlocks
|
||||
* @author John O'Conner
|
||||
*/
|
||||
|
||||
import java.lang.Character.UnicodeBlock;
|
||||
import java.lang.reflect.Field;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
|
||||
public class CheckBlocks {
|
||||
|
||||
static boolean err = false;
|
||||
static Class<?> clazzUnicodeBlock;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
generateBlockList();
|
||||
|
||||
try {
|
||||
clazzUnicodeBlock = Class.forName("java.lang.Character$UnicodeBlock");
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException("Class.forName(\"java.lang.Character$UnicodeBlock\") failed.");
|
||||
}
|
||||
|
||||
for (Block blk : blocks) {
|
||||
test4830803_1(blk);
|
||||
test4830803_2();
|
||||
test4886934(blk);
|
||||
}
|
||||
|
||||
test8202771();
|
||||
|
||||
if (err) {
|
||||
throw new RuntimeException("Failed");
|
||||
} else {
|
||||
System.out.println("Passed");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the UnicodeBlock forName() method works as expected.
|
||||
*/
|
||||
private static void test4830803_1(Block blk) throws Exception {
|
||||
|
||||
/*
|
||||
* Try 3 forms of block name in the forName() method. Each form should
|
||||
* produce the same expected block.
|
||||
*/
|
||||
String blkName = blk.getName();
|
||||
|
||||
// For backward compatibility
|
||||
switch (blkName) {
|
||||
case "COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS":
|
||||
blkName = "COMBINING_MARKS_FOR_SYMBOLS";
|
||||
System.out.println("*** COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS"
|
||||
+ " is replaced with COMBINING_MARKS_FOR_SYMBOLS"
|
||||
+ " for backward compatibility.");
|
||||
break;
|
||||
case "GREEK_AND_COPTIC":
|
||||
blkName = "GREEK";
|
||||
System.out.println("*** GREEK_AND_COPTIC is replaced with GREEK"
|
||||
+ " for backward compatibility.");
|
||||
break;
|
||||
case "CYRILLIC_SUPPLEMENT":
|
||||
blkName = "CYRILLIC_SUPPLEMENTARY";
|
||||
System.out.println("*** CYRILLIC_SUPPLEMENT is replaced with"
|
||||
+ " CYRILLIC_SUPPLEMENTARY for backward compatibility.");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
String expectedBlock = null;
|
||||
try {
|
||||
expectedBlock = clazzUnicodeBlock.getField(blkName).getName();
|
||||
} catch (NoSuchFieldException | SecurityException e) {
|
||||
System.err.println("Error: " + blkName + " was not found.");
|
||||
err = true;
|
||||
return;
|
||||
}
|
||||
|
||||
String canonicalBlockName = blk.getOriginalName();
|
||||
String idBlockName = expectedBlock;
|
||||
String regexBlockName = toRegExString(canonicalBlockName);
|
||||
|
||||
if (regexBlockName == null) {
|
||||
System.err.println("Error: Block name which was processed with regex was null.");
|
||||
err = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!expectedBlock.equals(UnicodeBlock.forName(canonicalBlockName).toString())) {
|
||||
System.err.println("Error #1: UnicodeBlock.forName(\"" +
|
||||
canonicalBlockName + "\") returned wrong value.\n\tGot: " +
|
||||
UnicodeBlock.forName(canonicalBlockName) +
|
||||
"\n\tExpected: " + expectedBlock);
|
||||
err = true;
|
||||
}
|
||||
|
||||
if (!expectedBlock.equals(UnicodeBlock.forName(idBlockName).toString())) {
|
||||
System.err.println("Error #2: UnicodeBlock.forName(\"" +
|
||||
idBlockName + "\") returned wrong value.\n\tGot: " +
|
||||
UnicodeBlock.forName(idBlockName) +
|
||||
"\n\tExpected: " + expectedBlock);
|
||||
err = true;
|
||||
}
|
||||
|
||||
if (!expectedBlock.equals(UnicodeBlock.forName(regexBlockName).toString())) {
|
||||
System.err.println("Error #3: UnicodeBlock.forName(\"" +
|
||||
regexBlockName + "\") returned wrong value.\n\tGot: " +
|
||||
UnicodeBlock.forName(regexBlockName) +
|
||||
"\n\tExpected: " + expectedBlock);
|
||||
err = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* now try a bad block name. This should produce an IAE.
|
||||
*/
|
||||
private static void test4830803_2() {
|
||||
boolean threwExpected = false;
|
||||
|
||||
try {
|
||||
UnicodeBlock block = UnicodeBlock.forName("notdefined");
|
||||
}
|
||||
catch(IllegalArgumentException e) {
|
||||
threwExpected = true;
|
||||
}
|
||||
|
||||
if (threwExpected == false) {
|
||||
System.err.println("Error: UnicodeBlock.forName(\"notdefined\") should throw IllegalArgumentException.");
|
||||
err = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the argument to a block name form used by the regex package.
|
||||
* That is, remove all spaces.
|
||||
*/
|
||||
private static String toRegExString(String str) {
|
||||
String[] tokens = null;
|
||||
StringBuilder retStr = new StringBuilder();
|
||||
try {
|
||||
tokens = str.split(" ");
|
||||
}
|
||||
catch(java.util.regex.PatternSyntaxException e) {
|
||||
return null;
|
||||
}
|
||||
for(int x=0; x < tokens.length; ++x) {
|
||||
retStr.append(tokens[x]);
|
||||
}
|
||||
return retStr.toString();
|
||||
}
|
||||
|
||||
private static void test4886934(Block blk) {
|
||||
String blkName = blk.getName();
|
||||
String blkOrigName = blk.getOriginalName();
|
||||
UnicodeBlock block;
|
||||
String blockName;
|
||||
|
||||
// For backward compatibility
|
||||
switch (blkName) {
|
||||
case "COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS":
|
||||
blkName = "COMBINING_MARKS_FOR_SYMBOLS";
|
||||
System.out.println("*** COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS"
|
||||
+ " is replaced with COMBINING_MARKS_FOR_SYMBOLS"
|
||||
+ " for backward compatibility.");
|
||||
break;
|
||||
case "GREEK_AND_COPTIC":
|
||||
blkName = "GREEK";
|
||||
System.out.println("*** GREEK_AND_COPTIC is replaced with GREEK"
|
||||
+ " for backward compatibility.");
|
||||
break;
|
||||
case "CYRILLIC_SUPPLEMENT":
|
||||
blkName = "CYRILLIC_SUPPLEMENTARY";
|
||||
System.out.println("*** CYRILLIC_SUPPLEMENT is replaced with"
|
||||
+ " CYRILLIC_SUPPLEMENTARY for backward compatibility.");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (int ch = blk.getBegin(); ch <= blk.getEnd(); ch++) {
|
||||
block = UnicodeBlock.of(ch);
|
||||
if (block == null) {
|
||||
System.err.println("Error: The block for " + blkName
|
||||
+ " is missing. Please check java.lang.Character.UnicodeBlock.");
|
||||
err = true;
|
||||
break;
|
||||
}
|
||||
blockName = block.toString();
|
||||
if (!blockName.equals(blkName)) {
|
||||
System.err.println("Error: Character(0x"
|
||||
+ Integer.toHexString(ch).toUpperCase()
|
||||
+ ") should be in \"" + blkName + "\" block "
|
||||
+ "(Block name is \"" + blkOrigName + "\")"
|
||||
+ " but found in \"" + blockName + "\" block.");
|
||||
err = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if every Field of Character.UnicodeBlock is a valid Unicode Block.
|
||||
*/
|
||||
private static void test8202771() {
|
||||
Field[] fields = clazzUnicodeBlock.getFields();
|
||||
|
||||
for (Field f : fields) {
|
||||
// Handle Deprecated field "SURROGATES_AREA".
|
||||
if (f.getAnnotation(Deprecated.class) != null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String blkName = f.getName();
|
||||
switch (blkName) {
|
||||
case "COMBINING_MARKS_FOR_SYMBOLS":
|
||||
validateBlock("COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS");
|
||||
break;
|
||||
case "GREEK":
|
||||
validateBlock("GREEK_AND_COPTIC");
|
||||
break;
|
||||
case "CYRILLIC_SUPPLEMENTARY":
|
||||
validateBlock("CYRILLIC_SUPPLEMENT");
|
||||
break;
|
||||
default:
|
||||
validateBlock(blkName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void validateBlock(String blkName) {
|
||||
for (Block block : blocks) {
|
||||
String blockName = block.getName();
|
||||
if (blockName.equals(blkName)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
err = true;
|
||||
System.err.println(blkName + " is not a valid Unicode Block.");
|
||||
}
|
||||
|
||||
// List of all Unicode blocks, their start, and end codepoints.
|
||||
public static HashSet<Block> blocks = new HashSet<>();
|
||||
|
||||
private static void generateBlockList() throws Exception {
|
||||
File blockData = UCDFiles.BLOCKS.toFile();
|
||||
try (BufferedReader f = new BufferedReader(new FileReader(blockData))) {
|
||||
String line;
|
||||
while ((line = f.readLine()) != null) {
|
||||
if (line.length() == 0 || line.charAt(0) == '#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
int index1 = line.indexOf('.');
|
||||
int begin = Integer.parseInt(line.substring(0, index1), 16);
|
||||
int index2 = line.indexOf(';');
|
||||
int end = Integer.parseInt(line.substring(index1 + 2, index2), 16);
|
||||
String name = line.substring(index2 + 1).trim();
|
||||
|
||||
System.out.println(" Adding a Block(" + Integer.toHexString(begin) + ", " + Integer.toHexString(end)
|
||||
+ ", " + name + ")");
|
||||
blocks.add(new Block(begin, end, name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Block {
|
||||
|
||||
public Block() {
|
||||
blockBegin = 0;
|
||||
blockEnd = 0;
|
||||
blockName = null;
|
||||
}
|
||||
|
||||
public Block(int begin, int end, String name) {
|
||||
blockBegin = begin;
|
||||
blockEnd = end;
|
||||
blockName = name.replaceAll("[ -]", "_").toUpperCase(Locale.ENGLISH);
|
||||
originalBlockName = name;
|
||||
}
|
||||
|
||||
public int getBegin() {
|
||||
return blockBegin;
|
||||
}
|
||||
|
||||
public int getEnd() {
|
||||
return blockEnd;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return blockName;
|
||||
}
|
||||
|
||||
public String getOriginalName() {
|
||||
return originalBlockName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null) return false;
|
||||
if (!(obj instanceof Block)) return false;
|
||||
|
||||
Block other = (Block)obj;
|
||||
return other.blockBegin == blockBegin &&
|
||||
other.blockEnd == blockEnd &&
|
||||
other.blockName.equals(blockName) &&
|
||||
other.originalBlockName.equals(originalBlockName);
|
||||
}
|
||||
int blockBegin, blockEnd;
|
||||
String blockName, originalBlockName;
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8080535 8191410 8215194 8221431 8239383 8268081 8283465 8284856
|
||||
* @summary Check if the NUM_ENTITIES field reflects the correct number
|
||||
* of Character.UnicodeBlock constants. Also checks the size of
|
||||
* Character.UnicodeScript's "aliases" map.
|
||||
* @modules java.base/java.lang:open
|
||||
* @run junit NumberEntities
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class NumberEntities {
|
||||
@Test
|
||||
public void test_UnicodeBlock_NumberEntities() throws Throwable {
|
||||
// The number of entries in Character.UnicodeBlock.map.
|
||||
// See src/java.base/share/classes/java/lang/Character.java
|
||||
Field n = Character.UnicodeBlock.class.getDeclaredField("NUM_ENTITIES");
|
||||
Field m = Character.UnicodeBlock.class.getDeclaredField("map");
|
||||
n.setAccessible(true);
|
||||
m.setAccessible(true);
|
||||
assertEquals(n.getInt(null), ((Map)m.get(null)).size());
|
||||
}
|
||||
@Test
|
||||
public void test_UnicodeScript_aliases() throws Throwable {
|
||||
// The number of entries in Character.UnicodeScript.aliases.
|
||||
// See src/java.base/share/classes/java/lang/Character.java
|
||||
Field aliases = Character.UnicodeScript.class.getDeclaredField("aliases");
|
||||
aliases.setAccessible(true);
|
||||
assertEquals(Character.UnicodeScript.UNKNOWN.ordinal() + 1, ((Map)aliases.get(null)).size());
|
||||
}
|
||||
}
|
||||
175
test/jdk/java/lang/Character/UnicodeCasingTest.java
Normal file
175
test/jdk/java/lang/Character/UnicodeCasingTest.java
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4397357 6565620 6959267 8032446 8072600 8221431
|
||||
* @summary Confirm normal case mappings are handled correctly.
|
||||
* @library /lib/testlibrary/java/lang
|
||||
* @run main/timeout=200 UnicodeCasingTest
|
||||
*/
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
public class UnicodeCasingTest {
|
||||
|
||||
private static boolean err = false;
|
||||
|
||||
// Locales which are used for testing
|
||||
private static List<Locale> locales = new ArrayList<>();
|
||||
static {
|
||||
locales.add(Locale.of("az"));
|
||||
locales.addAll(java.util.Arrays.asList(Locale.getAvailableLocales()));
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
UnicodeCasingTest specialCasingTest = new UnicodeCasingTest();
|
||||
specialCasingTest.test();
|
||||
}
|
||||
|
||||
private void test() {
|
||||
Locale defaultLocale = Locale.getDefault();
|
||||
|
||||
BufferedReader in = null;
|
||||
|
||||
try {
|
||||
File file = UCDFiles.UNICODE_DATA.toFile();
|
||||
|
||||
int locale_num = locales.size();
|
||||
for (int l = 0; l < locale_num; l++) {
|
||||
Locale locale = locales.get(l);
|
||||
Locale.setDefault(locale);
|
||||
System.out.println("Testing on " + locale + " locale....");
|
||||
|
||||
in = new BufferedReader(new FileReader(file));
|
||||
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
if (line.length() == 0 || line.charAt(0) == '#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
test(line);
|
||||
}
|
||||
|
||||
in.close();
|
||||
in = null;
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
err = true;
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
}
|
||||
catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
Locale.setDefault(defaultLocale);
|
||||
|
||||
if (err) {
|
||||
throw new RuntimeException("UnicodeCasingTest failed.");
|
||||
} else {
|
||||
System.out.println("UnicodeCasingTest passed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void test(String line) {
|
||||
String[] fields = line.split(";", 15);
|
||||
int orig = convert(fields[0]);
|
||||
|
||||
if (fields[12].length() != 0) {
|
||||
testUpperCase(orig, convert(fields[12]));
|
||||
} else {
|
||||
testUpperCase(orig, orig);
|
||||
}
|
||||
|
||||
if (fields[13].length() != 0) {
|
||||
testLowerCase(orig, convert(fields[13]));
|
||||
} else {
|
||||
testLowerCase(orig, orig);
|
||||
}
|
||||
|
||||
if (fields[14].length() != 0) {
|
||||
testTitleCase(orig, convert(fields[14]));
|
||||
} else {
|
||||
testTitleCase(orig, orig);
|
||||
}
|
||||
}
|
||||
|
||||
private void testUpperCase(int orig, int expected) {
|
||||
int got = Character.toUpperCase(orig);
|
||||
|
||||
if (expected != got) {
|
||||
err = true;
|
||||
System.err.println("toUpperCase(" +
|
||||
") failed.\n\tOriginal: " + toString(orig) +
|
||||
"\n\tGot: " + toString(got) +
|
||||
"\n\tExpected: " + toString(expected));
|
||||
}
|
||||
}
|
||||
|
||||
private void testLowerCase(int orig, int expected) {
|
||||
int got = Character.toLowerCase(orig);
|
||||
|
||||
if (expected != got) {
|
||||
err = true;
|
||||
System.err.println("toLowerCase(" +
|
||||
") failed.\n\tOriginal: " + toString(orig) +
|
||||
"\n\tGot: " + toString(got) +
|
||||
"\n\tExpected: " + toString(expected));
|
||||
}
|
||||
}
|
||||
|
||||
private void testTitleCase(int orig, int expected) {
|
||||
int got = Character.toTitleCase(orig);
|
||||
|
||||
if (expected != got) {
|
||||
err = true;
|
||||
System.err.println("toTitleCase(" +
|
||||
") failed.\n\tOriginal: " + toString(orig) +
|
||||
"\n\tGot: " + toString(got) +
|
||||
"\n\tExpected: " + toString(expected));
|
||||
}
|
||||
}
|
||||
|
||||
private int convert(String str) {
|
||||
return Integer.parseInt(str, 16);
|
||||
}
|
||||
|
||||
private String toString(int i) {
|
||||
return Integer.toHexString(i).toUpperCase();
|
||||
}
|
||||
|
||||
}
|
||||
754
test/jdk/java/lang/Character/UnicodeSpec.java
Normal file
754
test/jdk/java/lang/Character/UnicodeSpec.java
Normal file
|
|
@ -0,0 +1,754 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* The UnicodeSpec class provides a way to read in Unicode character
|
||||
* properties from a Unicode data file. One instance of class UnicodeSpec
|
||||
* holds a decoded version of one line of the data file. The file may
|
||||
* be obtained from www.unicode.org. The method readSpecFile returns an array
|
||||
* of UnicodeSpec objects.
|
||||
*
|
||||
* @author Guy Steele
|
||||
* @author John O'Conner
|
||||
*/
|
||||
|
||||
public class UnicodeSpec {
|
||||
|
||||
public UnicodeSpec() {
|
||||
this(0xffff);
|
||||
}
|
||||
|
||||
public UnicodeSpec(int codePoint) {
|
||||
this.codePoint = codePoint;
|
||||
generalCategory = UNASSIGNED;
|
||||
bidiCategory = DIRECTIONALITY_UNDEFINED;
|
||||
mirrored = false;
|
||||
titleMap = 0xFFFF;
|
||||
upperMap = 0xFFFF;
|
||||
lowerMap = 0xFFFF;
|
||||
decimalValue = -1;
|
||||
digitValue = -1;
|
||||
numericValue = "";
|
||||
oldName = null;
|
||||
comment = null;
|
||||
name = null;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer result = new StringBuffer(hex6(codePoint));
|
||||
if (getUpperMap() != 0xffff) {
|
||||
result.append(", upper=").append(hex6(upperMap));
|
||||
}
|
||||
if (getLowerMap() != 0xffff) {
|
||||
result.append(", lower=").append(hex6(lowerMap));
|
||||
}
|
||||
if (getTitleMap() != 0xffff) {
|
||||
result.append(", title=").append(hex6(titleMap));
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
static String hex4(int n) {
|
||||
String q = Long.toHexString(n & 0xFFFF).toUpperCase();
|
||||
return "0000".substring(Math.min(4, q.length())) + q;
|
||||
}
|
||||
|
||||
static String hex6(int n) {
|
||||
String str = Integer.toHexString(n & 0xFFFFFF).toUpperCase();
|
||||
return "000000".substring(Math.min(6, str.length())) + str;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given one line of a Unicode data file as a String, parse the line
|
||||
* and return a UnicodeSpec object that contains the same character information.
|
||||
*
|
||||
* @param s a line of the Unicode data file to be parsed
|
||||
* @return a UnicodeSpec object, or null if the parsing process failed for some reason
|
||||
*/
|
||||
public static UnicodeSpec parse(String s) {
|
||||
UnicodeSpec spec = null;
|
||||
String[] tokens = null;
|
||||
|
||||
try {
|
||||
tokens = tokenSeparator.split(s, REQUIRED_FIELDS);
|
||||
spec = new UnicodeSpec();
|
||||
spec.setCodePoint(parseCodePoint(tokens[FIELD_VALUE]));
|
||||
spec.setName(parseName(tokens[FIELD_NAME]));
|
||||
spec.setGeneralCategory(parseGeneralCategory(tokens[FIELD_CATEGORY]));
|
||||
spec.setBidiCategory(parseBidiCategory(tokens[FIELD_BIDI]));
|
||||
spec.setCombiningClass(parseCombiningClass(tokens[FIELD_CLASS]));
|
||||
spec.setDecomposition(parseDecomposition(tokens[FIELD_DECOMPOSITION]));
|
||||
spec.setDecimalValue(parseDecimalValue(tokens[FIELD_DECIMAL]));
|
||||
spec.setDigitValue(parseDigitValue(tokens[FIELD_DIGIT]));
|
||||
spec.setNumericValue(parseNumericValue(tokens[FIELD_NUMERIC]));
|
||||
spec.setMirrored(parseMirrored(tokens[FIELD_MIRRORED]));
|
||||
spec.setOldName(parseOldName(tokens[FIELD_OLDNAME]));
|
||||
spec.setComment(parseComment(tokens[FIELD_COMMENT]));
|
||||
spec.setUpperMap(parseUpperMap(tokens[FIELD_UPPERCASE]));
|
||||
spec.setLowerMap(parseLowerMap(tokens[FIELD_LOWERCASE]));
|
||||
spec.setTitleMap(parseTitleMap(tokens[FIELD_TITLECASE]));
|
||||
}
|
||||
catch(Exception e) {
|
||||
spec = null;
|
||||
System.out.println("Error parsing spec line.");
|
||||
}
|
||||
return spec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the codePoint attribute for a Unicode character. If the parse succeeds,
|
||||
* the codePoint field of this UnicodeSpec object is updated and false is returned.
|
||||
*
|
||||
* The codePoint attribute should be a four-digit hexadecimal integer.
|
||||
*
|
||||
* @param s the codePoint attribute extracted from a line of the Unicode data file
|
||||
* @return code point if successful
|
||||
* @exception NumberFormatException if unable to parse argument
|
||||
*/
|
||||
public static int parseCodePoint(String s) throws NumberFormatException {
|
||||
return Integer.parseInt(s, 16);
|
||||
}
|
||||
|
||||
public static String parseName(String s) throws Exception {
|
||||
if (s==null) throw new Exception("Cannot parse name.");
|
||||
return s;
|
||||
}
|
||||
|
||||
public static byte parseGeneralCategory(String s) throws Exception {
|
||||
byte category = GENERAL_CATEGORY_COUNT;
|
||||
|
||||
for (byte x=0; x<generalCategoryList.length; x++) {
|
||||
if (s.equals(generalCategoryList[x][SHORT])) {
|
||||
category = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (category >= GENERAL_CATEGORY_COUNT) {
|
||||
throw new Exception("Could not parse general category.");
|
||||
}
|
||||
return category;
|
||||
}
|
||||
|
||||
public static byte parseBidiCategory(String s) throws Exception {
|
||||
byte category = DIRECTIONALITY_CATEGORY_COUNT;
|
||||
|
||||
for (byte x=0; x<bidiCategoryList.length; x++) {
|
||||
if (s.equals(bidiCategoryList[x][SHORT])) {
|
||||
category = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (category >= DIRECTIONALITY_CATEGORY_COUNT) {
|
||||
throw new Exception("Could not parse bidi category.");
|
||||
}
|
||||
return category;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse the combining attribute for a Unicode character. If there is a combining
|
||||
* attribute and the parse succeeds, then the hasCombining field is set to true,
|
||||
* the combining field of this UnicodeSpec object is updated, and false is returned.
|
||||
* If the combining attribute is an empty string, the parse succeeds but the
|
||||
* hasCombining field is set to false. (and false is returned).
|
||||
*
|
||||
* The combining attribute, if any, should be a nonnegative decimal integer.
|
||||
*
|
||||
* @param s the combining attribute extracted from a line of the Unicode data file
|
||||
* @return the combining class value if any, -1 if property not defined
|
||||
* @exception Exception if can't parse the combining class
|
||||
*/
|
||||
|
||||
public static int parseCombiningClass(String s) throws Exception {
|
||||
int combining = -1;
|
||||
if (s.length()>0) {
|
||||
combining = Integer.parseInt(s, 10);
|
||||
}
|
||||
return combining;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the decomposition attribute for a Unicode character. If the parse succeeds,
|
||||
* the decomposition field of this UnicodeSpec object is updated and false is returned.
|
||||
*
|
||||
* The decomposition attribute is complicated; for now, it is treated as a string.
|
||||
*
|
||||
* @param s the decomposition attribute extracted from a line of the Unicode data file
|
||||
* @return true if the parse failed; otherwise false
|
||||
*/
|
||||
|
||||
public static String parseDecomposition(String s) throws Exception {
|
||||
if (s==null) throw new Exception("Cannot parse decomposition.");
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse the decimal value attribute for a Unicode character. If there is a decimal value
|
||||
* attribute and the parse succeeds, then the hasDecimalValue field is set to true,
|
||||
* the decimalValue field of this UnicodeSpec object is updated, and false is returned.
|
||||
* If the decimal value attribute is an empty string, the parse succeeds but the
|
||||
* hasDecimalValue field is set to false. (and false is returned).
|
||||
*
|
||||
* The decimal value attribute, if any, should be a nonnegative decimal integer.
|
||||
*
|
||||
* @param s the decimal value attribute extracted from a line of the Unicode data file
|
||||
* @return the decimal value as an int, -1 if no decimal value defined
|
||||
* @exception NumberFormatException if the parse fails
|
||||
*/
|
||||
public static int parseDecimalValue(String s) throws NumberFormatException {
|
||||
int value = -1;
|
||||
|
||||
if (s.length() > 0) {
|
||||
value = Integer.parseInt(s, 10);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the digit value attribute for a Unicode character. If there is a digit value
|
||||
* attribute and the parse succeeds, then the hasDigitValue field is set to true,
|
||||
* the digitValue field of this UnicodeSpec object is updated, and false is returned.
|
||||
* If the digit value attribute is an empty string, the parse succeeds but the
|
||||
* hasDigitValue field is set to false. (and false is returned).
|
||||
*
|
||||
* The digit value attribute, if any, should be a nonnegative decimal integer.
|
||||
*
|
||||
* @param s the digit value attribute extracted from a line of the Unicode data file
|
||||
* @return the digit value as an non-negative int, or -1 if no digit property defined
|
||||
* @exception NumberFormatException if the parse fails
|
||||
*/
|
||||
public static int parseDigitValue(String s) throws NumberFormatException {
|
||||
int value = -1;
|
||||
|
||||
if (s.length() > 0) {
|
||||
value = Integer.parseInt(s, 10);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public static String parseNumericValue(String s) throws Exception {
|
||||
if (s == null) throw new Exception("Cannot parse numeric value.");
|
||||
return s;
|
||||
}
|
||||
|
||||
public static String parseComment(String s) throws Exception {
|
||||
if (s == null) throw new Exception("Cannot parse comment.");
|
||||
return s;
|
||||
}
|
||||
|
||||
public static boolean parseMirrored(String s) throws Exception {
|
||||
boolean mirrored;
|
||||
if (s.length() == 1) {
|
||||
if (s.charAt(0) == 'Y') {mirrored = true;}
|
||||
else if (s.charAt(0) == 'N') {mirrored = false;}
|
||||
else {throw new Exception("Cannot parse mirrored property.");}
|
||||
}
|
||||
else { throw new Exception("Cannot parse mirrored property.");}
|
||||
return mirrored;
|
||||
}
|
||||
|
||||
public static String parseOldName(String s) throws Exception {
|
||||
if (s == null) throw new Exception("Cannot parse old name");
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the uppercase mapping attribute for a Unicode character. If there is a uppercase
|
||||
* mapping attribute and the parse succeeds, then the hasUpperMap field is set to true,
|
||||
* the upperMap field of this UnicodeSpec object is updated, and false is returned.
|
||||
* If the uppercase mapping attribute is an empty string, the parse succeeds but the
|
||||
* hasUpperMap field is set to false. (and false is returned).
|
||||
*
|
||||
* The uppercase mapping attribute should be a four-digit hexadecimal integer.
|
||||
*
|
||||
* @param s the uppercase mapping attribute extracted from a line of the Unicode data file
|
||||
* @return uppercase char if defined, \uffff otherwise
|
||||
* @exception NumberFormatException if parse fails
|
||||
*/
|
||||
public static int parseUpperMap(String s) throws NumberFormatException {
|
||||
int upperCase = 0xFFFF;
|
||||
|
||||
if (s.length() >= 4) {
|
||||
upperCase = Integer.parseInt(s, 16);
|
||||
}
|
||||
else if (s.length() != 0) {
|
||||
throw new NumberFormatException();
|
||||
}
|
||||
return upperCase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the lowercase mapping attribute for a Unicode character. If there is a lowercase
|
||||
* mapping attribute and the parse succeeds, then the hasLowerMap field is set to true,
|
||||
* the lowerMap field of this UnicodeSpec object is updated, and false is returned.
|
||||
* If the lowercase mapping attribute is an empty string, the parse succeeds but the
|
||||
* hasLowerMap field is set to false. (and false is returned).
|
||||
*
|
||||
* The lowercase mapping attribute should be a four-digit hexadecimal integer.
|
||||
*
|
||||
* @param s the lowercase mapping attribute extracted from a line of the Unicode data file
|
||||
* @return lowercase char mapping if defined, \uFFFF otherwise
|
||||
* @exception NumberFormatException if parse fails
|
||||
*/
|
||||
public static int parseLowerMap(String s) throws NumberFormatException {
|
||||
int lowerCase = 0xFFFF;
|
||||
|
||||
if (s.length() >= 4) {
|
||||
lowerCase = Integer.parseInt(s, 16);
|
||||
}
|
||||
else if (s.length() != 0) {
|
||||
throw new NumberFormatException();
|
||||
}
|
||||
return lowerCase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the titlecase mapping attribute for a Unicode character. If there is a titlecase
|
||||
* mapping attribute and the parse succeeds, then the hasTitleMap field is set to true,
|
||||
* the titleMap field of this UnicodeSpec object is updated, and false is returned.
|
||||
* If the titlecase mapping attribute is an empty string, the parse succeeds but the
|
||||
* hasTitleMap field is set to false. (and false is returned).
|
||||
*
|
||||
* The titlecase mapping attribute should be a four-digit hexadecimal integer.
|
||||
*
|
||||
* @param s the titlecase mapping attribute extracted from a line of the Unicode data file
|
||||
* @return title case char mapping if defined, \uFFFF otherwise
|
||||
* @exception NumberFormatException if parse fails
|
||||
*/
|
||||
public static int parseTitleMap(String s) throws NumberFormatException {
|
||||
int titleCase = 0xFFFF;
|
||||
|
||||
if (s.length() >= 4) {
|
||||
titleCase = Integer.parseInt(s, 16);
|
||||
}
|
||||
else if (s.length() != 0) {
|
||||
throw new NumberFormatException();
|
||||
}
|
||||
return titleCase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read and parse a Unicode data file.
|
||||
*
|
||||
* @param file a file specifying the Unicode data file to be read
|
||||
* @return an array of UnicodeSpec objects, one for each line of the
|
||||
* Unicode data file that could be successfully parsed as
|
||||
* specifying Unicode character attributes
|
||||
*/
|
||||
|
||||
public static UnicodeSpec[] readSpecFile(File file, int plane) throws FileNotFoundException {
|
||||
ArrayList<UnicodeSpec> list = new ArrayList<>(3000);
|
||||
UnicodeSpec[] result = null;
|
||||
int count = 0;
|
||||
BufferedReader f = new BufferedReader(new FileReader(file));
|
||||
String line = null;
|
||||
loop:
|
||||
while(true) {
|
||||
try {
|
||||
line = f.readLine();
|
||||
}
|
||||
catch (IOException e) {
|
||||
break loop;
|
||||
}
|
||||
if (line == null) break loop;
|
||||
UnicodeSpec item = parse(line.trim());
|
||||
int specPlane = item.getCodePoint() >>> 16;
|
||||
if (specPlane < plane) continue;
|
||||
if (specPlane > plane) break;
|
||||
|
||||
if (item != null) {
|
||||
list.add(item);
|
||||
}
|
||||
}
|
||||
result = new UnicodeSpec[list.size()];
|
||||
list.toArray(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void setCodePoint(int value) {
|
||||
codePoint = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the code point in this Unicode specification
|
||||
* @return the char code point representing by the specification
|
||||
*/
|
||||
public int getCodePoint() {
|
||||
return codePoint;
|
||||
}
|
||||
|
||||
void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
void setGeneralCategory(byte category) {
|
||||
generalCategory = category;
|
||||
}
|
||||
|
||||
public byte getGeneralCategory() {
|
||||
return generalCategory;
|
||||
}
|
||||
|
||||
void setBidiCategory(byte category) {
|
||||
bidiCategory = category;
|
||||
}
|
||||
|
||||
public byte getBidiCategory() {
|
||||
return bidiCategory;
|
||||
}
|
||||
|
||||
void setCombiningClass(int combiningClass) {
|
||||
this.combiningClass = combiningClass;
|
||||
}
|
||||
|
||||
public int getCombiningClass() {
|
||||
return combiningClass;
|
||||
}
|
||||
|
||||
void setDecomposition(String decomposition) {
|
||||
this.decomposition = decomposition;
|
||||
}
|
||||
|
||||
public String getDecomposition() {
|
||||
return decomposition;
|
||||
}
|
||||
|
||||
void setDecimalValue(int value) {
|
||||
decimalValue = value;
|
||||
}
|
||||
|
||||
public int getDecimalValue() {
|
||||
return decimalValue;
|
||||
}
|
||||
|
||||
public boolean isDecimalValue() {
|
||||
return decimalValue != -1;
|
||||
}
|
||||
|
||||
void setDigitValue(int value) {
|
||||
digitValue = value;
|
||||
}
|
||||
|
||||
public int getDigitValue() {
|
||||
return digitValue;
|
||||
}
|
||||
|
||||
public boolean isDigitValue() {
|
||||
return digitValue != -1;
|
||||
}
|
||||
|
||||
void setNumericValue(String value) {
|
||||
numericValue = value;
|
||||
}
|
||||
|
||||
public String getNumericValue() {
|
||||
return numericValue;
|
||||
}
|
||||
|
||||
public boolean isNumericValue() {
|
||||
return numericValue.length() > 0;
|
||||
}
|
||||
|
||||
void setMirrored(boolean value) {
|
||||
mirrored = value;
|
||||
}
|
||||
|
||||
public boolean isMirrored() {
|
||||
return mirrored;
|
||||
}
|
||||
|
||||
void setOldName(String name) {
|
||||
oldName = name;
|
||||
}
|
||||
|
||||
public String getOldName() {
|
||||
return oldName;
|
||||
}
|
||||
|
||||
void setComment(String comment) {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
void setUpperMap(int ch) {
|
||||
upperMap = ch;
|
||||
};
|
||||
|
||||
public int getUpperMap() {
|
||||
return upperMap;
|
||||
}
|
||||
|
||||
public boolean hasUpperMap() {
|
||||
return upperMap != 0xffff;
|
||||
}
|
||||
|
||||
void setLowerMap(int ch) {
|
||||
lowerMap = ch;
|
||||
}
|
||||
|
||||
public int getLowerMap() {
|
||||
return lowerMap;
|
||||
}
|
||||
|
||||
public boolean hasLowerMap() {
|
||||
return lowerMap != 0xffff;
|
||||
}
|
||||
|
||||
void setTitleMap(int ch) {
|
||||
titleMap = ch;
|
||||
}
|
||||
|
||||
public int getTitleMap() {
|
||||
return titleMap;
|
||||
}
|
||||
|
||||
public boolean hasTitleMap() {
|
||||
return titleMap != 0xffff;
|
||||
}
|
||||
|
||||
int codePoint; // the characters UTF-32 code value
|
||||
String name; // the ASCII name
|
||||
byte generalCategory; // general category, available via Characte.getType()
|
||||
byte bidiCategory; // available via Character.getBidiType()
|
||||
int combiningClass; // not used in Character
|
||||
String decomposition; // not used in Character
|
||||
int decimalValue; // decimal digit value
|
||||
int digitValue; // not all digits are decimal
|
||||
String numericValue; // numeric value if digit or non-digit
|
||||
boolean mirrored; //
|
||||
String oldName;
|
||||
String comment;
|
||||
int upperMap;
|
||||
int lowerMap;
|
||||
int titleMap;
|
||||
|
||||
// this is the number of fields in one line of the UnicodeData.txt file
|
||||
// each field is separated by a semicolon (a token)
|
||||
static final int REQUIRED_FIELDS = 15;
|
||||
|
||||
/**
|
||||
* General category types
|
||||
* To preserve compatibility, these values cannot be changed
|
||||
*/
|
||||
public static final byte
|
||||
UNASSIGNED = 0, // Cn normative
|
||||
UPPERCASE_LETTER = 1, // Lu normative
|
||||
LOWERCASE_LETTER = 2, // Ll normative
|
||||
TITLECASE_LETTER = 3, // Lt normative
|
||||
MODIFIER_LETTER = 4, // Lm normative
|
||||
OTHER_LETTER = 5, // Lo normative
|
||||
NON_SPACING_MARK = 6, // Mn informative
|
||||
ENCLOSING_MARK = 7, // Me informative
|
||||
COMBINING_SPACING_MARK = 8, // Mc normative
|
||||
DECIMAL_DIGIT_NUMBER = 9, // Nd normative
|
||||
LETTER_NUMBER = 10, // Nl normative
|
||||
OTHER_NUMBER = 11, // No normative
|
||||
SPACE_SEPARATOR = 12, // Zs normative
|
||||
LINE_SEPARATOR = 13, // Zl normative
|
||||
PARAGRAPH_SEPARATOR = 14, // Zp normative
|
||||
CONTROL = 15, // Cc normative
|
||||
FORMAT = 16, // Cf normative
|
||||
// 17 is unused for no apparent reason,
|
||||
// but must preserve forward compatibility
|
||||
PRIVATE_USE = 18, // Co normative
|
||||
SURROGATE = 19, // Cs normative
|
||||
DASH_PUNCTUATION = 20, // Pd informative
|
||||
START_PUNCTUATION = 21, // Ps informative
|
||||
END_PUNCTUATION = 22, // Pe informative
|
||||
CONNECTOR_PUNCTUATION = 23, // Pc informative
|
||||
OTHER_PUNCTUATION = 24, // Po informative
|
||||
MATH_SYMBOL = 25, // Sm informative
|
||||
CURRENCY_SYMBOL = 26, // Sc informative
|
||||
MODIFIER_SYMBOL = 27, // Sk informative
|
||||
OTHER_SYMBOL = 28, // So informative
|
||||
INITIAL_QUOTE_PUNCTUATION = 29, // Pi informative
|
||||
FINAL_QUOTE_PUNCTUATION = 30, // Pf informative
|
||||
|
||||
// this value is only used in the character generation tool
|
||||
// it can change to accommodate the addition of new categories.
|
||||
GENERAL_CATEGORY_COUNT = 31; // sentinel value
|
||||
|
||||
static final byte SHORT = 0, LONG = 1;
|
||||
// general category type strings
|
||||
// NOTE: The order of this category array is dependent on the assignment of
|
||||
// category constants above. We want to access this array using constants above.
|
||||
// [][SHORT] is the SHORT name, [][LONG] is the LONG name
|
||||
static final String[][] generalCategoryList = {
|
||||
{"Cn", "UNASSIGNED"},
|
||||
{"Lu", "UPPERCASE_LETTER"},
|
||||
{"Ll", "LOWERCASE_LETTER"},
|
||||
{"Lt", "TITLECASE_LETTER"},
|
||||
{"Lm", "MODIFIER_LETTER"},
|
||||
{"Lo", "OTHER_LETTER"},
|
||||
{"Mn", "NON_SPACING_MARK"},
|
||||
{"Me", "ENCLOSING_MARK"},
|
||||
{"Mc", "COMBINING_SPACING_MARK"},
|
||||
{"Nd", "DECIMAL_DIGIT_NUMBER"},
|
||||
{"Nl", "LETTER_NUMBER"},
|
||||
{"No", "OTHER_NUMBER"},
|
||||
{"Zs", "SPACE_SEPARATOR"},
|
||||
{"Zl", "LINE_SEPARATOR"},
|
||||
{"Zp", "PARAGRAPH_SEPARATOR"},
|
||||
{"Cc", "CONTROL"},
|
||||
{"Cf", "FORMAT"},
|
||||
{"xx", "unused"},
|
||||
{"Co", "PRIVATE_USE"},
|
||||
{"Cs", "SURROGATE"},
|
||||
{"Pd", "DASH_PUNCTUATION"},
|
||||
{"Ps", "START_PUNCTUATION"},
|
||||
{"Pe", "END_PUNCTUATION"},
|
||||
{"Pc", "CONNECTOR_PUNCTUATION"},
|
||||
{"Po", "OTHER_PUNCTUATION"},
|
||||
{"Sm", "MATH_SYMBOL"},
|
||||
{"Sc", "CURRENCY_SYMBOL"},
|
||||
{"Sk", "MODIFIER_SYMBOL"},
|
||||
{"So", "OTHER_SYMBOL"},
|
||||
{"Pi", "INITIAL_QUOTE_PUNCTUATION"},
|
||||
{"Pf", "FINAL_QUOTE_PUNCTUATION"}
|
||||
};
|
||||
|
||||
/**
|
||||
* Bidirectional categories
|
||||
*/
|
||||
public static final byte
|
||||
DIRECTIONALITY_UNDEFINED = -1,
|
||||
// Strong category
|
||||
DIRECTIONALITY_LEFT_TO_RIGHT = 0, // L
|
||||
DIRECTIONALITY_RIGHT_TO_LEFT = 1, // R
|
||||
DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC = 2, // AL
|
||||
// Weak category
|
||||
DIRECTIONALITY_EUROPEAN_NUMBER = 3, // EN
|
||||
DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR = 4, // ES
|
||||
DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR = 5, // ET
|
||||
DIRECTIONALITY_ARABIC_NUMBER = 6, // AN
|
||||
DIRECTIONALITY_COMMON_NUMBER_SEPARATOR = 7, // CS
|
||||
DIRECTIONALITY_NONSPACING_MARK = 8, // NSM
|
||||
DIRECTIONALITY_BOUNDARY_NEUTRAL = 9, // BN
|
||||
// Neutral category
|
||||
DIRECTIONALITY_PARAGRAPH_SEPARATOR = 10, // B
|
||||
DIRECTIONALITY_SEGMENT_SEPARATOR = 11, // S
|
||||
DIRECTIONALITY_WHITESPACE = 12, // WS
|
||||
DIRECTIONALITY_OTHER_NEUTRALS = 13, // ON
|
||||
|
||||
DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING = 14, // LRE
|
||||
DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE = 15, // LRO
|
||||
DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING = 16, // RLE
|
||||
DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE = 17, // RLO
|
||||
DIRECTIONALITY_POP_DIRECTIONAL_FORMAT = 18, // PDF
|
||||
|
||||
DIRECTIONALITY_LEFT_TO_RIGHT_ISOLATE = 19, // LRI
|
||||
DIRECTIONALITY_RIGHT_TO_LEFT_ISOLATE = 20, // RLI
|
||||
DIRECTIONALITY_FIRST_STRONG_ISOLATE = 21, // FSI
|
||||
DIRECTIONALITY_POP_DIRECTIONAL_ISOLATE = 22, // PDI
|
||||
|
||||
DIRECTIONALITY_CATEGORY_COUNT = 23; // sentinel value
|
||||
|
||||
// If changes are made to the above bidi category assignments, this
|
||||
// list of bidi category names must be changed to keep their order in synch.
|
||||
// Access this list using the bidi category constants above.
|
||||
static final String[][] bidiCategoryList = {
|
||||
{"L", "DIRECTIONALITY_LEFT_TO_RIGHT"},
|
||||
{"R", "DIRECTIONALITY_RIGHT_TO_LEFT"},
|
||||
{"AL", "DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC"},
|
||||
{"EN", "DIRECTIONALITY_EUROPEAN_NUMBER"},
|
||||
{"ES", "DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR"},
|
||||
{"ET", "DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR"},
|
||||
{"AN", "DIRECTIONALITY_ARABIC_NUMBER"},
|
||||
{"CS", "DIRECTIONALITY_COMMON_NUMBER_SEPARATOR"},
|
||||
{"NSM", "DIRECTIONALITY_NONSPACING_MARK"},
|
||||
{"BN", "DIRECTIONALITY_BOUNDARY_NEUTRAL"},
|
||||
{"B", "DIRECTIONALITY_PARAGRAPH_SEPARATOR"},
|
||||
{"S", "DIRECTIONALITY_SEGMENT_SEPARATOR"},
|
||||
{"WS", "DIRECTIONALITY_WHITESPACE"},
|
||||
{"ON", "DIRECTIONALITY_OTHER_NEUTRALS"},
|
||||
{"LRE", "DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING"},
|
||||
{"LRO", "DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE"},
|
||||
{"RLE", "DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING"},
|
||||
{"RLO", "DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE"},
|
||||
{"PDF", "DIRECTIONALITY_POP_DIRECTIONAL_FORMAT"},
|
||||
{"LRI", "DIRECTIONALITY_LEFT_TO_RIGHT_ISOLATE"},
|
||||
{"RLI", "DIRECTIONALITY_RIGHT_TO_LEFT_ISOLATE"},
|
||||
{"FSI", "DIRECTIONALITY_FIRST_STRONG_ISOLATE"},
|
||||
{"PDI", "DIRECTIONALITY_POP_DIRECTIONAL_ISOLATE"},
|
||||
|
||||
};
|
||||
|
||||
// Unicode specification lines have fields in this order.
|
||||
static final byte
|
||||
FIELD_VALUE = 0,
|
||||
FIELD_NAME = 1,
|
||||
FIELD_CATEGORY = 2,
|
||||
FIELD_CLASS = 3,
|
||||
FIELD_BIDI = 4,
|
||||
FIELD_DECOMPOSITION = 5,
|
||||
FIELD_DECIMAL = 6,
|
||||
FIELD_DIGIT = 7,
|
||||
FIELD_NUMERIC = 8,
|
||||
FIELD_MIRRORED = 9,
|
||||
FIELD_OLDNAME = 10,
|
||||
FIELD_COMMENT = 11,
|
||||
FIELD_UPPERCASE = 12,
|
||||
FIELD_LOWERCASE = 13,
|
||||
FIELD_TITLECASE = 14;
|
||||
|
||||
static final Pattern tokenSeparator = Pattern.compile(";");
|
||||
|
||||
public static void main(String[] args) {
|
||||
UnicodeSpec[] spec = null;
|
||||
if (args.length == 2 ) {
|
||||
try {
|
||||
File file = new File(args[0]);
|
||||
int plane = Integer.parseInt(args[1]);
|
||||
spec = UnicodeSpec.readSpecFile(file, plane);
|
||||
System.out.println("UnicodeSpec[" + spec.length + "]:");
|
||||
for (int x=0; x<spec.length; x++) {
|
||||
System.out.println(spec[x].toString());
|
||||
}
|
||||
}
|
||||
catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
108
test/jdk/java/lang/Class/ArrayMethods.java
Normal file
108
test/jdk/java/lang/Class/ArrayMethods.java
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 4987375
|
||||
* @summary make sure clone() isn't reflected and that Cloneable and
|
||||
* Serializable are found
|
||||
*/
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ArrayMethods {
|
||||
public int failed = 0;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ArrayMethods m = new ArrayMethods();
|
||||
|
||||
m.testGetMethod();
|
||||
m.testGetMethods();
|
||||
m.testGetDeclaredMethod();
|
||||
m.testGetDeclaredMethods();
|
||||
m.testGetInterfaces();
|
||||
|
||||
if (m.failed != 0)
|
||||
throw new RuntimeException("Test failed, check log for details");
|
||||
}
|
||||
|
||||
public void testGetMethod() {
|
||||
try {
|
||||
Method m = new String[0].getClass().getMethod("clone", (Class<?>[])null);
|
||||
|
||||
failed++;
|
||||
System.out.println("getMethod(\"clone\", null) Should not find clone()");
|
||||
} catch (NoSuchMethodException e) {
|
||||
; //all good
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetMethods() {
|
||||
Method[] m = new Integer[0][0][0].getClass().getMethods();
|
||||
for (Method mm : m)
|
||||
if(mm.getName().contentEquals("clone")) {
|
||||
failed++;
|
||||
System.out.println("getMethods() Should not find clone()");
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetDeclaredMethod() {
|
||||
try {
|
||||
Method m = new Object[0][0].getClass().getDeclaredMethod("clone", (Class<?>[])null);
|
||||
|
||||
failed++;
|
||||
System.out.println("getDeclaredMethod(\"clone\", null) Should not find clone()");
|
||||
|
||||
} catch (NoSuchMethodException e) {
|
||||
; //all good
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetDeclaredMethods() {
|
||||
Method[] m = new Throwable[0][0][0][0].getClass().getDeclaredMethods();
|
||||
if (m.length != 0) {
|
||||
failed++;
|
||||
System.out.println("getDeclaredMethods().length should be 0");
|
||||
}
|
||||
}
|
||||
|
||||
public void testGetInterfaces() {
|
||||
Class<?>[] is = new Integer[0].getClass().getInterfaces();
|
||||
boolean thisFailed = false;
|
||||
|
||||
if (is.length != 2)
|
||||
thisFailed = true;
|
||||
|
||||
if (!is[0].getCanonicalName().equals("java.lang.Cloneable"))
|
||||
thisFailed = true;
|
||||
|
||||
if (!is[1].getCanonicalName().equals("java.io.Serializable"))
|
||||
thisFailed = true;
|
||||
|
||||
if (thisFailed) {
|
||||
failed++;
|
||||
System.out.println(Arrays.asList(is));
|
||||
System.out.println("Should contain exactly Cloneable, Serializable in that order.");
|
||||
}
|
||||
}
|
||||
}
|
||||
49
test/jdk/java/lang/Class/ArrayType.java
Normal file
49
test/jdk/java/lang/Class/ArrayType.java
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8268250
|
||||
* @summary Check exceptional behavior of Class.arrayType
|
||||
*/
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.util.function.*;
|
||||
|
||||
public class ArrayType {
|
||||
public static void main(String... args) {
|
||||
expectException(() -> Void.TYPE);
|
||||
expectException(() -> Array.newInstance(int.class, new int[255])
|
||||
.getClass());
|
||||
}
|
||||
|
||||
private static void expectException(Supplier<Class<?>> arrayTypeArg) {
|
||||
try {
|
||||
Class<?> arrayClazz = arrayTypeArg.get().arrayType();
|
||||
throw new RuntimeException("Expected exception not thrown: " +
|
||||
arrayClazz);
|
||||
} catch (UnsupportedOperationException uoe) {
|
||||
; // Expected
|
||||
}
|
||||
}
|
||||
}
|
||||
39
test/jdk/java/lang/Class/Cast.java
Normal file
39
test/jdk/java/lang/Class/Cast.java
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4881275
|
||||
* @summary (reflect) Class.cast() - typesafe cast desired
|
||||
*/
|
||||
|
||||
public class Cast {
|
||||
static class Foo {}
|
||||
|
||||
public static void main(String argv[]) throws Exception {
|
||||
Object o = Foo.class.newInstance();
|
||||
Foo f = Foo.class.cast(o);
|
||||
if (f == null) throw new Error();
|
||||
Foo f2 = Foo.class.cast(null);
|
||||
}
|
||||
}
|
||||
BIN
test/jdk/java/lang/Class/EnumPoseur.class
Normal file
BIN
test/jdk/java/lang/Class/EnumPoseur.class
Normal file
Binary file not shown.
11
test/jdk/java/lang/Class/EnumPoseur.java.src
Normal file
11
test/jdk/java/lang/Class/EnumPoseur.java.src
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
*
|
||||
*
|
||||
* This file is used indirectly by the IsEnum.java test. The class
|
||||
* file generated from this source file has class file version 48;
|
||||
* i.e. it is not a version 49 class file generated by target 1.5.
|
||||
*/
|
||||
class EnumPoseur extends java.lang.Enum {
|
||||
private EnumPoseur(){
|
||||
}
|
||||
}
|
||||
27
test/jdk/java/lang/Class/Foo.java
Normal file
27
test/jdk/java/lang/Class/Foo.java
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package foo;
|
||||
|
||||
// Loaded by a custom class loader in GetPackageTest
|
||||
public class Foo {
|
||||
}
|
||||
103
test/jdk/java/lang/Class/ForPrimitiveName.java
Normal file
103
test/jdk/java/lang/Class/ForPrimitiveName.java
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Test Class.forPrimitiveName
|
||||
* @bug 6361826
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ForPrimitiveName {
|
||||
public static void main(String... args) {
|
||||
positiveTests();
|
||||
negativeTests();
|
||||
}
|
||||
|
||||
private static final void positiveTests() {
|
||||
|
||||
/**
|
||||
* immutable table mapping primitive type names to corresponding
|
||||
* class objects
|
||||
*/
|
||||
final Map<String, Class<?>> primClasses =
|
||||
Map.of("boolean", boolean.class,
|
||||
"byte", byte.class,
|
||||
"char", char.class,
|
||||
"short", short.class,
|
||||
"int", int.class,
|
||||
"long", long.class,
|
||||
"float", float.class,
|
||||
"double", double.class,
|
||||
"void", void.class);
|
||||
|
||||
for (var entry : primClasses.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
Class<?> expected = entry.getValue();
|
||||
Class<?> result = Class.forPrimitiveName(key);
|
||||
|
||||
// For java.lang.Class, equality is identity.
|
||||
if (result != expected) {
|
||||
throw new RuntimeException("Unexpected mapping for " + key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final void negativeTests() {
|
||||
final List<String> expectedNull =
|
||||
List.of("java.lang.Object",
|
||||
"java.lang.String",
|
||||
|
||||
// descriptor string names for primitive types
|
||||
"Z", // boolean
|
||||
"B", // byte
|
||||
"C", // char
|
||||
"D", // double
|
||||
"F", // float
|
||||
"I", // int
|
||||
"L", // long
|
||||
"S", // short
|
||||
"V", // void
|
||||
|
||||
// Wrapper classes
|
||||
"java.lang.Byte",
|
||||
"java.lang.Boolean",
|
||||
"java.lang.Character",
|
||||
"java.lang.Short",
|
||||
"java.lang.Integer",
|
||||
"java.lang.Long",
|
||||
"java.lang.Float",
|
||||
"java.lang.Double",
|
||||
"java.lang.Void");
|
||||
for (var entry : expectedNull) {
|
||||
Class<?> result = Class.forPrimitiveName(entry);
|
||||
if (result != null ) {
|
||||
throw new RuntimeException("Unexpected nonnull result for " +
|
||||
entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
249
test/jdk/java/lang/Class/GenericStringTest.java
Normal file
249
test/jdk/java/lang/Class/GenericStringTest.java
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6298888 6992705 8161500 6304578 8322878
|
||||
* @summary Check Class.toGenericString()
|
||||
*/
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.lang.annotation.*;
|
||||
import java.util.*;
|
||||
|
||||
@ExpectedGenericString("public class GenericStringTest")
|
||||
public class GenericStringTest {
|
||||
public Map<String, Integer>[] mixed = null;
|
||||
public Map<String, Integer>[][] mixed2 = null;
|
||||
|
||||
private static record PlatformTestCase(Class<?> clazz, String expected) {}
|
||||
|
||||
public static void main(String... args) throws ReflectiveOperationException {
|
||||
int failures = 0;
|
||||
|
||||
String[][] nested = {{""}};
|
||||
int[][] intArray = {{1}};
|
||||
|
||||
List<PlatformTestCase> platformTestCases =
|
||||
List.of(new PlatformTestCase(int.class, "int"),
|
||||
new PlatformTestCase(void.class, "void"),
|
||||
new PlatformTestCase(args.getClass(), "java.lang.String[]"),
|
||||
new PlatformTestCase(nested.getClass(), "java.lang.String[][]"),
|
||||
new PlatformTestCase(intArray.getClass(), "int[][]"),
|
||||
|
||||
new PlatformTestCase(java.lang.Enum.class,
|
||||
"public abstract class java.lang.Enum<E extends java.lang.Enum<E>>"),
|
||||
new PlatformTestCase(java.util.Map.class,
|
||||
"public abstract interface java.util.Map<K,V>"),
|
||||
new PlatformTestCase(java.util.EnumMap.class,
|
||||
"public class java.util.EnumMap<K extends java.lang.Enum<K>,V>"),
|
||||
new PlatformTestCase(java.util.EventListenerProxy.class,
|
||||
"public abstract class java.util.EventListenerProxy<T extends java.util.EventListener>"),
|
||||
|
||||
// Sealed class
|
||||
new PlatformTestCase(java.lang.ref.Reference.class,
|
||||
"public abstract sealed class java.lang.ref.Reference<T>"),
|
||||
// non-sealed class
|
||||
new PlatformTestCase(java.lang.ref.WeakReference.class,
|
||||
"public non-sealed class java.lang.ref.WeakReference<T>")
|
||||
);
|
||||
|
||||
for (PlatformTestCase platformTestCase : platformTestCases) {
|
||||
failures += checkToGenericString(platformTestCase.clazz,
|
||||
platformTestCase.expected);
|
||||
}
|
||||
|
||||
Field f = GenericStringTest.class.getDeclaredField("mixed");
|
||||
// The expected value includes "<K,V>" rather than
|
||||
// "<...String,...Integer>" since the Class object rather than
|
||||
// Type objects is being queried.
|
||||
failures += checkToGenericString(f.getType(), "java.util.Map<K,V>[]");
|
||||
f = GenericStringTest.class.getDeclaredField("mixed2");
|
||||
failures += checkToGenericString(f.getType(), "java.util.Map<K,V>[][]");
|
||||
|
||||
for(Class<?> clazz : List.of(GenericStringTest.class,
|
||||
AnInterface.class,
|
||||
LocalMap.class,
|
||||
AnEnum.class,
|
||||
AnotherEnum.class,
|
||||
|
||||
SealedRootClass.class,
|
||||
SealedRootClass.ChildA.class,
|
||||
SealedRootClass.ChildB.class,
|
||||
SealedRootClass.ChildB.GrandChildAB.class,
|
||||
SealedRootClass.ChildC.class,
|
||||
SealedRootClass.ChildC.GrandChildACA.class,
|
||||
SealedRootClass.ChildC.GrandChildACB.class,
|
||||
SealedRootClass.ChildC.GrandChildACC.class,
|
||||
SealedRootClass.ChildC.GrandChildACC.GreatGrandChildACCA.class,
|
||||
SealedRootClass.ChildC.GrandChildACC.GreatGrandChildACCB.class,
|
||||
|
||||
SealedRootIntf.class,
|
||||
SealedRootIntf.ChildA.class,
|
||||
SealedRootIntf.ChildB.class,
|
||||
SealedRootIntf.ChildB.GrandChildAB.class,
|
||||
SealedRootIntf.ChildC.class,
|
||||
SealedRootIntf.ChildC.GrandChildACA.class,
|
||||
SealedRootIntf.ChildC.GrandChildACB.class,
|
||||
SealedRootIntf.ChildC.GrandChildACC.class,
|
||||
SealedRootIntf.ChildC.GrandChildACC.GreatGrandChildACCA.class,
|
||||
SealedRootIntf.ChildC.GrandChildACC.GreatGrandChildACCB.class,
|
||||
SealedRootIntf.IntfA.class,
|
||||
SealedRootIntf.IntfA.IntfAImpl.class,
|
||||
SealedRootIntf.IntfB.class,
|
||||
SealedRootIntf.IntfB.IntfAImpl.class)) {
|
||||
failures += checkToGenericString(clazz, clazz.getAnnotation(ExpectedGenericString.class).value());
|
||||
}
|
||||
|
||||
if (failures > 0) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
private static int checkToGenericString(Class<?> clazz, String expected) {
|
||||
String genericString = clazz.toGenericString();
|
||||
if (!genericString.equals(expected)) {
|
||||
System.err.printf("Unexpected Class.toGenericString output; expected %n\t'%s',%n got %n\t'%s'.%n",
|
||||
expected,
|
||||
genericString);
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface ExpectedGenericString {
|
||||
String value();
|
||||
}
|
||||
|
||||
@ExpectedGenericString("abstract interface AnInterface")
|
||||
strictfp interface AnInterface {}
|
||||
|
||||
@ExpectedGenericString("abstract interface LocalMap<K,V>")
|
||||
interface LocalMap<K,V> {}
|
||||
|
||||
@ExpectedGenericString("final enum AnEnum")
|
||||
enum AnEnum {
|
||||
FOO;
|
||||
}
|
||||
|
||||
// If an enum class has a specialized enum constant, that is compiled
|
||||
// by having the enum class as being sealed rather than final. See JLS
|
||||
// 8.9 Enum Classes.
|
||||
@ExpectedGenericString("sealed enum AnotherEnum")
|
||||
enum AnotherEnum {
|
||||
BAR{};
|
||||
}
|
||||
|
||||
// Test cases for sealed/non-sealed _class_ hierarchy.
|
||||
@ExpectedGenericString("sealed class SealedRootClass")
|
||||
sealed class SealedRootClass
|
||||
permits
|
||||
SealedRootClass.ChildA,
|
||||
SealedRootClass.ChildB,
|
||||
SealedRootClass.ChildC {
|
||||
|
||||
@ExpectedGenericString("final class SealedRootClass$ChildA")
|
||||
final class ChildA extends SealedRootClass {}
|
||||
|
||||
@ExpectedGenericString("sealed class SealedRootClass$ChildB")
|
||||
sealed class ChildB extends SealedRootClass permits SealedRootClass.ChildB.GrandChildAB {
|
||||
@ExpectedGenericString("final class SealedRootClass$ChildB$GrandChildAB")
|
||||
final class GrandChildAB extends ChildB {}
|
||||
}
|
||||
|
||||
@ExpectedGenericString("non-sealed class SealedRootClass$ChildC")
|
||||
non-sealed class ChildC extends SealedRootClass {
|
||||
// The subclasses of ChildC do not themselves have to be
|
||||
// sealed, non-sealed, or final.
|
||||
@ExpectedGenericString("class SealedRootClass$ChildC$GrandChildACA")
|
||||
class GrandChildACA extends ChildC {}
|
||||
|
||||
@ExpectedGenericString("final class SealedRootClass$ChildC$GrandChildACB")
|
||||
final class GrandChildACB extends ChildC {}
|
||||
|
||||
@ExpectedGenericString("sealed class SealedRootClass$ChildC$GrandChildACC")
|
||||
sealed class GrandChildACC extends ChildC {
|
||||
@ExpectedGenericString("final class SealedRootClass$ChildC$GrandChildACC$GreatGrandChildACCA")
|
||||
final class GreatGrandChildACCA extends GrandChildACC {}
|
||||
|
||||
@ExpectedGenericString("non-sealed class SealedRootClass$ChildC$GrandChildACC$GreatGrandChildACCB")
|
||||
non-sealed class GreatGrandChildACCB extends GrandChildACC {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test cases for sealed/non-sealed _interface_ hierarchy.
|
||||
@ExpectedGenericString("abstract sealed interface SealedRootIntf")
|
||||
sealed interface SealedRootIntf
|
||||
permits
|
||||
SealedRootIntf.ChildA,
|
||||
SealedRootIntf.ChildB,
|
||||
SealedRootIntf.ChildC,
|
||||
|
||||
SealedRootIntf.IntfA,
|
||||
SealedRootIntf.IntfB {
|
||||
|
||||
@ExpectedGenericString("public static final class SealedRootIntf$ChildA")
|
||||
final class ChildA implements SealedRootIntf {}
|
||||
|
||||
@ExpectedGenericString("public static sealed class SealedRootIntf$ChildB")
|
||||
sealed class ChildB implements SealedRootIntf permits SealedRootIntf.ChildB.GrandChildAB {
|
||||
@ExpectedGenericString("final class SealedRootIntf$ChildB$GrandChildAB")
|
||||
final class GrandChildAB extends ChildB {}
|
||||
}
|
||||
|
||||
@ExpectedGenericString("public static non-sealed class SealedRootIntf$ChildC")
|
||||
non-sealed class ChildC implements SealedRootIntf {
|
||||
// The subclasses of ChildC do not themselves have to be
|
||||
// sealed, non-sealed, or final.
|
||||
@ExpectedGenericString("class SealedRootIntf$ChildC$GrandChildACA")
|
||||
class GrandChildACA extends ChildC {}
|
||||
|
||||
@ExpectedGenericString("final class SealedRootIntf$ChildC$GrandChildACB")
|
||||
final class GrandChildACB extends ChildC {}
|
||||
|
||||
@ExpectedGenericString("sealed class SealedRootIntf$ChildC$GrandChildACC")
|
||||
sealed class GrandChildACC extends ChildC {
|
||||
@ExpectedGenericString("final class SealedRootIntf$ChildC$GrandChildACC$GreatGrandChildACCA")
|
||||
final class GreatGrandChildACCA extends GrandChildACC {}
|
||||
|
||||
@ExpectedGenericString("non-sealed class SealedRootIntf$ChildC$GrandChildACC$GreatGrandChildACCB")
|
||||
non-sealed class GreatGrandChildACCB extends GrandChildACC {}
|
||||
}
|
||||
}
|
||||
|
||||
@ExpectedGenericString("public abstract static sealed interface SealedRootIntf$IntfA")
|
||||
sealed interface IntfA extends SealedRootIntf {
|
||||
@ExpectedGenericString("public static non-sealed class SealedRootIntf$IntfA$IntfAImpl")
|
||||
non-sealed class IntfAImpl implements IntfA {}
|
||||
}
|
||||
|
||||
@ExpectedGenericString("public abstract static non-sealed interface SealedRootIntf$IntfB")
|
||||
non-sealed interface IntfB extends SealedRootIntf {
|
||||
// Check that non-sealing can be allowed with a second superinterface being sealed.
|
||||
@ExpectedGenericString("public static non-sealed class SealedRootIntf$IntfB$IntfAImpl")
|
||||
non-sealed class IntfAImpl implements IntfB, IntfA {}
|
||||
}
|
||||
}
|
||||
79
test/jdk/java/lang/Class/GetModuleTest.java
Normal file
79
test/jdk/java/lang/Class/GetModuleTest.java
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Exercise Class#getModule
|
||||
* @modules java.desktop
|
||||
* @run testng GetModuleTest
|
||||
*/
|
||||
|
||||
import java.awt.Component;
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
public class GetModuleTest {
|
||||
|
||||
private static final Module TEST_MODULE = GetModuleTest.class.getModule();
|
||||
|
||||
|
||||
@DataProvider(name = "testclasses")
|
||||
public Object[][] testClasses() {
|
||||
return new Object[][] {
|
||||
|
||||
// unnamed module
|
||||
|
||||
{ GetModuleTest.class, null },
|
||||
{ GetModuleTest[].class, null },
|
||||
{ GetModuleTest[][].class, null },
|
||||
|
||||
// should return named module
|
||||
|
||||
{ int.class, "java.base" },
|
||||
{ int[].class, "java.base" },
|
||||
{ int[][].class, "java.base" },
|
||||
{ void.class, "java.base" },
|
||||
|
||||
{ Object.class, "java.base" },
|
||||
{ Object[].class, "java.base" },
|
||||
{ Object[][].class, "java.base" },
|
||||
{ Component.class, "java.desktop" },
|
||||
{ Component[].class, "java.desktop" },
|
||||
{ Component[][].class, "java.desktop" },
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "testclasses")
|
||||
public void testGetModule(Class<?> type, String expected) {
|
||||
Module m = type.getModule();
|
||||
assertNotNull(m);
|
||||
if (expected == null) {
|
||||
assertTrue(m == TEST_MODULE);
|
||||
} else {
|
||||
assertEquals(m.getName(), expected);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
59
test/jdk/java/lang/Class/GetPackageBootLoaderChildLayer.java
Normal file
59
test/jdk/java/lang/Class/GetPackageBootLoaderChildLayer.java
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @requires !vm.graal.enabled
|
||||
* @modules jdk.attach
|
||||
* @run main/othervm --limit-modules jdk.attach -Djdk.attach.allowAttachSelf
|
||||
* GetPackageBootLoaderChildLayer
|
||||
* @summary Exercise Class.getPackage on a class defined to the boot loader
|
||||
* but in a module that is in a child layer rather than the boot layer
|
||||
*/
|
||||
|
||||
import com.sun.tools.attach.VirtualMachine;
|
||||
|
||||
public class GetPackageBootLoaderChildLayer {
|
||||
public static void main(String[] args) throws Exception {
|
||||
// ensure that the java.management module is not in the boot layer
|
||||
ModuleLayer.boot().findModule("java.management").ifPresent(m -> {
|
||||
throw new RuntimeException("java.management loaded!!!");
|
||||
});
|
||||
|
||||
// start local JMX agent via the attach mechanism
|
||||
String vmid = "" + ProcessHandle.current().pid();
|
||||
VirtualMachine vm = VirtualMachine.attach(vmid);
|
||||
vm.startLocalManagementAgent();
|
||||
|
||||
// check layer, class loader, and Package object
|
||||
Class<?> clazz = Class.forName("javax.management.MXBean");
|
||||
if (clazz.getModule().getLayer() == ModuleLayer.boot())
|
||||
throw new RuntimeException("Module is in boot layer!!!");
|
||||
ClassLoader loader = clazz.getClassLoader();
|
||||
if (loader != null)
|
||||
throw new RuntimeException("Unexpected class loader: " + loader);
|
||||
Package p = clazz.getPackage();
|
||||
if (!p.getName().equals("javax.management"))
|
||||
throw new RuntimeException("Unexpected package " + p);
|
||||
}
|
||||
}
|
||||
116
test/jdk/java/lang/Class/GetPackageTest.java
Normal file
116
test/jdk/java/lang/Class/GetPackageTest.java
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Basic test for Class.getPackage
|
||||
* @compile Foo.java
|
||||
* @run testng GetPackageTest
|
||||
*/
|
||||
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Properties;
|
||||
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
public class GetPackageTest {
|
||||
private static Class<?> fooClass; // definePackage is not called for Foo class
|
||||
|
||||
@BeforeTest
|
||||
public static void loadFooClass() throws ClassNotFoundException {
|
||||
TestClassLoader loader = new TestClassLoader();
|
||||
fooClass = loader.loadClass("foo.Foo");
|
||||
assertEquals(fooClass.getClassLoader(), loader);
|
||||
}
|
||||
|
||||
@DataProvider(name = "testClasses")
|
||||
public Object[][] testClasses() {
|
||||
return new Object[][] {
|
||||
// primitive type, void, array types
|
||||
{ int.class, null },
|
||||
{ long[].class, null },
|
||||
{ Object[][].class, null },
|
||||
{ void.class, null },
|
||||
|
||||
// unnamed package
|
||||
{ GetPackageTest.class, "" },
|
||||
|
||||
// named package
|
||||
{ fooClass, "foo" },
|
||||
{ Object.class, "java.lang" },
|
||||
{ Properties.class, "java.util" },
|
||||
{ BigInteger.class, "java.math" },
|
||||
{ Test.class, "org.testng.annotations" },
|
||||
};
|
||||
}
|
||||
|
||||
@Test(dataProvider = "testClasses")
|
||||
public void testGetPackage(Class<?> type, String expected) {
|
||||
Package p = type.getPackage();
|
||||
if (expected == null) {
|
||||
assertTrue(p == null);
|
||||
} else {
|
||||
assertEquals(p.getName(), expected);
|
||||
}
|
||||
}
|
||||
|
||||
static class TestClassLoader extends ClassLoader {
|
||||
public TestClassLoader() {
|
||||
super();
|
||||
}
|
||||
|
||||
public TestClassLoader(ClassLoader parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> findClass(String name) throws ClassNotFoundException {
|
||||
Path p = Paths.get(System.getProperty("test.classes", "."));
|
||||
|
||||
try {
|
||||
byte[] bb = Files.readAllBytes(p.resolve("foo/Foo.class"));
|
||||
return defineClass(name, bb, 0, bb.length);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
protected Class<?> loadClass(String cn, boolean resolve) throws ClassNotFoundException {
|
||||
if (!cn.equals("foo.Foo"))
|
||||
return super.loadClass(cn, resolve);
|
||||
return findClass(cn);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
63
test/jdk/java/lang/Class/IsAnnotationType.java
Normal file
63
test/jdk/java/lang/Class/IsAnnotationType.java
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4891872 4988155
|
||||
* @summary Check isAnnotation() method
|
||||
*/
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
public class IsAnnotationType {
|
||||
interface AnnotationPoseur extends Annotation {
|
||||
}
|
||||
|
||||
static int test(Class clazz, boolean expected) {
|
||||
int status = (clazz.isAnnotation() == expected)?0:1;
|
||||
|
||||
if (status == 1) {
|
||||
System.err.println("Unexpected annotation status for " + clazz);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
int failures = 0;
|
||||
|
||||
failures += test(String.class, false);
|
||||
failures += test(Enum.class, false);
|
||||
failures += test(java.math.RoundingMode.class, false);
|
||||
// Classes in java.lang.annotation
|
||||
failures += test(Annotation.class, false);
|
||||
failures += test(Retention.class, true);
|
||||
failures += test(RetentionPolicy.class, false);
|
||||
failures += test(Target.class, true);
|
||||
failures += test(AnnotationPoseur.class, false);
|
||||
|
||||
if (failures > 0) {
|
||||
throw new RuntimeException("Unexpected annotation " +
|
||||
"status detected.");
|
||||
}
|
||||
}
|
||||
}
|
||||
78
test/jdk/java/lang/Class/IsEnum.java
Normal file
78
test/jdk/java/lang/Class/IsEnum.java
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4891872 4989735 4990789 5020490
|
||||
* @summary Check isEnum() method
|
||||
*/
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
public class IsEnum {
|
||||
|
||||
static int test(Class<?> clazz, boolean expected) {
|
||||
int status = (clazz.isEnum() == expected) ? 0 : 1;
|
||||
|
||||
if (status == 1) {
|
||||
System.err.println("Unexpected enum status for " + clazz);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
public static void main(String... argv) {
|
||||
int failures = 0;
|
||||
|
||||
failures += test(IsEnum.class, false);
|
||||
failures += test(String.class, false);
|
||||
failures += test(Enum.class, false);
|
||||
failures += test(EnumPoseur.class, false);
|
||||
failures += test(java.math.RoundingMode.class, true);
|
||||
|
||||
// Classes in java.lang.annotation
|
||||
failures += test(Annotation.class, false);
|
||||
failures += test(ElementType.class, true);
|
||||
failures += test(Retention.class, false);
|
||||
failures += test(RetentionPolicy.class, true);
|
||||
failures += test(Target.class, false);
|
||||
|
||||
// A class for a specialized enum constant isn't itself an enum
|
||||
failures += test(SpecialEnum.class, true);
|
||||
failures += test(SpecialEnum.RED.getClass(), false);
|
||||
failures += test(SpecialEnum.GREEN.getClass(), true);
|
||||
|
||||
if (failures > 0) {
|
||||
throw new RuntimeException("Unexpected enum status detected.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum SpecialEnum {
|
||||
RED {
|
||||
String special() {return "riding hood";}
|
||||
},
|
||||
|
||||
GREEN;
|
||||
|
||||
String special() {return "how was my valley";}
|
||||
}
|
||||
81
test/jdk/java/lang/Class/IsSynthetic.java
Normal file
81
test/jdk/java/lang/Class/IsSynthetic.java
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 5012133
|
||||
* @summary Check Class.isSynthetic method
|
||||
*/
|
||||
|
||||
import java.lang.reflect.*;
|
||||
|
||||
public class IsSynthetic {
|
||||
|
||||
static class NestedClass {
|
||||
}
|
||||
|
||||
static int test(Class<?> clazz, boolean expected) {
|
||||
if (clazz.isSynthetic() == expected)
|
||||
return 0;
|
||||
else {
|
||||
System.err.println("Unexpected synthetic status for " +
|
||||
clazz.getName() + " expected: " + expected +
|
||||
" got: " + (!expected));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
int failures = 0;
|
||||
class LocalClass {}
|
||||
|
||||
Cloneable clone = new Cloneable() {};
|
||||
|
||||
failures += test(IsSynthetic.class, false);
|
||||
failures += test(java.lang.String.class, false);
|
||||
failures += test(LocalClass.class, false);
|
||||
failures += test(NestedClass.class, false);
|
||||
failures += test(clone.getClass(), false);
|
||||
|
||||
for(Constructor c: Tricky.class.getDeclaredConstructors()) {
|
||||
Class<?>[] paramTypes = c.getParameterTypes();
|
||||
if (paramTypes.length > 0) {
|
||||
System.out.println("Testing class that should be synthetic.");
|
||||
for(Class paramType: paramTypes) {
|
||||
failures += test(paramType, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (failures != 0)
|
||||
throw new RuntimeException("Test failed with " + failures + " failures.");
|
||||
}
|
||||
}
|
||||
|
||||
class Tricky {
|
||||
private Tricky() {}
|
||||
|
||||
public static class Nested {
|
||||
Tricky t = new Tricky();
|
||||
}
|
||||
}
|
||||
101
test/jdk/java/lang/Class/NameTest.java
Normal file
101
test/jdk/java/lang/Class/NameTest.java
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8281671
|
||||
* @summary Checks on various "getFooName" methods of java.lang.Class
|
||||
*/
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class NameTest {
|
||||
public static void main(String... args) {
|
||||
testCanonicalName();
|
||||
testSimpleName();
|
||||
}
|
||||
|
||||
private static void testCanonicalName() {
|
||||
class LocalClass {} // Local class; no canonical name
|
||||
Object o = new Object() {}; // Anonymous class; no canonical name
|
||||
Object[] objectArray = {};
|
||||
|
||||
Map<Class<?>, String> expectedCanonicalName = new HashMap<>();
|
||||
|
||||
expectedCanonicalName.put(LocalClass.class, null);
|
||||
expectedCanonicalName.put(o.getClass(), null);
|
||||
|
||||
// If a component type doesn't have a canonical name, neither
|
||||
// does an array of that type.
|
||||
expectedCanonicalName.put(LocalClass.class.arrayType(), null);
|
||||
expectedCanonicalName.put(o.getClass().arrayType(), null);
|
||||
|
||||
expectedCanonicalName.put(int.class, "int");
|
||||
expectedCanonicalName.put(Object.class, "java.lang.Object");
|
||||
expectedCanonicalName.put(objectArray.getClass(), "java.lang.Object[]");
|
||||
|
||||
for (var entry : expectedCanonicalName.entrySet()) {
|
||||
var key = entry.getKey();
|
||||
var expectedName = entry.getValue();
|
||||
String canonicalName = key.getCanonicalName();
|
||||
if (!Objects.equals(canonicalName, expectedName)) {
|
||||
System.err.println("Unexpected canonical name '" +
|
||||
canonicalName + "' found for " +
|
||||
key + ", expected " + expectedName);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void testSimpleName() {
|
||||
class ALocalClass {} // Local class
|
||||
Object o = new Object() {}; // Anonymous class, empty simple name
|
||||
Object[] objectArray = {};
|
||||
|
||||
Map<Class<?>, String> expectedSimpleName = new HashMap<>();
|
||||
|
||||
expectedSimpleName.put(ALocalClass.class, "ALocalClass");
|
||||
expectedSimpleName.put(o.getClass(), "");
|
||||
|
||||
expectedSimpleName.put(ALocalClass.class.arrayType(), "ALocalClass[]");
|
||||
expectedSimpleName.put(o.getClass().arrayType(), "[]");
|
||||
|
||||
expectedSimpleName.put(int.class, "int");
|
||||
expectedSimpleName.put(Object.class, "Object");
|
||||
expectedSimpleName.put(objectArray.getClass(), "Object[]");
|
||||
|
||||
for (var entry : expectedSimpleName.entrySet()) {
|
||||
var key = entry.getKey();
|
||||
var expectedName = entry.getValue();
|
||||
String simpleName = key.getSimpleName();
|
||||
if (!Objects.equals(simpleName, expectedName)) {
|
||||
System.err.println("Unexpected simple name '" +
|
||||
simpleName + "' found for " +
|
||||
key + ", expected " + expectedName);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
65
test/jdk/java/lang/Class/NullBehaviorTest.java
Normal file
65
test/jdk/java/lang/Class/NullBehaviorTest.java
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8371953
|
||||
* @summary Check null argument behaviors for java.lang.Class APIs.
|
||||
* @run junit NullBehaviorTest
|
||||
*/
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class NullBehaviorTest {
|
||||
@Test
|
||||
void nullChecks() {
|
||||
assertThrows(NullPointerException.class, () -> Class.forName(null));
|
||||
assertDoesNotThrow(() -> Class.forName("java.lang.Object", false, null));
|
||||
assertThrows(NullPointerException.class, () -> Class.forName(null, false, null));
|
||||
assertThrows(NullPointerException.class, () -> Class.forName(null, "java.lang.Object"));
|
||||
assertThrows(NullPointerException.class, () -> Class.forName(Object.class.getModule(), null));
|
||||
assertThrows(NullPointerException.class, () -> Class.forPrimitiveName(null));
|
||||
assertFalse(Object.class.isInstance(null));
|
||||
assertThrows(NullPointerException.class, () -> Object.class.isAssignableFrom(null));
|
||||
assertThrows(NullPointerException.class, () -> Object.class.getField(null));
|
||||
assertThrows(NullPointerException.class, () -> Object.class.getDeclaredField(null));
|
||||
assertThrows(NullPointerException.class, () -> Object.class.getMethod(null));
|
||||
assertThrows(NullPointerException.class, () -> Object.class.getDeclaredMethod(null));
|
||||
assertDoesNotThrow(() -> Object.class.getMethod("hashCode", (Class<?>[]) null));
|
||||
assertDoesNotThrow(() -> Object.class.getDeclaredMethod("hashCode", (Class<?>[]) null));
|
||||
assertThrows(NoSuchMethodException.class, () -> Object.class.getMethod("hashCode", new Class[]{null}));
|
||||
assertThrows(NoSuchMethodException.class, () -> Object.class.getDeclaredMethod("hashCode", new Class[]{null}));
|
||||
assertDoesNotThrow(() -> Object.class.getConstructor((Class<?>[]) null));
|
||||
assertDoesNotThrow(() -> Object.class.getDeclaredConstructor((Class<?>[]) null));
|
||||
assertThrows(NoSuchMethodException.class, () -> Object.class.getConstructor(new Class[]{null}));
|
||||
assertThrows(NoSuchMethodException.class, () -> Object.class.getDeclaredConstructor(new Class[]{null}));
|
||||
assertThrows(NullPointerException.class, () -> Object.class.getResourceAsStream(null));
|
||||
assertThrows(NullPointerException.class, () -> Object.class.getResource(null));
|
||||
assertDoesNotThrow(() -> Object.class.cast(null));
|
||||
assertThrows(NullPointerException.class, () -> Object.class.asSubclass(null));
|
||||
assertThrows(NullPointerException.class, () -> Object.class.isNestmateOf(null));
|
||||
assertThrows(NullPointerException.class, () -> int.class.isNestmateOf(null));
|
||||
}
|
||||
}
|
||||
80
test/jdk/java/lang/Class/ProtectionDomainRace.java
Normal file
80
test/jdk/java/lang/Class/ProtectionDomainRace.java
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8334394
|
||||
* @summary ensure there is no race condition in Class::protectionDomain
|
||||
* @run main/othervm ProtectionDomainRace
|
||||
*/
|
||||
import javax.security.auth.Subject;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
/**
|
||||
* Without the code fix, this test would fail with
|
||||
* java.lang.AssertionError: sun.security.util.ResourcesMgr (PD)
|
||||
* at java.base/java.lang.invoke.MethodHandleImpl$BindCaller.checkInjectedInvoker(MethodHandleImpl.java:1209)
|
||||
* at java.base/java.lang.invoke.MethodHandleImpl$BindCaller.makeInjectedInvoker(MethodHandleImpl.java:1110)
|
||||
* at java.base/java.lang.invoke.MethodHandleImpl$BindCaller$1.computeValue(MethodHandleImpl.java:1117)
|
||||
* at java.base/java.lang.invoke.MethodHandleImpl$BindCaller$1.computeValue(MethodHandleImpl.java:1114)
|
||||
* at java.base/java.lang.ClassValue.getFromHashMap(ClassValue.java:229)
|
||||
* at java.base/java.lang.ClassValue.getFromBackup(ClassValue.java:211)
|
||||
* at java.base/java.lang.ClassValue.get(ClassValue.java:117)
|
||||
* at java.base/java.lang.invoke.MethodHandleImpl$BindCaller.bindCallerWithInjectedInvoker(MethodHandleImpl.java:1089)
|
||||
* at java.base/java.lang.invoke.MethodHandleImpl$BindCaller.bindCaller(MethodHandleImpl.java:1077)
|
||||
* at java.base/java.lang.invoke.MethodHandleImpl.bindCaller(MethodHandleImpl.java:1032)
|
||||
* at java.base/java.lang.invoke.MethodHandles$Lookup.maybeBindCaller(MethodHandles.java:4149)
|
||||
* at java.base/java.lang.invoke.MethodHandles$Lookup.getDirectMethodCommon(MethodHandles.java:4133)
|
||||
* at java.base/java.lang.invoke.MethodHandles$Lookup.getDirectMethodNoSecurityManager(MethodHandles.java:4077)
|
||||
* at java.base/java.lang.invoke.MethodHandles$Lookup.getDirectMethodForConstant(MethodHandles.java:4326)
|
||||
* at java.base/java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(MethodHandles.java:4274)
|
||||
* at java.base/java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(MethodHandleNatives.java:628)
|
||||
* at java.base/sun.security.util.ResourcesMgr.getBundle(ResourcesMgr.java:54)
|
||||
* at java.base/sun.security.util.ResourcesMgr.getString(ResourcesMgr.java:40)
|
||||
* at java.base/javax.security.auth.Subject.doAs(Subject.java:517)
|
||||
* ...
|
||||
* as the Class::protectionDomain might assign different objects to the (original) allPermDomain field.
|
||||
*/
|
||||
public class ProtectionDomainRace {
|
||||
private static volatile Throwable failed = null;
|
||||
public static void main(String[] args) throws Throwable {
|
||||
PrivilegedAction<?> pa = () -> null;
|
||||
Thread[] threads = new Thread[100];
|
||||
for (int i = 0; i < 100; i++) {
|
||||
threads[i] = new Thread(() -> {
|
||||
try {
|
||||
Subject.doAs(null, pa);
|
||||
} catch (Throwable t) {
|
||||
failed = t;
|
||||
}
|
||||
});
|
||||
threads[i].start();
|
||||
}
|
||||
for (int i = 0; i < 100; i++) {
|
||||
threads[i].join();
|
||||
}
|
||||
if (failed != null) {
|
||||
throw failed;
|
||||
}
|
||||
}
|
||||
}
|
||||
199
test/jdk/java/lang/Class/TypeCheckMicroBenchmark.java
Normal file
199
test/jdk/java/lang/Class/TypeCheckMicroBenchmark.java
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is not a regression test, but a micro-benchmark.
|
||||
*
|
||||
* I have run this as follows:
|
||||
*
|
||||
* repeat 5 for f in -client -server; do mergeBench dolphin . jr -dsa -da $f TypeCheckMicroBenchmark.java; done
|
||||
*
|
||||
*
|
||||
* @author Martin Buchholz
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class TypeCheckMicroBenchmark {
|
||||
abstract static class Job {
|
||||
private final String name;
|
||||
Job(String name) { this.name = name; }
|
||||
String name() { return name; }
|
||||
abstract void work() throws Throwable;
|
||||
}
|
||||
|
||||
private static void collectAllGarbage() {
|
||||
final java.util.concurrent.CountDownLatch drained
|
||||
= new java.util.concurrent.CountDownLatch(1);
|
||||
try {
|
||||
System.gc(); // enqueue finalizable objects
|
||||
new Object() { protected void finalize() {
|
||||
drained.countDown(); }};
|
||||
System.gc(); // enqueue detector
|
||||
drained.await(); // wait for finalizer queue to drain
|
||||
System.gc(); // cleanup finalized objects
|
||||
} catch (InterruptedException e) { throw new Error(e); }
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs each job for long enough that all the runtime compilers
|
||||
* have had plenty of time to warm up, i.e. get around to
|
||||
* compiling everything worth compiling.
|
||||
* Returns array of average times per job per run.
|
||||
*/
|
||||
private static long[] time0(Job ... jobs) throws Throwable {
|
||||
final long warmupNanos = 10L * 1000L * 1000L * 1000L;
|
||||
long[] nanoss = new long[jobs.length];
|
||||
for (int i = 0; i < jobs.length; i++) {
|
||||
collectAllGarbage();
|
||||
long t0 = System.nanoTime();
|
||||
long t;
|
||||
int j = 0;
|
||||
do { jobs[i].work(); j++; }
|
||||
while ((t = System.nanoTime() - t0) < warmupNanos);
|
||||
nanoss[i] = t/j;
|
||||
}
|
||||
return nanoss;
|
||||
}
|
||||
|
||||
private static void time(Job ... jobs) throws Throwable {
|
||||
|
||||
long[] warmup = time0(jobs); // Warm up run
|
||||
long[] nanoss = time0(jobs); // Real timing run
|
||||
long[] milliss = new long[jobs.length];
|
||||
double[] ratios = new double[jobs.length];
|
||||
|
||||
final String nameHeader = "Method";
|
||||
final String millisHeader = "Millis";
|
||||
final String ratioHeader = "Ratio";
|
||||
|
||||
int nameWidth = nameHeader.length();
|
||||
int millisWidth = millisHeader.length();
|
||||
int ratioWidth = ratioHeader.length();
|
||||
|
||||
for (int i = 0; i < jobs.length; i++) {
|
||||
nameWidth = Math.max(nameWidth, jobs[i].name().length());
|
||||
|
||||
milliss[i] = nanoss[i]/(1000L * 1000L);
|
||||
millisWidth = Math.max(millisWidth,
|
||||
String.format("%d", milliss[i]).length());
|
||||
|
||||
ratios[i] = (double) nanoss[i] / (double) nanoss[0];
|
||||
ratioWidth = Math.max(ratioWidth,
|
||||
String.format("%.3f", ratios[i]).length());
|
||||
}
|
||||
|
||||
String format = String.format("%%-%ds %%%dd %%%d.3f%%n",
|
||||
nameWidth, millisWidth, ratioWidth);
|
||||
String headerFormat = String.format("%%-%ds %%%ds %%%ds%%n",
|
||||
nameWidth, millisWidth, ratioWidth);
|
||||
System.out.printf(headerFormat, "Method", "Millis", "Ratio");
|
||||
|
||||
// Print out absolute and relative times, calibrated against first job
|
||||
for (int i = 0; i < jobs.length; i++)
|
||||
System.out.printf(format, jobs[i].name(), milliss[i], ratios[i]);
|
||||
}
|
||||
|
||||
private static String keywordValue(String[] args, String keyword) {
|
||||
for (String arg : args)
|
||||
if (arg.startsWith(keyword))
|
||||
return arg.substring(keyword.length() + 1);
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int intArg(String[] args, String keyword, int defaultValue) {
|
||||
String val = keywordValue(args, keyword);
|
||||
return val == null ? defaultValue : Integer.parseInt(val);
|
||||
}
|
||||
|
||||
private static java.util.regex.Pattern patternArg(String[] args,
|
||||
String keyword) {
|
||||
String val = keywordValue(args, keyword);
|
||||
return val == null ? null : java.util.regex.Pattern.compile(val);
|
||||
}
|
||||
|
||||
private static Job[] filter(java.util.regex.Pattern filter,
|
||||
Job[] jobs) {
|
||||
if (filter == null) return jobs;
|
||||
Job[] newJobs = new Job[jobs.length];
|
||||
int n = 0;
|
||||
for (Job job : jobs)
|
||||
if (filter.matcher(job.name()).find())
|
||||
newJobs[n++] = job;
|
||||
// Arrays.copyOf not available in JDK 5
|
||||
Job[] ret = new Job[n];
|
||||
System.arraycopy(newJobs, 0, ret, 0, n);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Usage: [iterations=N] [size=N] [filter=REGEXP]
|
||||
*/
|
||||
public static void main(String[] args) throws Throwable {
|
||||
final int iterations = intArg(args, "iterations", 30000);
|
||||
final int size = intArg(args, "size", 1000);
|
||||
final java.util.regex.Pattern filter
|
||||
= patternArg(args, "filter");
|
||||
|
||||
final List<Integer> list = new ArrayList<Integer>();
|
||||
final Random rnd = new Random();
|
||||
for (int i = 0; i < size; i++)
|
||||
list.add(rnd.nextInt());
|
||||
final Class klazz = Integer.class;
|
||||
|
||||
final Job[] jobs = {
|
||||
new Job("toArray(T[])") { void work() {
|
||||
Object[] a = new Integer[0];
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
try { list.toArray(a); }
|
||||
catch (ArrayStoreException ase) {
|
||||
throw new ClassCastException(); }}}},
|
||||
new Job("isInstance") { void work() {
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
for (Object x : list.toArray())
|
||||
if (! (x != null && klazz.isInstance(x)))
|
||||
throw new ClassCastException(); }}},
|
||||
new Job("Class.cast") { void work() {
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
for (Object x : list.toArray())
|
||||
klazz.cast(x); }}},
|
||||
new Job("write into array") { void work() {
|
||||
Object[] a = new Integer[1];
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
for (Object x : list.toArray()) {
|
||||
try { a[0] = x; }
|
||||
catch (ArrayStoreException unused) {
|
||||
throw new ClassCastException(); }}}}},
|
||||
new Job("write into dynamic array") { void work() {
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
for (Object x : list.toArray()) {
|
||||
Object[] a = (Object[])
|
||||
java.lang.reflect.Array.newInstance(klazz, 1);
|
||||
try { a[0] = x; }
|
||||
catch (ArrayStoreException unused) {
|
||||
throw new ClassCastException(); }}}}}
|
||||
};
|
||||
|
||||
time(filter(filter, jobs));
|
||||
}
|
||||
}
|
||||
51
test/jdk/java/lang/Class/asSubclass/BasicUnit.java
Normal file
51
test/jdk/java/lang/Class/asSubclass/BasicUnit.java
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 5030212
|
||||
* @summary please add a typesafe cast for Class<?> types
|
||||
* @author gafter
|
||||
*
|
||||
* @compile -Xlint:unchecked -Werror BasicUnit.java
|
||||
* @run main BasicUnit
|
||||
*/
|
||||
|
||||
interface Int {
|
||||
void main();
|
||||
}
|
||||
|
||||
class MyInt implements Int {
|
||||
public void main() {
|
||||
System.out.println("Hello, world!");
|
||||
}
|
||||
}
|
||||
|
||||
public class BasicUnit {
|
||||
static <T extends Int> T factory(Class<T> c) throws Throwable {
|
||||
return c.newInstance();
|
||||
}
|
||||
public static void main(String[] args) throws Throwable {
|
||||
factory(Class.forName("MyInt").asSubclass(Int.class)).main();
|
||||
}
|
||||
}
|
||||
76
test/jdk/java/lang/Class/attributes/ClassAttributesTest.java
Normal file
76
test/jdk/java/lang/Class/attributes/ClassAttributesTest.java
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8170595
|
||||
* @summary Checks Class.isAnonymousClass, isMemberClass and isLocalClass
|
||||
* attributes
|
||||
*/
|
||||
|
||||
public class ClassAttributesTest {
|
||||
|
||||
class NestedClass {}
|
||||
|
||||
static int test(Class<?> clazz, boolean anonymous, boolean local, boolean member) {
|
||||
if (clazz.isAnonymousClass() != anonymous) {
|
||||
System.err.println("Unexpected isAnonymousClass value for " +
|
||||
clazz.getName() + " expected: " + anonymous +
|
||||
" got: " + (!anonymous));
|
||||
return 1;
|
||||
}
|
||||
if (clazz.isLocalClass() != local) {
|
||||
System.err.println("Unexpected isLocalClass value for " +
|
||||
clazz.getName() + " expected: " + local +
|
||||
" got: " + (!local));
|
||||
return 1;
|
||||
}
|
||||
if (clazz.isMemberClass() != member) {
|
||||
System.err.println("Unexpected isMemberClass status for " +
|
||||
clazz.getName() + " expected: " + member +
|
||||
" got: " + (!member));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static void main(String argv[]) {
|
||||
int failures = 0;
|
||||
|
||||
class LocalClass {}
|
||||
Cloneable clone = new Cloneable() {};
|
||||
Runnable lambda = () -> System.out.println("run");
|
||||
|
||||
failures += test(ClassAttributesTest.class, false, false, false);
|
||||
failures += test(NestedClass.class, false, false, true);
|
||||
failures += test(LocalClass.class, false, true, false);
|
||||
failures += test(clone.getClass(), true, false, false);
|
||||
|
||||
// Lambdas may be hidden classes, but are named, non-local classes
|
||||
// in this sense
|
||||
failures += test(lambda.getClass(), false, false, false);
|
||||
|
||||
if (failures != 0)
|
||||
throw new RuntimeException("Test failed with " + failures + " failures.");
|
||||
}
|
||||
}
|
||||
177
test/jdk/java/lang/Class/forName/ForNameNames.java
Normal file
177
test/jdk/java/lang/Class/forName/ForNameNames.java
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8310242 8328874
|
||||
* @run junit ForNameNames
|
||||
* @summary Verify class names for Class.forName
|
||||
*/
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class ForNameNames {
|
||||
//Max length in Modified UTF-8 bytes for class names.
|
||||
private static final int JAVA_CLASSNAME_MAX_LEN = 65535;
|
||||
|
||||
private static final String ONE_BYTE = "A"; // 1-byte UTF-8
|
||||
private static final String TWO_BYTE = "\u0100"; // 2-byte UTF-8
|
||||
private static final String THREE_BYTE = "\u2600"; // 3-byte UTF-8
|
||||
|
||||
private static final String ERR_MSG_IN_CORE = "Class name length exceeds limit of"; // check in corelib
|
||||
private static final String ERR_MSG_IN_JVM = "Class name exceeds maximum length"; // check in jvm
|
||||
|
||||
static class Inner {}
|
||||
static Stream<Arguments> testCases() {
|
||||
return Stream.of(
|
||||
Arguments.of("java.lang.String", String.class),
|
||||
Arguments.of("[Ljava.lang.String;", String[].class),
|
||||
Arguments.of("ForNameNames$Inner", Inner.class),
|
||||
Arguments.of("[LForNameNames$Inner;", Inner[].class),
|
||||
Arguments.of("[[I", int[][].class)
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test 1-arg and 3-arg Class::forName. Class::getName on the returned
|
||||
* Class object returns the name passed to Class::forName.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("testCases")
|
||||
void testForName(String cn, Class<?> expected) throws ClassNotFoundException {
|
||||
ClassLoader loader = ForNameNames.class.getClassLoader();
|
||||
Class<?> c1 = Class.forName(cn, false, loader);
|
||||
assertEquals(expected, c1);
|
||||
assertEquals(cn, c1.getName());
|
||||
|
||||
Class<?> c2 = Class.forName(cn);
|
||||
assertEquals(expected, c2);
|
||||
assertEquals(cn, c2.getName());
|
||||
}
|
||||
|
||||
static Stream<Arguments> invalidNames() {
|
||||
return Stream.of(
|
||||
Arguments.of("I"), // primitive type
|
||||
Arguments.of("int[]"), // fully-qualified name of int array
|
||||
Arguments.of("ForNameNames.Inner"), // fully-qualified name of nested type
|
||||
Arguments.of("[java.lang.String"), // missing L and ;
|
||||
Arguments.of("[Ljava.lang.String"), // missing ;
|
||||
Arguments.of("[Ljava/lang/String;") // type descriptor
|
||||
|
||||
);
|
||||
}
|
||||
@ParameterizedTest
|
||||
@MethodSource("invalidNames")
|
||||
void testInvalidNames(String cn) {
|
||||
ClassLoader loader = ForNameNames.class.getClassLoader();
|
||||
assertThrows(ClassNotFoundException.class, () -> Class.forName(cn, false, loader));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testModule() {
|
||||
// Class.forName(Module, String) does not allow class name for array types
|
||||
Class<?> c = Class.forName(Object.class.getModule(), "[Ljava.lang.String;");
|
||||
assertNull(c);
|
||||
}
|
||||
|
||||
static Stream<Arguments> validLen() {
|
||||
return Stream.of(
|
||||
// 1-byte character
|
||||
Arguments.of(ONE_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN - 1)),
|
||||
Arguments.of(ONE_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN)),
|
||||
Arguments.of(ONE_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 3 - 1)),
|
||||
Arguments.of(ONE_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 3)),
|
||||
Arguments.of(ONE_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 3 + 1)),
|
||||
// 2-byte characters
|
||||
Arguments.of(TWO_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 2)),
|
||||
Arguments.of(TWO_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 6)),
|
||||
Arguments.of(TWO_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 6 + 1)),
|
||||
// 3-byte characters
|
||||
Arguments.of(THREE_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 3 - 1)),
|
||||
Arguments.of(THREE_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 3)),
|
||||
Arguments.of(THREE_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 9)),
|
||||
Arguments.of(THREE_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 9 + 1))
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test class name length handling in 1-arg and 3-arg Class::forName
|
||||
* with valid length.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("validLen")
|
||||
void testValidLen(String cn) {
|
||||
ClassLoader loader = ForNameNames.class.getClassLoader();
|
||||
// 3-arg Class.forName
|
||||
ClassNotFoundException ex = assertThrows(ClassNotFoundException.class,
|
||||
() -> Class.forName(cn, false, loader));
|
||||
assertFalse(ex.getMessage().contains(ERR_MSG_IN_CORE)
|
||||
|| ex.getMessage().contains(ERR_MSG_IN_JVM),
|
||||
"Unexpected exception message");
|
||||
|
||||
// 1-arg Class.forName
|
||||
ex = assertThrows(ClassNotFoundException.class,
|
||||
() -> Class.forName(cn));
|
||||
assertFalse(ex.getMessage().contains(ERR_MSG_IN_CORE)
|
||||
|| ex.getMessage().contains(ERR_MSG_IN_JVM),
|
||||
"Unexpected exception message");
|
||||
}
|
||||
|
||||
static Stream<Arguments> invalidLen() {
|
||||
return Stream.of(
|
||||
// 1-byte characters over the limit
|
||||
Arguments.of(ONE_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN + 1)),
|
||||
// 2-byte characters over the limit
|
||||
Arguments.of(TWO_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 2 + 1)),
|
||||
// 3-byte characters over the limit
|
||||
Arguments.of(THREE_BYTE.repeat(JAVA_CLASSNAME_MAX_LEN / 3 + 1))
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test class name length handling in 1-arg and 3-arg Class::forName
|
||||
* with invalid (too long) length.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@MethodSource("invalidLen")
|
||||
void testInvalidLen(String cn) {
|
||||
ClassLoader loader = ForNameNames.class.getClassLoader();
|
||||
// 3-arg Class.forName
|
||||
ClassNotFoundException ex = assertThrows(ClassNotFoundException.class,
|
||||
() -> Class.forName(cn, false, loader));
|
||||
assertTrue(ex.getMessage().contains(ERR_MSG_IN_CORE),
|
||||
"Unexpected exception message");
|
||||
|
||||
// 1-arg Class.forName
|
||||
ex = assertThrows(ClassNotFoundException.class,
|
||||
() -> Class.forName(cn));
|
||||
assertTrue(ex.getMessage().contains(ERR_MSG_IN_CORE),
|
||||
"Unexpected exception message");
|
||||
}
|
||||
}
|
||||
52
test/jdk/java/lang/Class/forName/InitArg.java
Normal file
52
test/jdk/java/lang/Class/forName/InitArg.java
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
@bug 4131701
|
||||
@summary This is a basic sanity test for the Class.forName
|
||||
variant that the 'whether-initialize' arg.
|
||||
*/
|
||||
|
||||
class x123 {
|
||||
static {
|
||||
InitArg.x123Initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
public class InitArg {
|
||||
|
||||
public static boolean x123Initialized = false;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Class c = Class.forName("x123", false,
|
||||
InitArg.class.getClassLoader());
|
||||
if (x123Initialized) {
|
||||
throw new Exception("forName should not run initializer");
|
||||
}
|
||||
Class d = Class.forName("x123", true,
|
||||
InitArg.class.getClassLoader());
|
||||
if (!x123Initialized) {
|
||||
throw new Exception("forName not running initializer");
|
||||
}
|
||||
}
|
||||
}
|
||||
42
test/jdk/java/lang/Class/forName/InvalidNameWithSlash.java
Normal file
42
test/jdk/java/lang/Class/forName/InvalidNameWithSlash.java
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
@bug 4104861
|
||||
@summary forName is accepting methods with slashes
|
||||
@author James Bond/007
|
||||
*/
|
||||
|
||||
public class InvalidNameWithSlash {
|
||||
public static void main(String[] args) throws Exception {
|
||||
boolean exceptionOccurred = false;
|
||||
try {
|
||||
Class c = Class.forName("java/lang.Object");
|
||||
} catch (Exception e) {
|
||||
exceptionOccurred = true;
|
||||
}
|
||||
if (!exceptionOccurred) {
|
||||
throw new Exception("forName accepting names with slashes?");
|
||||
}
|
||||
}
|
||||
}
|
||||
160
test/jdk/java/lang/Class/forName/NonJavaNames.java
Normal file
160
test/jdk/java/lang/Class/forName/NonJavaNames.java
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4952558
|
||||
* @library /test/lib
|
||||
* @run testng/othervm NonJavaNames
|
||||
* @summary Verify names that aren't legal Java names are accepted by forName.
|
||||
*/
|
||||
|
||||
public class NonJavaNames {
|
||||
public static class Baz {
|
||||
public Baz(){}
|
||||
}
|
||||
|
||||
public static interface myInterface {
|
||||
}
|
||||
|
||||
NonJavaNames.myInterface create() {
|
||||
// With target 1.5, this class's name will include a '+'
|
||||
// instead of a '$'.
|
||||
class Baz2 implements NonJavaNames.myInterface {
|
||||
public Baz2() { }
|
||||
}
|
||||
|
||||
return new Baz2();
|
||||
}
|
||||
|
||||
private static final String SRC_DIR = System.getProperty("test.src");
|
||||
private static final Path TEST_SRC = Path.of(SRC_DIR, "classes");
|
||||
private static final Path TEST_CLASSES = Path.of(System.getProperty("test.classes", "."));
|
||||
|
||||
@BeforeClass
|
||||
public void createInvalidNameClasses() throws IOException {
|
||||
Path hyphenPath = TEST_SRC.resolve("hyphen.class");
|
||||
Path commaPath = TEST_SRC.resolve("comma.class");
|
||||
Path periodPath = TEST_SRC.resolve("period.class");
|
||||
Path leftsquarePath = TEST_SRC.resolve("left-square.class");
|
||||
Path rightsquarePath = TEST_SRC.resolve("right-square.class");
|
||||
Path plusPath = TEST_SRC.resolve("plus.class");
|
||||
Path semicolonPath = TEST_SRC.resolve("semicolon.class");
|
||||
Path zeroPath = TEST_SRC.resolve("0.class");
|
||||
Path threePath = TEST_SRC.resolve("3.class");
|
||||
Path zadePath = TEST_SRC.resolve("Z.class");
|
||||
|
||||
Path dhyphenPath = TEST_CLASSES.resolve("-.class");
|
||||
Path dcommaPath = TEST_CLASSES.resolve(",.class");
|
||||
Path dperiodPath = TEST_CLASSES.resolve("..class");
|
||||
Path dleftsquarePath = TEST_CLASSES.resolve("[.class");
|
||||
Path drightsquarePath = TEST_CLASSES.resolve("].class");
|
||||
Path dplusPath = TEST_CLASSES.resolve("+.class");
|
||||
Path dsemicolonPath = TEST_CLASSES.resolve(";.class");
|
||||
Path dzeroPath = TEST_CLASSES.resolve("0.class");
|
||||
Path dthreePath = TEST_CLASSES.resolve("3.class");
|
||||
Path dzadePath = TEST_CLASSES.resolve("Z.class");
|
||||
|
||||
Files.copy(hyphenPath, dhyphenPath, REPLACE_EXISTING);
|
||||
Files.copy(commaPath, dcommaPath, REPLACE_EXISTING);
|
||||
Files.copy(periodPath, dperiodPath, REPLACE_EXISTING);
|
||||
Files.copy(leftsquarePath, dleftsquarePath, REPLACE_EXISTING);
|
||||
Files.copy(rightsquarePath, drightsquarePath, REPLACE_EXISTING);
|
||||
Files.copy(plusPath, dplusPath, REPLACE_EXISTING);
|
||||
Files.copy(semicolonPath, dsemicolonPath, REPLACE_EXISTING);
|
||||
Files.copy(zeroPath, dzeroPath, REPLACE_EXISTING);
|
||||
Files.copy(threePath, dthreePath, REPLACE_EXISTING);
|
||||
Files.copy(zadePath, dzadePath, REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForNameReturnsSameClass() throws ClassNotFoundException {
|
||||
NonJavaNames.Baz bz = new NonJavaNames.Baz();
|
||||
String name;
|
||||
|
||||
if (Class.forName(name=bz.getClass().getName()) != NonJavaNames.Baz.class) {
|
||||
System.err.println("Class object from forName does not match object.class.");
|
||||
System.err.println("Failures for class ``" + name + "''.");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
NonJavaNames.myInterface bz2 = (new NonJavaNames()).create();
|
||||
if (Class.forName(name=bz2.getClass().getName()) != bz2.getClass()) {
|
||||
System.err.println("Class object from forName does not match getClass.");
|
||||
System.err.println("Failures for class ``" + name + "''.");
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dataProvider = "goodNonJavaClassNames")
|
||||
public void testGoodNonJavaClassNames(String name) throws ClassNotFoundException {
|
||||
System.out.println("Testing good class name ``" + name + "''");
|
||||
Class.forName(name);
|
||||
}
|
||||
|
||||
@Test(dataProvider = "badNonJavaClassNames")
|
||||
public void testBadNonJavaClassNames(String name) {
|
||||
System.out.println("Testing bad class name ``" + name + "''");
|
||||
try {
|
||||
Class.forName(name);
|
||||
} catch (ClassNotFoundException e) {
|
||||
// Expected behavior
|
||||
return;
|
||||
}
|
||||
throw new RuntimeException("Bad class name ``" + name + "'' accepted.");
|
||||
}
|
||||
|
||||
@DataProvider(name = "goodNonJavaClassNames")
|
||||
Object[][] getGoodNonJavaClassNames() {
|
||||
return new Object[][] {
|
||||
{","},
|
||||
{"+"},
|
||||
{"-"},
|
||||
{"0"},
|
||||
{"3"},
|
||||
// ":", These names won't work under windows.
|
||||
// "<",
|
||||
// ">",
|
||||
{"Z"},
|
||||
{"]"}
|
||||
};
|
||||
}
|
||||
|
||||
@DataProvider(name = "badNonJavaClassNames")
|
||||
Object[][] getBadNonJavaClassNames() {
|
||||
return new Object[][] {
|
||||
{";"},
|
||||
{"["},
|
||||
{"."}
|
||||
};
|
||||
}
|
||||
}
|
||||
31
test/jdk/java/lang/Class/forName/NonLinking/Container.java
Normal file
31
test/jdk/java/lang/Class/forName/NonLinking/Container.java
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
public class Container {
|
||||
|
||||
public Container(MissingClass m) {}
|
||||
|
||||
public Container() {
|
||||
this(new MissingClass() {});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
public class MissingClass {}
|
||||
77
test/jdk/java/lang/Class/forName/NonLinking/NonLinking.java
Normal file
77
test/jdk/java/lang/Class/forName/NonLinking/NonLinking.java
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8231924 8233091 8233272
|
||||
* @summary Confirm load (but not link) behavior of Class.forName()
|
||||
* @library /test/lib
|
||||
*
|
||||
* @compile MissingClass.java Container.java
|
||||
*
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller -jar classes.jar Container Container$1
|
||||
*
|
||||
* @run main/othervm NonLinking init
|
||||
* @run main/othervm NonLinking load
|
||||
*/
|
||||
/*
|
||||
* The @compile and '@main ClassFileInstaller' tasks above create a classes.jar
|
||||
* file containing the .class file for Container, but not MissingClass.
|
||||
*/
|
||||
|
||||
public class NonLinking {
|
||||
public static void main(String[] args) throws Throwable {
|
||||
Path jarPath = Paths.get("classes.jar");
|
||||
URL url = jarPath.toUri().toURL();
|
||||
URLClassLoader ucl1 = new URLClassLoader("UCL1",
|
||||
new URL[] { url },
|
||||
null); // Don't delegate
|
||||
switch(args[0]) {
|
||||
case "init":
|
||||
try {
|
||||
// Trying to initialize Container without MissingClass -> NCDFE
|
||||
Class.forName("Container", true, ucl1);
|
||||
throw new RuntimeException("Missed expected NoClassDefFoundError");
|
||||
} catch (NoClassDefFoundError expected) {
|
||||
final String CLASSNAME = "MissingClass";
|
||||
Throwable cause = expected.getCause();
|
||||
if (!cause.getMessage().contains(CLASSNAME)) {
|
||||
throw new RuntimeException("Cause of NoClassDefFoundError does not contain \"" + CLASSNAME + "\"", cause);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "load":
|
||||
// Loading (but not linking) Container will succeed.
|
||||
// Before 8233091, this fails with NCDFE due to linking.
|
||||
Class.forName("Container", false, ucl1);
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("Unknown command: " + args[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
32
test/jdk/java/lang/Class/forName/Z.java
Normal file
32
test/jdk/java/lang/Class/forName/Z.java
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Source used to generated primordial class file for NonJavaNames
|
||||
* test.
|
||||
*/
|
||||
public class Z {
|
||||
public static void main(String argv[]) {
|
||||
System.out.println("Hello world.");
|
||||
}
|
||||
}
|
||||
24
test/jdk/java/lang/Class/forName/arrayClass/Class1.java
Normal file
24
test/jdk/java/lang/Class/forName/arrayClass/Class1.java
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
public class Class1 {}
|
||||
24
test/jdk/java/lang/Class/forName/arrayClass/Class2.java
Normal file
24
test/jdk/java/lang/Class/forName/arrayClass/Class2.java
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
public class Class2 {}
|
||||
24
test/jdk/java/lang/Class/forName/arrayClass/Class3.java
Normal file
24
test/jdk/java/lang/Class/forName/arrayClass/Class3.java
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
public class Class3 {}
|
||||
24
test/jdk/java/lang/Class/forName/arrayClass/Class4.java
Normal file
24
test/jdk/java/lang/Class/forName/arrayClass/Class4.java
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
public class Class4 {}
|
||||
129
test/jdk/java/lang/Class/forName/arrayClass/ExceedMaxDim.java
Normal file
129
test/jdk/java/lang/Class/forName/arrayClass/ExceedMaxDim.java
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 7044282
|
||||
* @build Class1 Class2 Class3 Class4
|
||||
* @run main ExceedMaxDim
|
||||
* @summary Make sure you can't get an array class of dimension > 255.
|
||||
*/
|
||||
|
||||
// Class1, Class2, Class3 and Class4 should not have been loaded prior to the
|
||||
// calls to forName
|
||||
|
||||
public class ExceedMaxDim {
|
||||
//0123456789012345678901234567890123456789
|
||||
private String brackets = "[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" +
|
||||
"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" +
|
||||
"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" +
|
||||
"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" +
|
||||
"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" +
|
||||
"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[" +
|
||||
"[[[[[[[[[[[[[[";
|
||||
private String name254 = brackets + "Ljava.lang.String;";
|
||||
private String name255 = "[" + name254;
|
||||
private String name256 = "[" + name255;
|
||||
private String name1 = "[Ljava.lang.String;";
|
||||
private String bigName;
|
||||
private int error = 0;
|
||||
|
||||
private static final ClassLoader IMPLICIT_LOADER = null;
|
||||
|
||||
public ExceedMaxDim() {
|
||||
super();
|
||||
|
||||
StringBuilder sb = new StringBuilder(Short.MAX_VALUE + 50);
|
||||
for (int i = 0; i < Short.MAX_VALUE + 20; i++)
|
||||
sb.append('[');
|
||||
sb.append("Ljava.lang.String;");
|
||||
bigName = sb.toString();
|
||||
|
||||
if (name256.lastIndexOf('[') != 255) // 256:th [
|
||||
throw new RuntimeException("Test broken");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ExceedMaxDim test = new ExceedMaxDim();
|
||||
test.testImplicitLoader();
|
||||
test.testOtherLoader();
|
||||
|
||||
if (test.error != 0)
|
||||
throw new RuntimeException("Test failed, was able to create array with dim > 255." +
|
||||
" See log for details.");
|
||||
}
|
||||
|
||||
private void testImplicitLoader() throws Exception {
|
||||
// These four should succeed
|
||||
assertSucceedForName(name1, IMPLICIT_LOADER);
|
||||
assertSucceedForName(name254, IMPLICIT_LOADER);
|
||||
assertSucceedForName(name255, IMPLICIT_LOADER);
|
||||
assertSucceedForName(brackets + "[LClass1;", IMPLICIT_LOADER);
|
||||
|
||||
// The following three should fail
|
||||
assertFailForName(name256, IMPLICIT_LOADER);
|
||||
assertFailForName(bigName, IMPLICIT_LOADER);
|
||||
assertFailForName(brackets + "[[LClass2;", IMPLICIT_LOADER);
|
||||
}
|
||||
|
||||
private void testOtherLoader() throws Exception {
|
||||
ClassLoader cl = ExceedMaxDim.class.getClassLoader();
|
||||
|
||||
// These four should succeed
|
||||
assertSucceedForName(name1, cl);
|
||||
assertSucceedForName(name254,cl);
|
||||
assertSucceedForName(name255, cl);
|
||||
assertSucceedForName(brackets + "[LClass3;", cl);
|
||||
|
||||
// The following three should fail
|
||||
assertFailForName(name256, cl);
|
||||
assertFailForName(bigName, cl);
|
||||
assertFailForName(brackets + "[[Class4;", cl);
|
||||
}
|
||||
|
||||
private void assertFailForName(String name, ClassLoader cl) {
|
||||
Class<?> c;
|
||||
try {
|
||||
if (cl == null)
|
||||
c = Class.forName(name);
|
||||
else
|
||||
c = Class.forName(name, true, cl);
|
||||
error++;
|
||||
System.err.println("ERROR: could create " + c);
|
||||
} catch (ClassNotFoundException e) {
|
||||
;// ok
|
||||
}
|
||||
}
|
||||
|
||||
private void assertSucceedForName(String name, ClassLoader cl) {
|
||||
Class<?> c;
|
||||
try {
|
||||
if (cl == null)
|
||||
c = Class.forName(name);
|
||||
else
|
||||
c = Class.forName(name, true, cl);
|
||||
} catch (ClassNotFoundException e) {
|
||||
error++;
|
||||
System.err.println("ERROR: could not create " + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
test/jdk/java/lang/Class/forName/classes/0.class
Normal file
BIN
test/jdk/java/lang/Class/forName/classes/0.class
Normal file
Binary file not shown.
BIN
test/jdk/java/lang/Class/forName/classes/3.class
Normal file
BIN
test/jdk/java/lang/Class/forName/classes/3.class
Normal file
Binary file not shown.
BIN
test/jdk/java/lang/Class/forName/classes/Z.class
Normal file
BIN
test/jdk/java/lang/Class/forName/classes/Z.class
Normal file
Binary file not shown.
BIN
test/jdk/java/lang/Class/forName/classes/comma.class
Normal file
BIN
test/jdk/java/lang/Class/forName/classes/comma.class
Normal file
Binary file not shown.
BIN
test/jdk/java/lang/Class/forName/classes/hyphen.class
Normal file
BIN
test/jdk/java/lang/Class/forName/classes/hyphen.class
Normal file
Binary file not shown.
BIN
test/jdk/java/lang/Class/forName/classes/left-square.class
Normal file
BIN
test/jdk/java/lang/Class/forName/classes/left-square.class
Normal file
Binary file not shown.
BIN
test/jdk/java/lang/Class/forName/classes/period.class
Normal file
BIN
test/jdk/java/lang/Class/forName/classes/period.class
Normal file
Binary file not shown.
BIN
test/jdk/java/lang/Class/forName/classes/plus.class
Normal file
BIN
test/jdk/java/lang/Class/forName/classes/plus.class
Normal file
Binary file not shown.
BIN
test/jdk/java/lang/Class/forName/classes/right-square.class
Normal file
BIN
test/jdk/java/lang/Class/forName/classes/right-square.class
Normal file
Binary file not shown.
BIN
test/jdk/java/lang/Class/forName/classes/semicolon.class
Normal file
BIN
test/jdk/java/lang/Class/forName/classes/semicolon.class
Normal file
Binary file not shown.
134
test/jdk/java/lang/Class/forName/modules/TestDriver.java
Normal file
134
test/jdk/java/lang/Class/forName/modules/TestDriver.java
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import jdk.test.lib.util.FileUtils;
|
||||
import jdk.test.lib.compiler.CompilerUtils;
|
||||
import static jdk.test.lib.process.ProcessTools.*;
|
||||
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8087335
|
||||
* @summary Tests for Class.forName(Module,String)
|
||||
* @library /test/lib
|
||||
* @modules jdk.compiler
|
||||
* @build jdk.test.lib.Platform
|
||||
* jdk.test.lib.util.FileUtils
|
||||
* jdk.test.lib.compiler.CompilerUtils
|
||||
* jdk.test.lib.process.ProcessTools
|
||||
* TestDriver TestMain TestLayer
|
||||
* @run testng TestDriver
|
||||
*/
|
||||
|
||||
public class TestDriver {
|
||||
|
||||
private static final String TEST_SRC =
|
||||
Paths.get(System.getProperty("test.src")).toString();
|
||||
private static final String TEST_CLASSES =
|
||||
Paths.get(System.getProperty("test.classes")).toString();
|
||||
|
||||
private static final Path MOD_SRC_DIR = Paths.get(TEST_SRC, "src");
|
||||
private static final Path MOD_DEST_DIR = Paths.get("mods");
|
||||
|
||||
private static final String[] modules = new String[] {"m1", "m2"};
|
||||
|
||||
/**
|
||||
* Compiles all modules used by the test.
|
||||
*/
|
||||
@BeforeClass
|
||||
public void setup() throws Exception {
|
||||
assertTrue(CompilerUtils.compile(
|
||||
MOD_SRC_DIR, MOD_DEST_DIR,
|
||||
"--module-source-path",
|
||||
MOD_SRC_DIR.toString()));
|
||||
|
||||
copyDirectories(MOD_DEST_DIR.resolve("m1"), Paths.get("mods1"));
|
||||
copyDirectories(MOD_DEST_DIR.resolve("m2"), Paths.get("mods2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
String[] options = new String[] {
|
||||
"-cp", TEST_CLASSES,
|
||||
"--module-path", MOD_DEST_DIR.toString(),
|
||||
"--add-modules", String.join(",", modules),
|
||||
"-m", "m2/p2.test.Main"
|
||||
};
|
||||
runTest(options);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnnamedModule() throws Exception {
|
||||
String[] options = new String[] {
|
||||
"-cp", TEST_CLASSES,
|
||||
"--module-path", MOD_DEST_DIR.toString(),
|
||||
"--add-modules", String.join(",", modules),
|
||||
"TestMain"
|
||||
};
|
||||
runTest(options);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLayer() throws Exception {
|
||||
String[] options = new String[] {
|
||||
"-cp", TEST_CLASSES,
|
||||
"TestLayer"
|
||||
};
|
||||
|
||||
runTest(options);
|
||||
}
|
||||
|
||||
private void runTest(String[] options) throws Exception {
|
||||
assertTrue(executeTestJava(options)
|
||||
.outputTo(System.out)
|
||||
.errorTo(System.err)
|
||||
.getExitValue() == 0);
|
||||
}
|
||||
|
||||
private void copyDirectories(Path source, Path dest) throws IOException {
|
||||
if (Files.exists(dest))
|
||||
FileUtils.deleteFileTreeWithRetry(dest);
|
||||
Files.walk(source, Integer.MAX_VALUE)
|
||||
.filter(Files::isRegularFile)
|
||||
.forEach(p -> {
|
||||
try {
|
||||
Path to = dest.resolve(source.relativize(p));
|
||||
Files.createDirectories(to.getParent());
|
||||
Files.copy(p, to);
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
80
test/jdk/java/lang/Class/forName/modules/TestLayer.java
Normal file
80
test/jdk/java/lang/Class/forName/modules/TestLayer.java
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.lang.module.Configuration;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Set;
|
||||
|
||||
public class TestLayer {
|
||||
private static final Path MODS_DIR = Paths.get("mods");
|
||||
private static final Set<String> modules = Set.of("m1", "m2");
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ModuleFinder finder = ModuleFinder.of(MODS_DIR);
|
||||
|
||||
Configuration parent = ModuleLayer.boot().configuration();
|
||||
Configuration cf = parent.resolveAndBind(ModuleFinder.of(),
|
||||
finder,
|
||||
modules);
|
||||
|
||||
ClassLoader scl = ClassLoader.getSystemClassLoader();
|
||||
ModuleLayer layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, scl);
|
||||
|
||||
Module m1 = layer.findModule("m1").get();
|
||||
Module m2 = layer.findModule("m2").get();
|
||||
|
||||
// find exported and non-exported class from a named module
|
||||
findClass(m1, "p1.A");
|
||||
findClass(m1, "p1.internal.B");
|
||||
findClass(m2, "p2.C");
|
||||
|
||||
// find class from unnamed module
|
||||
ClassLoader ld = TestLayer.class.getClassLoader();
|
||||
findClass(ld.getUnnamedModule(), "TestDriver");
|
||||
|
||||
// check if clinit should not be initialized
|
||||
// compile without module-path; so use reflection
|
||||
Class<?> c = Class.forName(m1, "p1.Initializer");
|
||||
Method m = c.getMethod("isInited");
|
||||
Boolean isClinited = (Boolean) m.invoke(null);
|
||||
if (isClinited.booleanValue()) {
|
||||
throw new RuntimeException("clinit should not be invoked");
|
||||
}
|
||||
}
|
||||
|
||||
static Class<?> findClass(Module module, String cn) {
|
||||
Class<?> c = Class.forName(module, cn);
|
||||
if (c == null) {
|
||||
throw new RuntimeException(cn + " not found in " + module);
|
||||
}
|
||||
if (c.getModule() != module) {
|
||||
throw new RuntimeException(c.getModule() + " != " + module);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
61
test/jdk/java/lang/Class/forName/modules/TestMain.java
Normal file
61
test/jdk/java/lang/Class/forName/modules/TestMain.java
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class TestMain {
|
||||
public static void main(String[] args) throws Exception {
|
||||
ModuleLayer boot = ModuleLayer.boot();
|
||||
Module m1 = boot.findModule("m1").get();
|
||||
Module m2 = boot.findModule("m2").get();
|
||||
|
||||
// find exported and non-exported class from a named module
|
||||
findClass(m1, "p1.A");
|
||||
findClass(m1, "p1.internal.B");
|
||||
findClass(m2, "p2.C");
|
||||
|
||||
// find class from unnamed module
|
||||
ClassLoader loader = TestMain.class.getClassLoader();
|
||||
findClass(loader.getUnnamedModule(), "TestDriver");
|
||||
|
||||
// check if clinit should not be initialized
|
||||
// compile without module-path; so use reflection
|
||||
Class<?> c = Class.forName(m1, "p1.Initializer");
|
||||
Method m = c.getMethod("isInited");
|
||||
Boolean isClinited = (Boolean) m.invoke(null);
|
||||
if (isClinited.booleanValue()) {
|
||||
throw new RuntimeException("clinit should not be invoked");
|
||||
}
|
||||
}
|
||||
|
||||
static Class<?> findClass(Module module, String cn) {
|
||||
Class<?> c = Class.forName(module, cn);
|
||||
if (c == null) {
|
||||
throw new RuntimeException(cn + " not found in " + module);
|
||||
}
|
||||
if (c.getModule() != module) {
|
||||
throw new RuntimeException(c.getModule() + " != " + module);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
module m1 {
|
||||
exports p1;
|
||||
}
|
||||
31
test/jdk/java/lang/Class/forName/modules/src/m1/p1/A.java
Normal file
31
test/jdk/java/lang/Class/forName/modules/src/m1/p1/A.java
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package p1;
|
||||
|
||||
public class A {
|
||||
static {
|
||||
Initializer.init();
|
||||
System.out.println("p1.A is initialzed");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package p1;
|
||||
|
||||
public class Initializer {
|
||||
private static boolean inited = false;
|
||||
static synchronized void init() {
|
||||
inited = true;
|
||||
}
|
||||
public static synchronized boolean isInited() {
|
||||
return inited;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package p1.internal;
|
||||
|
||||
public class B {
|
||||
public B() {}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
module m2 {
|
||||
exports p2;
|
||||
}
|
||||
27
test/jdk/java/lang/Class/forName/modules/src/m2/p2/C.java
Normal file
27
test/jdk/java/lang/Class/forName/modules/src/m2/p2/C.java
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package p2;
|
||||
|
||||
public class C {
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package p2.test;
|
||||
|
||||
public class Main {
|
||||
public static void main(String... args) throws Exception {
|
||||
ModuleLayer boot = ModuleLayer.boot();
|
||||
Module m1 = boot.findModule("m1").get();
|
||||
Module m2 = Main.class.getModule();
|
||||
|
||||
// find exported and non-exported class from a named module
|
||||
findClass(m1, "p1.A");
|
||||
findClass(m1, "p1.internal.B");
|
||||
findClass(m2, "p2.C");
|
||||
|
||||
// find class from unnamed module
|
||||
ClassLoader loader = m2.getClassLoader();
|
||||
findClass(loader.getUnnamedModule(), "TestDriver");
|
||||
|
||||
try {
|
||||
Class<?> c = findClass(m1, "p1.internal.B");
|
||||
c.newInstance();
|
||||
throw new RuntimeException(c.getName() + " should not be exported to m2");
|
||||
} catch (IllegalAccessException e) {}
|
||||
}
|
||||
|
||||
static Class<?> findClass(Module module, String cn) {
|
||||
Class<?> c = Class.forName(module, cn);
|
||||
if (c == null) {
|
||||
throw new RuntimeException(cn + " not found in " + module);
|
||||
}
|
||||
if (c.getModule() != module) {
|
||||
throw new RuntimeException(c.getModule() + " != " + module);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
52
test/jdk/java/lang/Class/getClasses/Sanity.java
Normal file
52
test/jdk/java/lang/Class/getClasses/Sanity.java
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
@bug 4028577
|
||||
@summary Sanity check that Class.getClasses() works.
|
||||
@author Anand Palaniswamy
|
||||
*/
|
||||
public class Sanity {
|
||||
public class Base {
|
||||
public class BInner { }
|
||||
protected class BProtected { }
|
||||
class BPackage { }
|
||||
}
|
||||
|
||||
public class Derived extends Base {
|
||||
public class DInner { }
|
||||
protected class DProtected { }
|
||||
class DPackage { }
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Class[] c = Derived.class.getClasses();
|
||||
if (c.length != 2)
|
||||
throw new Exception("Incorrect number of public classes returned");
|
||||
for (int i = 0; i < c.length; i++) {
|
||||
if (c[i] != Base.BInner.class &&
|
||||
c[i] != Derived.DInner.class)
|
||||
throw new Exception("Garbage in declared classes");
|
||||
}
|
||||
}
|
||||
}
|
||||
48
test/jdk/java/lang/Class/getDeclaredClasses/Sanity.java
Normal file
48
test/jdk/java/lang/Class/getDeclaredClasses/Sanity.java
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2002, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 4028577 4726689
|
||||
* @summary Sanity check that Class.getDeclaredClasses() works.
|
||||
*/
|
||||
public class Sanity {
|
||||
static class Toplevel { }
|
||||
class Nested { }
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
class BlockLocal { };
|
||||
new Object() { };
|
||||
Class[] c = Sanity.class.getDeclaredClasses();
|
||||
if (c.length < 2)
|
||||
throw new Exception("Incorrect number of declared classes");
|
||||
|
||||
for (int i = 0; i < c.length; i++) {
|
||||
String name = c[i].getName();
|
||||
System.out.println(name);
|
||||
|
||||
if (c[i] != Nested.class && c[i] != Toplevel.class
|
||||
&& !name.matches("\\D\\w*\\$\\d*"))
|
||||
throw new Exception("Unexpected class: " + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
62
test/jdk/java/lang/Class/getDeclaredClasses/TypeTag.java
Normal file
62
test/jdk/java/lang/Class/getDeclaredClasses/TypeTag.java
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2002, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 4185857 4726689
|
||||
* @summary The array returned by getDeclaredClasses doesn't have the
|
||||
* array element type tag.
|
||||
*/
|
||||
public class TypeTag {
|
||||
|
||||
private static class Inner { }
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Class[] v = null;
|
||||
|
||||
v = Integer.TYPE.getDeclaredClasses();
|
||||
if (v == null || v.length != 0)
|
||||
throw new Exception("Integer.TYPE.getDeclaredClasses is not working");
|
||||
System.out.println("Integer.TYPE: "+ v.toString());
|
||||
|
||||
v = TypeTag.class.getDeclaredClasses();
|
||||
if (v == null)
|
||||
throw new Exception("TypeTag.class.getDeclaredClasses returned null");
|
||||
System.out.println("TypeTag.class: " + v.toString());
|
||||
|
||||
int n = 0;
|
||||
for (int i = 0; i < v.length; i++) {
|
||||
String name = v[i].getName();
|
||||
System.out.print(name);
|
||||
|
||||
if (!name.matches("\\D\\w*\\$\\d*")) {
|
||||
n++;
|
||||
System.out.println(" -- user class");
|
||||
} else {
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
if (n != 1)
|
||||
throw new Exception("TypeTag.class.getDeclaredClasses found too many classes");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8065552
|
||||
* @summary test that all fields returned by getDeclaredFields() can be
|
||||
* set accessible if package java.lang is open to unnamed module;
|
||||
* this test also verifies that Class.classLoader final private field
|
||||
* is hidden from reflection access.
|
||||
* @modules java.base/java.lang:open
|
||||
* @run main/othervm ClassDeclaredFieldsTest
|
||||
*
|
||||
* @author danielfuchs
|
||||
*/
|
||||
public class ClassDeclaredFieldsTest {
|
||||
/**
|
||||
* @param args the command line arguments
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println(System.getProperty("java.version"));
|
||||
for (Field f : Class.class.getDeclaredFields()) {
|
||||
f.setAccessible(true);
|
||||
System.out.println("Field "+f.getName()+" is now accessible.");
|
||||
if (f.getName().equals("classLoader")) {
|
||||
throw new RuntimeException("Found "+f.getName()+" field!");
|
||||
}
|
||||
}
|
||||
try {
|
||||
Class.class.getDeclaredField("classLoader");
|
||||
throw new RuntimeException("Expected NoSuchFieldException for"
|
||||
+ " 'classLoader' field not raised");
|
||||
} catch(NoSuchFieldException x) {
|
||||
System.out.println("Got expected exception: " + x);
|
||||
}
|
||||
System.out.println("Passed");
|
||||
}
|
||||
}
|
||||
64
test/jdk/java/lang/Class/getDeclaredField/Exceptions.java
Normal file
64
test/jdk/java/lang/Class/getDeclaredField/Exceptions.java
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 4319910
|
||||
* @summary Verify that exceptions are thrown as expected.
|
||||
*/
|
||||
|
||||
public class Exceptions {
|
||||
int f0;
|
||||
public int f1;
|
||||
private int f2;
|
||||
protected int f4;
|
||||
|
||||
private static final String [] npe = {null};
|
||||
private static final String [] nsfe = {"f6"};
|
||||
private static final String [] pass = {"f0", "f1", "f2", "f4"};
|
||||
|
||||
private void test(String s, Class ex) {
|
||||
Throwable t = null;
|
||||
try {
|
||||
getClass().getDeclaredField(s);
|
||||
} catch (Throwable x) {
|
||||
if (ex.isAssignableFrom(x.getClass()))
|
||||
t = x;
|
||||
}
|
||||
if ((t == null) && (ex != null))
|
||||
throw new RuntimeException("expected " + ex.getName()
|
||||
+ " for " + s);
|
||||
else
|
||||
System.out.println(s + " OK");
|
||||
}
|
||||
|
||||
public static void main(String [] args) {
|
||||
Exceptions e = new Exceptions();
|
||||
for (int i = 0; i < npe.length; i++)
|
||||
e.test(npe[i], NullPointerException.class);
|
||||
for (int i = 0; i < nsfe.length; i++)
|
||||
e.test(nsfe[i], NoSuchFieldException.class);
|
||||
for (int i = 0; i < pass.length; i++)
|
||||
e.test(pass[i], null);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,330 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.lang.module.ModuleDescriptor;
|
||||
import java.lang.module.ModuleFinder;
|
||||
import java.lang.module.ModuleReference;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.InaccessibleObjectException;
|
||||
import java.net.URI;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import jdk.internal.module.Modules;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8065552 8309532
|
||||
* @summary test that all public fields returned by getDeclaredFields() can
|
||||
* be set accessible; this test
|
||||
* loads all classes and get their declared fields
|
||||
* and call setAccessible(false) followed by setAccessible(true);
|
||||
* @modules java.base/jdk.internal.module
|
||||
* @run main/othervm/timeout=480 --add-modules=ALL-SYSTEM FieldSetAccessibleTest
|
||||
*
|
||||
* @author danielfuchs
|
||||
*/
|
||||
public class FieldSetAccessibleTest {
|
||||
|
||||
static final List<String> cantread = new ArrayList<>();
|
||||
static final List<String> failed = new ArrayList<>();
|
||||
static final AtomicLong classCount = new AtomicLong();
|
||||
static final AtomicLong fieldCount = new AtomicLong();
|
||||
static long startIndex = 0;
|
||||
static long maxSize = Long.MAX_VALUE;
|
||||
static long maxIndex = Long.MAX_VALUE;
|
||||
static final ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
|
||||
|
||||
|
||||
// Test that all fields for any given class can be made accessibles
|
||||
static void testSetFieldsAccessible(Class<?> c) {
|
||||
Module self = FieldSetAccessibleTest.class.getModule();
|
||||
Module target = c.getModule();
|
||||
String pn = c.getPackageName();
|
||||
boolean exported = self.canRead(target) && target.isExported(pn, self);
|
||||
for (Field f : c.getDeclaredFields()) {
|
||||
fieldCount.incrementAndGet();
|
||||
|
||||
// setAccessible succeeds only if it's exported and the member
|
||||
// is public and of a public class, or it's opened
|
||||
// otherwise it would fail.
|
||||
boolean isPublic = Modifier.isPublic(f.getModifiers()) &&
|
||||
Modifier.isPublic(c.getModifiers());
|
||||
boolean access = (exported && isPublic) || target.isOpen(pn, self);
|
||||
try {
|
||||
f.setAccessible(false);
|
||||
f.setAccessible(true);
|
||||
if (!access) {
|
||||
throw new RuntimeException(
|
||||
String.format("Expected InaccessibleObjectException is not thrown "
|
||||
+ "for field %s in class %s%n", f.getName(), c.getName()));
|
||||
}
|
||||
} catch (InaccessibleObjectException expected) {
|
||||
if (access) {
|
||||
throw new RuntimeException(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Performs a series of test on the given class.
|
||||
// At this time, we only call testSetFieldsAccessible(c)
|
||||
public static boolean test(Class<?> c, boolean addExports) {
|
||||
Module self = FieldSetAccessibleTest.class.getModule();
|
||||
Module target = c.getModule();
|
||||
String pn = c.getPackageName();
|
||||
boolean exported = self.canRead(target) && target.isExported(pn, self);
|
||||
if (addExports && !exported) {
|
||||
Modules.addExports(target, pn, self);
|
||||
exported = true;
|
||||
}
|
||||
|
||||
classCount.incrementAndGet();
|
||||
|
||||
// Call getDeclaredFields() and try to set their accessible flag.
|
||||
testSetFieldsAccessible(c);
|
||||
|
||||
// add more tests here...
|
||||
|
||||
return c == Class.class;
|
||||
}
|
||||
|
||||
// Prints a summary at the end of the test.
|
||||
static void printSummary(long secs, long millis, long nanos) {
|
||||
System.out.println("Tested " + fieldCount.get() + " fields of "
|
||||
+ classCount.get() + " classes in "
|
||||
+ secs + "s " + millis + "ms " + nanos + "ns");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param args the command line arguments:
|
||||
*
|
||||
* [startIndex (default=0)] [maxSize (default=Long.MAX_VALUE)]
|
||||
*
|
||||
* @throws java.lang.Exception if the test fails
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args == null || args.length == 0) {
|
||||
args = new String[] {"0"};
|
||||
} else if (args.length > 2) {
|
||||
throw new RuntimeException("Expected at most one argument. Found "
|
||||
+ Arrays.asList(args));
|
||||
}
|
||||
try {
|
||||
if (args.length > 0) {
|
||||
startIndex = Long.parseLong(args[0]);
|
||||
if (startIndex < 0) {
|
||||
throw new IllegalArgumentException("startIndex args[0]: "
|
||||
+ startIndex);
|
||||
}
|
||||
}
|
||||
if (args.length > 1) {
|
||||
maxSize = Long.parseLong(args[1]);
|
||||
if (maxSize <= 0) {
|
||||
maxSize = Long.MAX_VALUE;
|
||||
}
|
||||
maxIndex = (Long.MAX_VALUE - startIndex) < maxSize
|
||||
? Long.MAX_VALUE : startIndex + maxSize;
|
||||
}
|
||||
test(listAllClassNames());
|
||||
} catch (OutOfMemoryError oome) {
|
||||
System.err.println(classCount.get());
|
||||
throw oome;
|
||||
}
|
||||
}
|
||||
|
||||
static Iterable<String> listAllClassNames() {
|
||||
return new ClassNameJrtStreamBuilder();
|
||||
}
|
||||
|
||||
static void test(Iterable<String> iterable) {
|
||||
final long start = System.nanoTime();
|
||||
boolean classFound = false;
|
||||
int index = 0;
|
||||
for (String s : iterable) {
|
||||
if (index == maxIndex) break;
|
||||
try {
|
||||
if (index < startIndex) continue;
|
||||
if (test(s, false)) {
|
||||
classFound = true;
|
||||
}
|
||||
} finally {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
// Re-test with all packages exported
|
||||
for (String s : iterable) {
|
||||
test(s, true);
|
||||
}
|
||||
|
||||
classCount.set(classCount.get() / 2);
|
||||
fieldCount.set(fieldCount.get() / 2);
|
||||
long elapsed = System.nanoTime() - start;
|
||||
long secs = elapsed / 1000_000_000;
|
||||
long millis = (elapsed % 1000_000_000) / 1000_000;
|
||||
long nanos = elapsed % 1000_000;
|
||||
System.out.println("Unreadable path elements: " + cantread);
|
||||
System.out.println("Failed path elements: " + failed);
|
||||
printSummary(secs, millis, nanos);
|
||||
|
||||
if (!failed.isEmpty()) {
|
||||
throw new RuntimeException("Test failed for the following classes: " + failed);
|
||||
}
|
||||
if (!classFound && startIndex == 0 && index < maxIndex) {
|
||||
// this is just to verify that we have indeed parsed the java.base module
|
||||
throw new RuntimeException("Test failed: Class.class not found...");
|
||||
}
|
||||
if (classCount.get() == 0 && startIndex == 0) {
|
||||
throw new RuntimeException("Test failed: no class found?");
|
||||
}
|
||||
}
|
||||
|
||||
static boolean test(String s, boolean addExports) {
|
||||
String clsName = s.replace('/', '.').substring(0, s.length() - 6);
|
||||
try {
|
||||
System.out.println("Loading " + clsName);
|
||||
final Class<?> c = Class.forName(
|
||||
clsName,
|
||||
false,
|
||||
systemClassLoader);
|
||||
return test(c, addExports);
|
||||
} catch (VerifyError ve) {
|
||||
System.err.println("VerifyError for " + clsName);
|
||||
ve.printStackTrace(System.err);
|
||||
failed.add(s);
|
||||
} catch (Exception t) {
|
||||
t.printStackTrace(System.err);
|
||||
failed.add(s);
|
||||
} catch (NoClassDefFoundError e) {
|
||||
e.printStackTrace(System.err);
|
||||
failed.add(s);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static class ClassNameJrtStreamBuilder implements Iterable<String>{
|
||||
|
||||
final FileSystem jrt;
|
||||
final Path root;
|
||||
final Set<String> modules;
|
||||
ClassNameJrtStreamBuilder() {
|
||||
jrt = FileSystems.getFileSystem(URI.create("jrt:/"));
|
||||
root = jrt.getPath("/modules");
|
||||
modules = systemModules();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<String> iterator() {
|
||||
try {
|
||||
return Files.walk(root)
|
||||
.filter(p -> p.getNameCount() > 2)
|
||||
.filter(p -> modules.contains(p.getName(1).toString()))
|
||||
.map(p -> p.subpath(2, p.getNameCount()))
|
||||
.map(p -> p.toString())
|
||||
.filter(s -> s.endsWith(".class") && !s.endsWith("module-info.class"))
|
||||
.iterator();
|
||||
} catch(IOException x) {
|
||||
throw new UncheckedIOException("Unable to walk \"/modules\"", x);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Filter JVMCI module and its transitive dependences
|
||||
*/
|
||||
static Set<String> systemModules() {
|
||||
// Build module graph and inverse dependences
|
||||
Set<String> modules = new HashSet<>();
|
||||
Map<String, Set<String>> moduleToDeps = new HashMap<>();
|
||||
Map<String, Set<String>> inverseDeps = new HashMap<>();
|
||||
for (ModuleReference mref : ModuleFinder.ofSystem().findAll()) {
|
||||
var md = mref.descriptor();
|
||||
modules.add(md.name());
|
||||
Set<String> deps = md.requires().stream().map(ModuleDescriptor.Requires::name)
|
||||
.collect(Collectors.toSet());
|
||||
moduleToDeps.put(md.name(), deps);
|
||||
inverseDeps.put(md.name(), new HashSet<>());
|
||||
}
|
||||
|
||||
// reverse edges
|
||||
moduleToDeps.keySet().forEach(u -> {
|
||||
moduleToDeps.get(u)
|
||||
.forEach(v -> inverseDeps.get(v)
|
||||
.add(u));
|
||||
});
|
||||
|
||||
Set<String> mods = Set.of(
|
||||
// All JVMCI packages other than jdk.vm.ci.services are dynamically
|
||||
// exported to Graal
|
||||
"jdk.graal.compiler", "jdk.graal.compiler.management"
|
||||
);
|
||||
// Filters all modules that directly or indirectly require Graal modules
|
||||
// as these are upgradeable and also provide APIs to add qualified exports dynamically
|
||||
Set<String> filters = mods.stream().flatMap(mn -> findDeps(mn, inverseDeps).stream())
|
||||
.collect(Collectors.toSet());
|
||||
System.out.println("Filtered modules: " + filters);
|
||||
return modules.stream()
|
||||
.filter(mn -> !filters.contains(mn))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
/*
|
||||
* Traverse the graph to find all the dependences from the given name.
|
||||
*/
|
||||
static Set<String> findDeps(String name, Map<String, Set<String>> graph) {
|
||||
Set<String> visited = new HashSet<>();
|
||||
Deque<String> deque = new LinkedList<>();
|
||||
deque.add(name);
|
||||
String node;
|
||||
while (!deque.isEmpty()) {
|
||||
node = deque.pop();
|
||||
if (visited.contains(node))
|
||||
continue;
|
||||
|
||||
visited.add(node);
|
||||
Set<String> deps = graph.get(node);
|
||||
if (deps != null)
|
||||
deque.addAll(deps);
|
||||
}
|
||||
return visited;
|
||||
}
|
||||
}
|
||||
}
|
||||
64
test/jdk/java/lang/Class/getDeclaredMethod/Exceptions.java
Normal file
64
test/jdk/java/lang/Class/getDeclaredMethod/Exceptions.java
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 4319910
|
||||
* @summary Verify that exceptions are thrown as expected.
|
||||
*/
|
||||
|
||||
public class Exceptions {
|
||||
void m0() {}
|
||||
public void m1() {}
|
||||
private void m2() {}
|
||||
protected void m4() {}
|
||||
|
||||
private static final String [] npe = {null};
|
||||
private static final String [] nsme = {"m6"};
|
||||
private static final String [] pass = {"m0", "m1", "m2", "m4"};
|
||||
|
||||
private void test(String s, Class ex) {
|
||||
Throwable t = null;
|
||||
try {
|
||||
getClass().getDeclaredMethod(s, new Class[] {});
|
||||
} catch (Throwable x) {
|
||||
if (ex.isAssignableFrom(x.getClass()))
|
||||
t = x;
|
||||
}
|
||||
if ((t == null) && (ex != null))
|
||||
throw new RuntimeException("expected " + ex.getName()
|
||||
+ " for " + s);
|
||||
else
|
||||
System.out.println(s + " OK");
|
||||
}
|
||||
|
||||
public static void main(String [] args) {
|
||||
Exceptions e = new Exceptions();
|
||||
for (int i = 0; i < npe.length; i++)
|
||||
e.test(npe[i], NullPointerException.class);
|
||||
for (int i = 0; i < nsme.length; i++)
|
||||
e.test(nsme[i], NoSuchMethodException.class);
|
||||
for (int i = 0; i < pass.length; i++)
|
||||
e.test(pass[i], null);
|
||||
}
|
||||
}
|
||||
47
test/jdk/java/lang/Class/getDeclaringClass/Sanity.java
Normal file
47
test/jdk/java/lang/Class/getDeclaringClass/Sanity.java
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
@bug 4028577
|
||||
@summary Sanity check that Class.getDeclaringClass() works.
|
||||
@author Anand Palaniswamy
|
||||
*/
|
||||
public class Sanity {
|
||||
class Nested {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (Nested.class.getDeclaringClass() != Sanity.class)
|
||||
throw new Exception("Not finding declaring class");
|
||||
|
||||
/* This will pass on old VM's that return null when this
|
||||
* method was unimplemented. But write the test to keep
|
||||
* regression from happening in the current code.
|
||||
*/
|
||||
class BlockLocal {
|
||||
};
|
||||
|
||||
if (BlockLocal.class.getDeclaringClass() != null)
|
||||
throw new Exception("Finding declaring class for block local");
|
||||
}
|
||||
}
|
||||
363
test/jdk/java/lang/Class/getEnclosingClass/EnclosingClass.java
Normal file
363
test/jdk/java/lang/Class/getEnclosingClass/EnclosingClass.java
Normal file
|
|
@ -0,0 +1,363 @@
|
|||
/*
|
||||
* Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* @summary Check getEnclosingClass and other methods
|
||||
* @author Peter von der Ahé
|
||||
*
|
||||
* a) Top level classes
|
||||
* b) Nested classes (static member classes)
|
||||
* c) Inner classes (non-static member classes)
|
||||
* d) Local classes (named classes declared within a method)
|
||||
* e) Anonymous classes
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* Test annotations
|
||||
* Test Locals in static initializers
|
||||
* Test Locals in methods
|
||||
* Test Locals in constructors
|
||||
* Test interfaces
|
||||
* Test enums
|
||||
* Test method with a String[] argument
|
||||
*/
|
||||
|
||||
//package
|
||||
|
||||
import common.TestMe;
|
||||
|
||||
interface MakeClass {
|
||||
Class<?> make();
|
||||
}
|
||||
|
||||
public class EnclosingClass {
|
||||
public EnclosingClass() {
|
||||
aec = (new Object() {}).getClass();
|
||||
}
|
||||
static class Nested {
|
||||
static class NestedNested {
|
||||
}
|
||||
class NestedInner {
|
||||
}
|
||||
Class<?> nestedLocal0;
|
||||
Class<?> nestedLocal1;
|
||||
Class<?> nestedLocal2;
|
||||
{
|
||||
class NestedLocal0 {};
|
||||
nestedLocal0 = NestedLocal0.class;
|
||||
nestedMethod1();
|
||||
nestedMethod2(null);
|
||||
}
|
||||
void nestedMethod1() {
|
||||
class NestedLocal1 {}
|
||||
nestedLocal1 = NestedLocal1.class;
|
||||
}
|
||||
void nestedMethod2(String[] args) {
|
||||
class NestedLocal2 {}
|
||||
nestedLocal2 = NestedLocal2.class;
|
||||
}
|
||||
Class<?> nestedAnonymous = (new Object() {}).getClass();
|
||||
static enum NestedNestedEnum {
|
||||
}
|
||||
enum NestedInnerEnum {
|
||||
}
|
||||
}
|
||||
|
||||
class Inner {
|
||||
class InnerInner {
|
||||
}
|
||||
Class<?> innerLocal0;
|
||||
Class<?> innerLocal1;
|
||||
Class<?> innerLocal2;
|
||||
{
|
||||
class InnerLocal0 {
|
||||
};
|
||||
innerLocal0 = InnerLocal0.class;
|
||||
innerMethod1();
|
||||
innerMethod2(null);
|
||||
}
|
||||
void innerMethod1() {
|
||||
class InnerLocal1 {}
|
||||
innerLocal1 = InnerLocal1.class;
|
||||
}
|
||||
void innerMethod2(String[] args) {
|
||||
class InnerLocal2 {}
|
||||
innerLocal2 = InnerLocal2.class;
|
||||
}
|
||||
Class<?> innerAnonymous = (new Object() {}).getClass();
|
||||
}
|
||||
|
||||
@TestMe(desc="top level class",
|
||||
encl="null",
|
||||
simple="EnclosingClass",
|
||||
canonical="EnclosingClass")
|
||||
public Class<?> a = EnclosingClass.class;
|
||||
|
||||
@TestMe(desc="nested class within top level class",
|
||||
encl="class EnclosingClass",
|
||||
simple="Nested",
|
||||
canonical="EnclosingClass.Nested")
|
||||
public Class<?> ab = Nested.class;
|
||||
@TestMe(desc="inner class within top level class",
|
||||
encl="class EnclosingClass",
|
||||
simple="Inner",
|
||||
canonical="EnclosingClass.Inner")
|
||||
public Class<?> ac = Inner.class;
|
||||
@TestMe(desc="local class within top level class",
|
||||
encl="class EnclosingClass",
|
||||
simple="Local0",
|
||||
hasCanonical=false)
|
||||
public Class<?> ad0;
|
||||
@TestMe(desc="local class within top level class",
|
||||
encl="class EnclosingClass",
|
||||
simple="Local1",
|
||||
hasCanonical=false)
|
||||
public Class<?> ad1;
|
||||
@TestMe(desc="local class within top level class",
|
||||
encl="class EnclosingClass",
|
||||
simple="Local2",
|
||||
hasCanonical=false)
|
||||
public Class<?> ad2;
|
||||
@TestMe(desc="local class within a top level class static initializer" ,
|
||||
encl="class EnclosingClass",
|
||||
simple="StaticLocal0",
|
||||
hasCanonical=false)
|
||||
public Class<?> sad0;
|
||||
@TestMe(desc="local class within a top level class static method" ,
|
||||
encl="class EnclosingClass",
|
||||
simple="StaticLocal1",
|
||||
hasCanonical=false)
|
||||
public Class<?> sad1;
|
||||
@TestMe(desc="local class within a top level class static method",
|
||||
encl="class EnclosingClass",
|
||||
simple="StaticLocal2",
|
||||
hasCanonical=false)
|
||||
public Class<?> sad2;
|
||||
{
|
||||
class Local0 {
|
||||
class LocalInner {}
|
||||
{
|
||||
class LocalLocal {};
|
||||
dd = LocalLocal.class;
|
||||
de = (new Object() {}).getClass();
|
||||
}
|
||||
};
|
||||
ad0 = Local0.class;
|
||||
dc = Local0.LocalInner.class;
|
||||
new Local0();
|
||||
method1();
|
||||
method2(null);
|
||||
sad0 = staticLocal0;
|
||||
sad1 = staticMethod1();
|
||||
sad2 = staticMethod2(null);
|
||||
}
|
||||
static Class<?> staticLocal0;
|
||||
static {
|
||||
class StaticLocal0 {};
|
||||
staticLocal0 = StaticLocal0.class;
|
||||
}
|
||||
static Class<?> staticMethod1() {
|
||||
class StaticLocal1 {};
|
||||
return StaticLocal1.class;
|
||||
}
|
||||
static Class<?> staticMethod2(String[] args) {
|
||||
class StaticLocal2 {};
|
||||
return StaticLocal2.class;
|
||||
}
|
||||
void method1() {
|
||||
class Local1 {};
|
||||
ad1 = Local1.class;
|
||||
}
|
||||
void method2(String[] args) {
|
||||
class Local2 {};
|
||||
ad2 = Local2.class;
|
||||
}
|
||||
@TestMe(desc="anonymous class within top level class",
|
||||
encl="class EnclosingClass",
|
||||
simple="",
|
||||
hasCanonical=false)
|
||||
public Class<?> ae = (new Object() {}).getClass();
|
||||
@TestMe(desc="anonymous class within top level class constructor",
|
||||
encl="class EnclosingClass",
|
||||
simple="",
|
||||
hasCanonical=false)
|
||||
public Class<?> aec;
|
||||
|
||||
@TestMe(desc="nested class within nested class",
|
||||
encl="class EnclosingClass$Nested",
|
||||
simple="NestedNested",
|
||||
canonical="EnclosingClass.Nested.NestedNested")
|
||||
public Class<?> bb = Nested.NestedNested.class;
|
||||
@TestMe(desc="inner class within nested class",
|
||||
encl="class EnclosingClass$Nested",
|
||||
simple="NestedInner",
|
||||
canonical="EnclosingClass.Nested.NestedInner")
|
||||
public Class<?> bc = Nested.NestedInner.class;
|
||||
@TestMe(desc="local class within nested class",
|
||||
encl="class EnclosingClass$Nested",
|
||||
simple="NestedLocal0",
|
||||
hasCanonical=false)
|
||||
public Class<?> bd0 = (new Nested()).nestedLocal0;
|
||||
@TestMe(desc="local class within nested class",
|
||||
encl="class EnclosingClass$Nested",
|
||||
simple="NestedLocal1",
|
||||
hasCanonical=false)
|
||||
public Class<?> bd1 = (new Nested()).nestedLocal1;
|
||||
@TestMe(desc="local class within nested class",
|
||||
encl="class EnclosingClass$Nested",
|
||||
simple="NestedLocal2",
|
||||
hasCanonical=false)
|
||||
public Class<?> bd2 = (new Nested()).nestedLocal2;
|
||||
@TestMe(desc="anonymous class within nested class",
|
||||
encl="class EnclosingClass$Nested",
|
||||
simple="",
|
||||
hasCanonical=false)
|
||||
public Class<?> be = (new Nested()).nestedAnonymous;
|
||||
|
||||
@TestMe(desc="nested class within an inner class", encl="", simple="")
|
||||
public Class<?> cb = Void.class; // not legal
|
||||
@TestMe(desc="inner class within an inner class",
|
||||
encl="class EnclosingClass$Inner",
|
||||
simple="InnerInner",
|
||||
canonical="EnclosingClass.Inner.InnerInner")
|
||||
public Class<?> cc = ((new Inner()).new InnerInner()).getClass();
|
||||
@TestMe(desc="local class within an inner class",
|
||||
encl="class EnclosingClass$Inner",
|
||||
simple="InnerLocal0",
|
||||
hasCanonical=false)
|
||||
public Class<?> cd = (new Inner()).innerLocal0;
|
||||
@TestMe(desc="anonymous class within an inner class",
|
||||
encl="class EnclosingClass$Inner",
|
||||
simple="",
|
||||
hasCanonical=false)
|
||||
public Class<?> ce = (new Inner()).innerAnonymous;
|
||||
|
||||
@TestMe(desc="nested class within a local class", encl="", simple="")
|
||||
public Class<?> db = Void.class; // not legal
|
||||
@TestMe(desc="inner class within a local class",
|
||||
encl="class EnclosingClass$1Local0",
|
||||
simple="LocalInner",
|
||||
hasCanonical=false)
|
||||
public Class<?> dc; // initialized above
|
||||
@TestMe(desc="local class within a local class",
|
||||
encl="class EnclosingClass$1Local0",
|
||||
simple="LocalLocal",
|
||||
hasCanonical=false)
|
||||
public Class<?> dd; // initialized above
|
||||
@TestMe(desc="anonymous class within a local class",
|
||||
encl="class EnclosingClass$1Local0",
|
||||
simple="",
|
||||
hasCanonical=false)
|
||||
public Class<?> de; // initialized above
|
||||
|
||||
@TestMe(desc="nested class within an anonymous class", encl="", simple="")
|
||||
public Class<?> eb = Void.class; // not legal
|
||||
@TestMe(desc="inner class within an anonymous class",
|
||||
encl="class EnclosingClass$3",
|
||||
simple="AnonymousInner",
|
||||
hasCanonical=false)
|
||||
public Class<?> ec = new MakeClass() {
|
||||
class AnonymousInner {}
|
||||
public Class<?> make() { return AnonymousInner.class; }
|
||||
}.make();
|
||||
@TestMe(desc="local class within an anonymous class",
|
||||
encl="class EnclosingClass$4",
|
||||
simple="AnonymousLocal",
|
||||
hasCanonical=false)
|
||||
public Class<?> ed = new MakeClass() {
|
||||
Class<?> c;
|
||||
{
|
||||
class AnonymousLocal {}
|
||||
c = AnonymousLocal.class;
|
||||
}
|
||||
public Class<?> make() { return c; }
|
||||
}.make();
|
||||
@TestMe(desc="anonymous class within an anonymous class",
|
||||
encl="class EnclosingClass$5",
|
||||
simple="",
|
||||
hasCanonical=false)
|
||||
public Class<?> ee = new MakeClass() {
|
||||
Class<?> c;
|
||||
{
|
||||
c = new Object() {}.getClass();
|
||||
}
|
||||
public Class<?> make() { return c; }
|
||||
}.make();
|
||||
|
||||
@TestMe(desc="the primitive boolean type",
|
||||
encl="null",
|
||||
simple="boolean",
|
||||
canonical="boolean")
|
||||
public Class<?> booleanClass = boolean.class;
|
||||
|
||||
@TestMe(desc="the primitive char type",
|
||||
encl="null",
|
||||
simple="char",
|
||||
canonical="char")
|
||||
public Class<?> charClass = char.class;
|
||||
|
||||
@TestMe(desc="the primitive byte type",
|
||||
encl="null",
|
||||
simple="byte",
|
||||
canonical="byte")
|
||||
public Class<?> byteClass = byte.class;
|
||||
|
||||
@TestMe(desc="the primitive short type",
|
||||
encl="null",
|
||||
simple="short",
|
||||
canonical="short")
|
||||
public Class<?> shortClass = short.class;
|
||||
|
||||
@TestMe(desc="the primitive int type",
|
||||
encl="null",
|
||||
simple="int",
|
||||
canonical="int")
|
||||
public Class<?> intClass = int.class;
|
||||
|
||||
@TestMe(desc="the primitive long type",
|
||||
encl="null",
|
||||
simple="long",
|
||||
canonical="long")
|
||||
public Class<?> longClass = long.class;
|
||||
|
||||
@TestMe(desc="the primitive float type",
|
||||
encl="null",
|
||||
simple="float",
|
||||
canonical="float")
|
||||
public Class<?> floatClass = float.class;
|
||||
|
||||
@TestMe(desc="the primitive double type",
|
||||
encl="null",
|
||||
simple="double",
|
||||
canonical="double")
|
||||
public Class<?> doubleClass = double.class;
|
||||
|
||||
@TestMe(desc="the primitive void type",
|
||||
encl="null",
|
||||
simple="void",
|
||||
canonical="void")
|
||||
public Class<?> voidClass = void.class;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,208 @@
|
|||
/*
|
||||
* Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4992173 4992170
|
||||
* @library /test/lib
|
||||
* @modules jdk.compiler
|
||||
* @run testng/othervm EnclosingClassTest
|
||||
* @summary Check getEnclosingClass and other methods
|
||||
* @author Peter von der Ahé
|
||||
*/
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import common.TestMe;
|
||||
import jdk.test.lib.compiler.CompilerUtils;
|
||||
import jdk.test.lib.util.FileUtils;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/*
|
||||
* We have five kinds of classes:
|
||||
* a) Top level classes
|
||||
* b) Nested classes (static member classes)
|
||||
* c) Inner classes (non-static member classes)
|
||||
* d) Local classes (named classes declared within a method)
|
||||
* e) Anonymous classes
|
||||
*
|
||||
* Each one can be within a package or not.
|
||||
* Kinds b-e can/must be within kinds a-e.
|
||||
* This gives us a three dimensional space:
|
||||
* 1. dimension: b-e
|
||||
* 2. dimension: a-e
|
||||
* 3. dimension: packages
|
||||
*
|
||||
* We make a two dimensional matrix of (b-e)x(a-e) and change the
|
||||
* package configuration on that:
|
||||
*
|
||||
* b c d e
|
||||
* a x x x x
|
||||
* b x x x x
|
||||
* c o x x x where o means "not legal"
|
||||
* d o x x x
|
||||
* e o x x x
|
||||
*/
|
||||
|
||||
public class EnclosingClassTest {
|
||||
private static final String SRC_DIR = System.getProperty("test.src");
|
||||
private static final Path ENCLOSING_CLASS_SRC = Path.of(SRC_DIR, "EnclosingClass.java");
|
||||
private static final String GEN_SRC_DIR = "gensrc";
|
||||
|
||||
@BeforeClass
|
||||
public void createEnclosingClasses() throws IOException {
|
||||
Path pkg1Dir = Path.of(GEN_SRC_DIR, "pkg1");
|
||||
Path pkg2Dir = Path.of(GEN_SRC_DIR, "pkg1", "pkg2");
|
||||
Path pkg1File = pkg1Dir.resolve("EnclosingClass.java");
|
||||
Path pkg2File = pkg2Dir.resolve("EnclosingClass.java");
|
||||
|
||||
if (!Files.notExists(pkg1Dir)) {
|
||||
FileUtils.deleteFileTreeWithRetry(pkg1Dir);
|
||||
}
|
||||
Files.createDirectories(pkg2Dir);
|
||||
createAndWriteEnclosingClasses(ENCLOSING_CLASS_SRC, pkg1File, "pkg1");
|
||||
createAndWriteEnclosingClasses(ENCLOSING_CLASS_SRC, pkg2File, "pkg1.pkg2");
|
||||
|
||||
Assert.assertTrue(CompilerUtils.compile(ENCLOSING_CLASS_SRC, Path.of(System.getProperty("test.classes")),
|
||||
"--source-path", SRC_DIR));
|
||||
Assert.assertTrue(CompilerUtils.compile(pkg1File, Path.of(System.getProperty("test.classes")),
|
||||
"-classpath", System.getProperty("test.class.path")));
|
||||
Assert.assertTrue(CompilerUtils.compile(pkg2File, Path.of(System.getProperty("test.classes")),
|
||||
"-classpath", System.getProperty("test.class.path")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnclosingClasses() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException,
|
||||
InvocationTargetException, InstantiationException {
|
||||
test(Class.forName("EnclosingClass").getDeclaredConstructor().newInstance());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnclosingClassesInPackage() throws ClassNotFoundException, NoSuchMethodException,
|
||||
IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||
test(Class.forName("pkg1.EnclosingClass").getDeclaredConstructor().newInstance());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnclosingClassesInNestedPackage() throws ClassNotFoundException, NoSuchMethodException,
|
||||
IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||
test(Class.forName("pkg1.pkg2.EnclosingClass").getDeclaredConstructor().newInstance());
|
||||
}
|
||||
|
||||
private void createAndWriteEnclosingClasses(Path source, Path target, String packageName) throws IOException {
|
||||
String className = packageName + ".EnclosingClass";
|
||||
try (BufferedReader br = new BufferedReader(new FileReader(source.toFile()));
|
||||
PrintWriter bw = new PrintWriter(new FileWriter(target.toFile()))) {
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
if (line.contains("canonical=\"EnclosingClass")) {
|
||||
line = line.replaceAll("canonical=\"EnclosingClass", "canonical=\"" + className);
|
||||
} else if (line.contains("\"class EnclosingClass")) {
|
||||
line = line.replaceAll("\"class EnclosingClass", "\"class " + className);
|
||||
} else if (line.contains("//package")) {
|
||||
line = line.replaceAll("//package", "package " + packageName + ";");
|
||||
}
|
||||
bw.println(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void info(Class<?> c, Class<?> encClass, String desc) {
|
||||
if (!"".equals(desc)) {
|
||||
System.out.println(desc + ":");
|
||||
}
|
||||
System.out.println(c);
|
||||
System.out.println("\tis enclosed by:\t\t" + encClass);
|
||||
System.out.println("\thas simple name:\t`" +
|
||||
c.getSimpleName() + "'");
|
||||
System.out.println("\thas canonical name:\t`" +
|
||||
c.getCanonicalName() + "'");
|
||||
}
|
||||
|
||||
private void match(String actual, String expected) {
|
||||
Assert.assertTrue((actual == null && expected == null) || actual.equals(expected));
|
||||
System.out.println("\t`" +
|
||||
actual + "' matches expected `" +
|
||||
expected + "'");
|
||||
}
|
||||
|
||||
private void check(Class<?> c, Class<?> enc,
|
||||
String encName, String encNameExpected,
|
||||
String simpleName, String simpleNameExpected,
|
||||
String canonicalName, String canonicalNameExpected) {
|
||||
match(encName, encNameExpected);
|
||||
match(simpleName, simpleNameExpected);
|
||||
match(canonicalName, canonicalNameExpected);
|
||||
}
|
||||
|
||||
private void testClass(Class<?> c, TestMe annotation, Field f) {
|
||||
if (Void.class.equals(c))
|
||||
return;
|
||||
Class<?> encClass = c.getEnclosingClass();
|
||||
c.getEnclosingMethod(); // make sure it does not crash
|
||||
c.getEnclosingConstructor(); // make sure it does not crash
|
||||
info(c, encClass, annotation.desc());
|
||||
check(c, encClass,
|
||||
""+encClass, annotation.encl(),
|
||||
c.getSimpleName(), annotation.simple(),
|
||||
c.getCanonicalName(),
|
||||
annotation.hasCanonical() ? annotation.canonical() : null);
|
||||
if (void.class.equals(c))
|
||||
return;
|
||||
Class<?> array = java.lang.reflect.Array.newInstance(c, 0).getClass();
|
||||
check(array, array.getEnclosingClass(),
|
||||
"", "",
|
||||
array.getSimpleName(), annotation.simple()+"[]",
|
||||
array.getCanonicalName(),
|
||||
annotation.hasCanonical() ? annotation.canonical()+"[]" : null);
|
||||
}
|
||||
|
||||
private void test(Object tests) {
|
||||
for (Field f : tests.getClass().getFields()) {
|
||||
TestMe annotation = f.getAnnotation(TestMe.class);
|
||||
if (annotation != null) {
|
||||
try {
|
||||
testClass((Class<?>)f.get(tests), annotation, f);
|
||||
} catch (AssertionError ex) {
|
||||
System.err.println("Error in " +
|
||||
tests.getClass().getName() +
|
||||
"." + f.getName());
|
||||
throw ex;
|
||||
} catch (IllegalAccessException ex) {
|
||||
ex.printStackTrace();
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
48
test/jdk/java/lang/Class/getEnclosingClass/T4992170.java
Normal file
48
test/jdk/java/lang/Class/getEnclosingClass/T4992170.java
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 4992170
|
||||
*
|
||||
* @run main/othervm -esa -ea T4992170
|
||||
*
|
||||
* @summary enclosing type parameter missing in anonymous and local classes
|
||||
* @author Neal Gafter
|
||||
*/
|
||||
|
||||
import java.lang.reflect.*;
|
||||
|
||||
class A<T> {
|
||||
Object o = new Object() {
|
||||
public T t;
|
||||
};
|
||||
}
|
||||
|
||||
public class T4992170 {
|
||||
public static void main(String[] args) throws NoSuchFieldException {
|
||||
Type t = new A<Integer>().o.getClass().getField("t").getGenericType();
|
||||
if (!(t instanceof TypeVariable))
|
||||
throw new Error("" + t);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2004, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @summary Check getEnclosingClass and other methods
|
||||
* @author Peter von der Ahé
|
||||
*/
|
||||
|
||||
package common;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface TestMe {
|
||||
String desc();
|
||||
String encl();
|
||||
String simple();
|
||||
boolean hasCanonical() default true;
|
||||
String canonical() default "";
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue