Skip to content

Commit

Permalink
[Java 21] Add tests for exhaustive switch expressions on native enums.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 724475235
  • Loading branch information
rluble authored and copybara-github committed Feb 7, 2025
1 parent 38e22c6 commit e1f307e
Show file tree
Hide file tree
Showing 19 changed files with 1,028 additions and 558 deletions.
32 changes: 32 additions & 0 deletions jre/java/java/lang/MatchException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright 2025 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package java.lang;

/**
* See <a
* href="https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/MatchException.html">the
* official Java API doc</a> for details.
*/
public class MatchException extends RuntimeException {

public MatchException() {
this("", null);
}

public MatchException(String message, Throwable cause) {
super(message, cause);
}
}
19 changes: 19 additions & 0 deletions jre/java/javasynth/java/lang/IncompatibleClassChangeError.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright 2025 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package java.lang;

/** Exists solely to make javac happy. */
public class IncompatibleClassChangeError extends Error {}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ j2wasm_library(
"NativeEnums.java",
],
),
javacopts = ["-XepDisableAllChecks"],
javacopts = [
"-XepDisableAllChecks",
"-source 17",
"-target 17",
],
deps = [
"//jre/java:javaemul_internal_annotations-j2wasm",
"//third_party:jsinterop-annotations-j2wasm",
Expand All @@ -37,4 +41,8 @@ integration_test(
# Contains JsInterop features which are only applicable for JS output.
enable_jvm_test = False,
enable_kt = False,
javacopts = [
"-source 17",
"-target 17",
],
)
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import javaemul.internal.annotations.UncheckedCast;
import javaemul.internal.annotations.Wasm;
import jsenum.NativeEnums.NativeEnum;
import jsenum.NativeEnums.NativeEnumWitMissingValues;
import jsenum.NativeEnums.NativeEnumWithClinit;
import jsenum.NativeEnums.NumberNativeEnum;
import jsenum.NativeEnums.StringNativeEnum;
Expand All @@ -55,6 +56,8 @@ public class Main {

public static void main(String... args) {
testNativeJsEnum();
// TODO(b/380878051): Enable once bug is fixed.
// testNativeJsEnumWithMissingValues();
testStringNativeJsEnum();
testCastOnNative();
testComparableJsEnum();
Expand Down Expand Up @@ -158,6 +161,20 @@ private static void testNativeJsEnum() {
assertTrue(asSeenFromJs(NativeEnum.ACCEPT) == OK_STRING);
}

@Wasm("nop") // TODO(b/288145698): Support native JsEnum.
private static void testNativeJsEnumWithMissingValues() {
try {
NativeEnumWitMissingValues e = (NativeEnumWitMissingValues) (Object) NativeEnum.CANCEL;
int i =
switch (e) {
case OK -> 1;
};
fail();
} catch (MatchException | IncompatibleClassChangeError expected) {
// Expected behavior.
}
}

@JsMethod(name = "passThrough")
@Wasm("nop") // TODO(b/288145698): Support native JsEnum.
private static native Object asSeenFromJs(NativeEnum s);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,10 @@ String getValue() {
}
}

@JsEnum(isNative = true, namespace = "test", name = "NativeEnum")
enum NativeEnumWitMissingValues {
OK,
}

private NativeEnums() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package jsenum;


/** Placeholders for Wasm. TODO(b/288145698): Native JsEnum is not supported. */
class NativeEnums {

Expand Down Expand Up @@ -53,5 +54,9 @@ String getValue() {
}
}

enum NativeEnumWitMissingValues {
OK,
}

private NativeEnums() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,12 @@ readable_example(
"*.java",
"*.native.js",
]),
deps = ["//third_party:jsinterop-annotations-j2cl"],
javacopts = [
"-source 14",
"-target 14",
],
deps = [
"//jre/java:javaemul_internal_annotations-j2cl",
"//third_party:jsinterop-annotations-j2cl",
],
)
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import javaemul.internal.annotations.Wasm;
import jsinterop.annotations.JsEnum;
import jsinterop.annotations.JsFunction;
import jsinterop.annotations.JsMethod;
Expand Down Expand Up @@ -145,6 +146,19 @@ public static void testJsEnumSwitch() {
acceptsSupplierOfSupplier(() -> (() -> ComparableJsEnum.ONE));
}

// TODO(b/395108282): Remove nop once the bug is fixed.
@Wasm("nop")
private static void testExhaustiveJsEnumSwitchExpression() {
ComparableJsEnum comparableJsEnum =
ComparableJsEnum.ONE.getValue() == 1 ? ComparableJsEnum.TWO : null;
int i =
switch (comparableJsEnum) {
case TWO -> 2;
case ONE -> 1;
case ZERO -> 0;
};
}

private static void testJsEnumAutoboxingSpecialMethods() {
StringJsEnum stringJsEnum = StringJsEnum.ONE;
StringJsEnum nullStringJsEnum = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,20 @@ class Main extends j_l_Object {
}));
}
/** @nodts */
static m_testExhaustiveJsEnumSwitchExpression__void() {
let comparableJsEnum = $Overlay.m_getValue__$devirt__jsenum_Main_ComparableJsEnum__int(ComparableJsEnum.ONE) == 1 ? ComparableJsEnum.TWO : /**@type {?ComparableJsEnum}*/ ($Enums.unbox(null, $Overlay));
let i = (() =>{
switch ((InternalPreconditions.m_checkNotNull__boolean__void(!$Equality.$same(comparableJsEnum, null)), comparableJsEnum)) {
case ComparableJsEnum.TWO:
return 2;
case ComparableJsEnum.ONE:
return 1;
case ComparableJsEnum.ZERO:
return 0;
}
})();
}
/** @nodts */
static m_testJsEnumAutoboxingSpecialMethods__void() {
let stringJsEnum = StringJsEnum.ONE;
let nullStringJsEnum = /**@type {?StringJsEnum}*/ ($Enums.unbox(null, StringJsEnum_$Overlay));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import kotlin.experimental.ExperimentalObjCName
import kotlin.jvm.JvmField
import kotlin.jvm.JvmStatic
import kotlin.native.ObjCName
import kotlin.run

@ObjCName("J2ktJsenumMain", exact = true)
open class Main {
Expand Down Expand Up @@ -97,6 +98,24 @@ open class Main {
)
}

@JvmStatic
private fun testExhaustiveJsEnumSwitchExpression() {
val comparableJsEnum: Main.ComparableJsEnum? = if (Main.ComparableJsEnum.ONE.getValue() == 1) Main.ComparableJsEnum.TWO else null
val i: Int = run {
when (comparableJsEnum!!) {
Main.ComparableJsEnum.TWO -> {
return@run 2
}
Main.ComparableJsEnum.ONE -> {
return@run 1
}
Main.ComparableJsEnum.ZERO -> {
return@run 0
}
}
}
}

@JvmStatic
private fun testJsEnumAutoboxingSpecialMethods() {
val stringJsEnum: Main.StringJsEnum? = Main.StringJsEnum.ONE
Expand Down
Loading

0 comments on commit e1f307e

Please sign in to comment.