mirror of
https://github.com/vim/vim.git
synced 2026-05-06 20:30:02 -04:00
159d392427
In addition to matching type parameter sections of generic classes and records and interfaces, match such sections of generic methods and constructors. As before, opt for it by defining "g:java_highlight_generics"; the diamond form still does not qualify for this kind of recognition. And make section patterns agree with one another in syntax items. References: https://docs.oracle.com/javase/specs/jls/se21/html/jls-4.html#jls-4.5 https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.4.4 https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.8.4 Signed-off-by: Aliaksei Budavei <0x000c70@gmail.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
193 lines
4.5 KiB
Java
193 lines
4.5 KiB
Java
// VIM_TEST_SETUP let g:java_highlight_functions = 'style'
|
|
// VIM_TEST_SETUP let g:java_highlight_generics = 1
|
|
|
|
|
|
import java.lang.invoke.MethodHandle;
|
|
import java.util.function.BiPredicate;
|
|
import java.util.function.Consumer;
|
|
import java.util.function.Function;
|
|
import java.util.function.IntFunction;
|
|
import java.util.function.IntSupplier;
|
|
import java.util.function.Predicate;
|
|
import java.util.function.Supplier;
|
|
import java.util.function.ToIntFunction;
|
|
import java.util.function.UnaryOperator;
|
|
|
|
class MethodReferencesTests
|
|
{
|
|
static {
|
|
// Primary :: [TypeArguments] Identifier
|
|
try {
|
|
Runnable r1 = ((Runtime) null)::gc;
|
|
} catch (NullPointerException expected) {
|
|
}
|
|
|
|
Supplier<Integer> s1 = ((Number) 0)::hashCode;
|
|
Supplier<Integer> s2 = ((Comparable<?>) '\0')::hashCode;
|
|
Supplier<Integer> s3 = ((Comparable<?>) false)::hashCode;
|
|
Supplier<Integer> s4 = "::"::hashCode;
|
|
Supplier<Class<?>> s5 = int[].class::arrayType;
|
|
Supplier<Integer> s6 = new MethodReferencesTests() ::
|
|
hashCode;
|
|
Supplier<Integer> s7 = ((Number)
|
|
(new MethodReferencesTests().xy)[0])::intValue;
|
|
Supplier<int[]> s8 = new MethodReferencesTests().xy::
|
|
clone;
|
|
Consumer<Object> c1 = System.out :: println;
|
|
Supplier<byte[]> s9 = ((Supplier<String>) ()->"()").get()
|
|
::getBytes;
|
|
Supplier<String> sa = ((Supplier<String>)
|
|
((Supplier<String>) ((Supplier<String>)
|
|
((Supplier<String>) ((Supplier<String>)
|
|
() -> "() -> ()")
|
|
::toString)
|
|
::toString)
|
|
::get)
|
|
::toString)
|
|
::toString;
|
|
|
|
// ExpressionName :: [TypeArguments] Identifier
|
|
// ReferenceType :: [TypeArguments] Identifier
|
|
Function<String, IntSupplier> f1 = s ->
|
|
s :: length;
|
|
Function<int[][], Supplier<int[]>> f2 = ii ->
|
|
((int[]) (ii.length > 0 ? ii[0] : ii))
|
|
:: clone;
|
|
UnaryOperator<String> uo1 = String::valueOf;
|
|
ToIntFunction<String> tif1 = s -> s.transform(
|
|
String :: length);
|
|
|
|
// ClassType :: [TypeArguments] new
|
|
// ArrayType :: new
|
|
Function<Object, C2> f3 = C2::<Object>new;
|
|
Function<C2, C2.C21> f4 = pci -> pci.new
|
|
<String>C21(null); // Cf. "d".
|
|
Supplier<C1<?>> sb = C1::new;
|
|
Function<Byte, C1<?>> f5 = C1<Void> :: <Byte> new;
|
|
IntFunction<C1<?>[]> if1 = C1<?>[] :: new;
|
|
IntFunction<byte[]> if2 = byte[] :: new;
|
|
}
|
|
|
|
final int[] xy = { 0, 1 };
|
|
|
|
// super :: [TypeArguments] Identifier
|
|
// TypeName . super :: [TypeArguments] Identifier
|
|
<T> MethodReferencesTests()
|
|
{
|
|
Predicate<T> p1 = MethodReferencesTests.super::equals;
|
|
Predicate<T> p2 = MethodReferencesTests.this::equals;
|
|
}
|
|
|
|
interface I4<T> extends I3<T>
|
|
{
|
|
default Predicate<T> superEqualist()
|
|
{
|
|
return I3
|
|
.super::equals; /* "a" */
|
|
}
|
|
}
|
|
|
|
interface I3<T> extends I2<T>
|
|
{
|
|
default Predicate<T> superEqualist()
|
|
{
|
|
return I2.
|
|
super::equals; /* "b" */
|
|
}
|
|
}
|
|
|
|
interface I2<T> extends I1<T>
|
|
{
|
|
default Predicate<T> superEqualist()
|
|
{ /* Non-capturing gymnastics for super::equals. */
|
|
return Function.<Function<MethodHandle,
|
|
Predicate<T>>>
|
|
identity()
|
|
.apply(mh -> o -> MethodReferencesTests
|
|
.invokePredicate(mh, o))
|
|
.apply(EQUALS.bindTo(this));
|
|
}
|
|
}
|
|
|
|
interface I1<T>
|
|
{
|
|
default Predicate<T> equalist()
|
|
{ /* Non-capturing gymnastics for this::equals. */
|
|
return Function.<Function<I1<T>, Predicate<T>>>
|
|
identity()
|
|
.apply(that -> o -> Function
|
|
.<BiPredicate<I1<T>, T>>
|
|
identity()
|
|
.apply(I1<T>:: /* "c" */
|
|
equals)
|
|
.test(that, o))
|
|
.apply(I1.this);
|
|
}
|
|
}
|
|
|
|
static <T> boolean invokePredicate(MethodHandle mh, T o)
|
|
{
|
|
try {
|
|
return (boolean) mh.invokeExact(o);
|
|
} catch (Throwable th) {
|
|
throw new RuntimeException(th);
|
|
}
|
|
}
|
|
|
|
private static final MethodHandle EQUALS;
|
|
|
|
static {
|
|
try {
|
|
EQUALS = java.lang.invoke.MethodHandles.lookup()
|
|
.findSpecial(
|
|
I1.class,
|
|
"equals",
|
|
java.lang.invoke.MethodType.methodType(
|
|
boolean.class,
|
|
Object.class),
|
|
I2.class);
|
|
} catch (ReflectiveOperationException e) {
|
|
throw new Error(e);
|
|
}
|
|
}
|
|
|
|
static class C1<T>
|
|
{
|
|
C1() { }
|
|
<A> C1(A dummy) { }
|
|
}
|
|
|
|
static class C2
|
|
{
|
|
C2() { <String> this(""); }
|
|
|
|
<A> C2(A dummy)
|
|
{
|
|
C2.stringer().apply(((Function<C2, C2.C21>)
|
|
C2.C21::new) /* "d" */
|
|
.apply(C2.this));
|
|
}
|
|
|
|
class C21
|
|
{
|
|
C21() { <String> this(""); }
|
|
|
|
<B> C21(B dummy)
|
|
{
|
|
C2.stringer().apply(C2.this);
|
|
}
|
|
}
|
|
|
|
static <T extends Object> Function<T, String> stringer()
|
|
{
|
|
return T::toString; /* "e" */
|
|
}
|
|
}
|
|
|
|
static {
|
|
((Supplier<Class<?>>)((Supplier<C2.C21>)()->new
|
|
<Object>C2().new <Object> C21(new<Object>
|
|
C1< Object >((C1<?>)null)))::getClass).get();
|
|
}
|
|
}
|