Skip to content

Commit

Permalink
[J2KT] Create InsertNotNullAssertionToPolyNullMethodCalls pass whic…
Browse files Browse the repository at this point in the history
…h would insert not-null assertion to JRE method calls which are known to be `@PolyNull`. At this moment, there's only one method which needs that: `Optional.orElse()`.

The existing `InsertNotNullAssertions` pass is renamed to `InsertNotNullAssertionsOnNullabilityMismatch`, for consistency with `InsertCastsOnNullabilityMismatch` pass.

PiperOrigin-RevId: 706707865
  • Loading branch information
Googler authored and copybara-github committed Dec 16, 2024
1 parent 527c92e commit 6328c55
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 110 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ public class TypeDescriptors {
public DeclaredTypeDescriptor javaUtilMap;
public DeclaredTypeDescriptor javaUtilList;
public DeclaredTypeDescriptor javaUtilObjects;
public DeclaredTypeDescriptor javaUtilOptional;

@Nullable
@QualifiedBinaryName("java.util.ReadonlyCollection")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@
import com.google.j2cl.transpiler.passes.InsertNarrowingPrimitiveConversions;
import com.google.j2cl.transpiler.passes.InsertNarrowingPrimitiveConversionsJ2kt;
import com.google.j2cl.transpiler.passes.InsertNarrowingReferenceConversions;
import com.google.j2cl.transpiler.passes.InsertNotNullAssertions;
import com.google.j2cl.transpiler.passes.InsertNotNullAssertionToPolyNullMethodCalls;
import com.google.j2cl.transpiler.passes.InsertNotNullAssertionsOnNullabilityMismatch;
import com.google.j2cl.transpiler.passes.InsertQualifierProjectionCasts;
import com.google.j2cl.transpiler.passes.InsertRawTypeCasts;
import com.google.j2cl.transpiler.passes.InsertStringConversions;
Expand Down Expand Up @@ -759,7 +760,8 @@ public ImmutableList<Supplier<NormalizationPass>> getPassFactories(BackendOption
NormalizePrimitiveCastsJ2kt::new,
ImplementBitLevelOperatorsJ2kt::new,
InsertQualifierProjectionCasts::new,
InsertNotNullAssertions::new,
InsertNotNullAssertionToPolyNullMethodCalls::new,
InsertNotNullAssertionsOnNullabilityMismatch::new,
InsertCastsOnNullabilityMismatch::new,
InsertCastForLowerBounds::new,
InsertRawTypeCasts::new,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright 2024 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 com.google.j2cl.transpiler.passes;

import com.google.j2cl.transpiler.ast.AbstractRewriter;
import com.google.j2cl.transpiler.ast.CompilationUnit;
import com.google.j2cl.transpiler.ast.MethodCall;
import com.google.j2cl.transpiler.ast.MethodDescriptor;
import com.google.j2cl.transpiler.ast.Node;
import com.google.j2cl.transpiler.ast.TypeDescriptors;

/**
* Inserts not-null assertion to method calls which are known to be @PolyNull, where the argument
* can not be null.
*/
public class InsertNotNullAssertionToPolyNullMethodCalls extends NormalizationPass {
private final MethodDescriptor javaUtilOptionalOrElse =
TypeDescriptors.get()
.javaUtilOptional
.getMethodDescriptor("orElse", TypeDescriptors.get().javaLangObject);

@Override
public void applyTo(CompilationUnit compilationUnit) {
compilationUnit.accept(
new AbstractRewriter() {
@Override
public Node rewriteMethodCall(MethodCall methodCall) {
MethodDescriptor methodDescriptor = methodCall.getTarget();
if (isOrOverrides(methodDescriptor, javaUtilOptionalOrElse)) {
if (!methodCall.getArguments().get(0).canBeNull()) {
return methodCall.postfixNotNullAssertion();
}
}
return methodCall;
}
});
}

private static boolean isOrOverrides(
MethodDescriptor methodDescriptor, MethodDescriptor otherMethodDescriptor) {
return methodDescriptor.getDeclarationDescriptor().equals(otherMethodDescriptor)
|| methodDescriptor.getJavaOverriddenMethodDescriptors().stream()
.anyMatch(it -> it.getDeclarationDescriptor().equals(otherMethodDescriptor));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
* Inserts NOT_NULL_ASSERTION (!!) in places where Java performs implicit null-check, and when
* conversion is needed from nullable to non-null type.
*/
public final class InsertNotNullAssertions extends NormalizationPass {
public final class InsertNotNullAssertionsOnNullabilityMismatch extends NormalizationPass {
@Override
public void applyTo(CompilationUnit compilationUnit) {
// Insert non-null assertions when converting from nullable to non-null type.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,9 @@ private static <T> T checkNotNull(@Nullable T reference) {
throw new RuntimeException();
}

// TODO(b/383581076): Uncomment when fixed.
// private static ImmutableList<User> testImplicitTypeArguments(Iterable<User> users) {
// return sortedCopyOf(comparing(user -> user.getName().orElse("")), users);
// }
private static ImmutableList<User> testImplicitTypeArguments(Iterable<User> users) {
return sortedCopyOf(comparing(user -> user.getName().orElse("")), users);
}

private static ImmutableList<User> testExplicitTypeArguments(Iterable<User> users) {
return sortedCopyOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ open class NullabilityInferenceProblem internal constructor() {
throw RuntimeException()
}

@JvmStatic
private fun testImplicitTypeArguments(users: MutableIterable<NullabilityInferenceProblem.User>): NullabilityInferenceProblem.ImmutableList<NullabilityInferenceProblem.User> {
return NullabilityInferenceProblem.sortedCopyOf<NullabilityInferenceProblem.User>(java.util.Comparator.comparing<NullabilityInferenceProblem.User, String>(Function { user: NullabilityInferenceProblem.User ->
return@Function user.getName().orElse("")!!
}), users)
}

@JvmStatic
private fun testExplicitTypeArguments(users: MutableIterable<NullabilityInferenceProblem.User>): NullabilityInferenceProblem.ImmutableList<NullabilityInferenceProblem.User> {
return NullabilityInferenceProblem.sortedCopyOf<NullabilityInferenceProblem.User>(java.util.Comparator.comparing<NullabilityInferenceProblem.User, String>(Function { user: NullabilityInferenceProblem.User ->
Expand All @@ -57,7 +64,7 @@ open class NullabilityInferenceProblem internal constructor() {
@JvmStatic
private fun testCheckNotNull(users: MutableIterable<NullabilityInferenceProblem.User>): NullabilityInferenceProblem.ImmutableList<NullabilityInferenceProblem.User> {
return NullabilityInferenceProblem.sortedCopyOf<NullabilityInferenceProblem.User>(java.util.Comparator.comparing<NullabilityInferenceProblem.User, String>(Function { user: NullabilityInferenceProblem.User ->
return@Function NullabilityInferenceProblem.checkNotNull<String>(user.getName().orElse(""))
return@Function NullabilityInferenceProblem.checkNotNull<String>(user.getName().orElse("")!!)
}), users)
}
}
Expand Down

This file was deleted.

This file was deleted.

0 comments on commit 6328c55

Please sign in to comment.