Skip to content

Commit

Permalink
[JS] Emit switch expressions using EmbeddedStatement.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 718534144
  • Loading branch information
rluble authored and copybara-github committed Jan 22, 2025
1 parent d4c520a commit 98ecc6b
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ public TypeDescriptor getTypeDescriptor() {

@Override
public Precedence getPrecedence() {
return Precedence.HIGHEST;
// EmbeddedStatement is emitted as an IIFE in JavaScript, hence the precedence is the same
// as the one for method call.
return Precedence.MEMBER_ACCESS;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,20 +98,6 @@ public class TypeDescriptors {
@QualifiedBinaryName("java.util.ReadonlyMap")
public DeclaredTypeDescriptor javaUtilReadonlyMap;

public DeclaredTypeDescriptor javaUtilFunctionSupplier;

@QualifiedBinaryName("java.util.function.BooleanSupplier")
public DeclaredTypeDescriptor javaUtilFunctionBooleanSupplier;

@QualifiedBinaryName("java.util.function.IntSupplier")
public DeclaredTypeDescriptor javaUtilFunctionIntSupplier;

@QualifiedBinaryName("java.util.function.LongSupplier")
public DeclaredTypeDescriptor javaUtilFunctionLongSupplier;

@QualifiedBinaryName("java.util.function.DoubleSupplier")
public DeclaredTypeDescriptor javaUtilFunctionDoubleSupplier;

public DeclaredTypeDescriptor javaIoSerializable;

@Nullable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@
import com.google.j2cl.transpiler.ast.AstUtils;
import com.google.j2cl.transpiler.ast.AwaitExpression;
import com.google.j2cl.transpiler.ast.BinaryExpression;
import com.google.j2cl.transpiler.ast.Block;
import com.google.j2cl.transpiler.ast.CastExpression;
import com.google.j2cl.transpiler.ast.ConditionalExpression;
import com.google.j2cl.transpiler.ast.DeclaredTypeDescriptor;
import com.google.j2cl.transpiler.ast.EmbeddedStatement;
import com.google.j2cl.transpiler.ast.Expression;
import com.google.j2cl.transpiler.ast.Expression.Precedence;
import com.google.j2cl.transpiler.ast.ExpressionWithComment;
Expand All @@ -52,6 +54,7 @@
import com.google.j2cl.transpiler.ast.PostfixExpression;
import com.google.j2cl.transpiler.ast.PrefixExpression;
import com.google.j2cl.transpiler.ast.PrefixOperator;
import com.google.j2cl.transpiler.ast.Statement;
import com.google.j2cl.transpiler.ast.SuperReference;
import com.google.j2cl.transpiler.ast.ThisReference;
import com.google.j2cl.transpiler.ast.TypeDescriptor;
Expand Down Expand Up @@ -149,6 +152,24 @@ public boolean enterExpressionWithComment(ExpressionWithComment expressionWithCo
return false;
}

@Override
public boolean enterEmbeddedStatement(EmbeddedStatement expression) {
// Emit the embedded statements as a parameterless IIFE.
sourceBuilder.append("(() =>");
Statement statement = expression.getStatement();
StatementTranspiler.render(
statement instanceof Block
? statement
: Block.newBuilder()
.setStatements(statement)
.setSourcePosition(statement.getSourcePosition())
.build(),
environment,
sourceBuilder);
sourceBuilder.append(")()");
return false;
}

@Override
public boolean enterFieldAccess(FieldAccess fieldAccess) {
String fieldMangledName = fieldAccess.getTarget().getMangledName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,8 @@ public boolean enterMultiExpression(MultiExpression multiExpression) {
public boolean enterEmbeddedStatement(EmbeddedStatement embeddedStatement) {
Statement statement = embeddedStatement.getStatement();
Label label = null;
// TODO(b/391582571): Use a cleaner representation for a labeled block that has a
// return value.
if (statement instanceof LabeledStatement) {
LabeledStatement labeledStatement = (LabeledStatement) statement;
label = labeledStatement.getLabel();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,15 @@

import com.google.j2cl.transpiler.ast.AbstractRewriter;
import com.google.j2cl.transpiler.ast.CompilationUnit;
import com.google.j2cl.transpiler.ast.DeclaredTypeDescriptor;
import com.google.j2cl.transpiler.ast.FunctionExpression;
import com.google.j2cl.transpiler.ast.LambdaAdaptorTypeDescriptors;
import com.google.j2cl.transpiler.ast.MethodCall;
import com.google.j2cl.transpiler.ast.EmbeddedStatement;
import com.google.j2cl.transpiler.ast.Node;
import com.google.j2cl.transpiler.ast.ReturnStatement;
import com.google.j2cl.transpiler.ast.SwitchExpression;
import com.google.j2cl.transpiler.ast.SwitchStatement;
import com.google.j2cl.transpiler.ast.TypeDescriptor;
import com.google.j2cl.transpiler.ast.TypeDescriptors;
import com.google.j2cl.transpiler.ast.YieldStatement;

/**
* Implements switch expressions as an immediately invoked function expressions that executes a
* switch statement..
* Implements switch expressions using EmbeddedStatements which are emitted as IIFEs.
*
* <p>In JavaScript switch constructs are only allowed as statements. This pass converts the switch
* expression into switch statement and wraps it into an IIFE which allows us to execute a statement
Expand Down Expand Up @@ -72,16 +66,10 @@ public void applyTo(CompilationUnit compilationUnit) {

@Override
public Node rewriteSwitchExpression(SwitchExpression switchExpression) {
DeclaredTypeDescriptor supplierJsFunctionTypeDescriptor =
getSupplierJsFunction(switchExpression.getTypeDescriptor());

return MethodCall.Builder.from(
supplierJsFunctionTypeDescriptor.getJsFunctionMethodDescriptor())
.setQualifier(
// Enclose the switch expression as a switch statement inside a function.
FunctionExpression.newBuilder()
.setTypeDescriptor(supplierJsFunctionTypeDescriptor)
.setStatements(SwitchStatement.Builder.from(switchExpression).build())
return EmbeddedStatement.newBuilder()
.setTypeDescriptor(switchExpression.getTypeDescriptor())
.setStatement(
SwitchStatement.Builder.from(switchExpression)
.setSourcePosition(switchExpression.getSourcePosition())
.build())
.build();
Expand All @@ -96,27 +84,4 @@ public ReturnStatement rewriteYieldStatement(YieldStatement yieldStatement) {
}
});
}

/** Returns the JsFunction supplier with the appropriate type for {@code typeDescriptor}. */
private DeclaredTypeDescriptor getSupplierJsFunction(TypeDescriptor typeDescriptor) {
// TODO(b/112308901): remove this hacky code when function types are modeled better.
return LambdaAdaptorTypeDescriptors.createJsFunctionTypeDescriptor(
getSupplierType(typeDescriptor));
}

/** Returns the supplier that is most suitable to be used for {@code typeDescriptor}. */
private DeclaredTypeDescriptor getSupplierType(TypeDescriptor typeDescriptor) {
if (!typeDescriptor.isPrimitive()) {
return TypeDescriptors.get()
.javaUtilFunctionSupplier
.specializeTypeVariables(typeVariable -> typeDescriptor);
} else if (TypeDescriptors.isPrimitiveBoolean(typeDescriptor)) {
return TypeDescriptors.get().javaUtilFunctionBooleanSupplier;
} else if (TypeDescriptors.isPrimitiveFloatOrDouble(typeDescriptor)) {
return TypeDescriptors.get().javaUtilFunctionDoubleSupplier;
} else if (TypeDescriptors.isPrimitiveLong(typeDescriptor)) {
return TypeDescriptors.get().javaUtilFunctionLongSupplier;
}
return TypeDescriptors.get().javaUtilFunctionIntSupplier;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,9 @@
}] => [switch (v) {
case 1: case 2:
... return 20;
}] "sourcemap.SourceMap.<lambda in testSwitchExpression>"
[10;] => [return 10;] "sourcemap.SourceMap.<lambda in testSwitchExpression>"
[20;] => [return 20;] "sourcemap.SourceMap.<lambda in testSwitchExpression>"
}] "sourcemap.SourceMap.testSwitchExpression"
[10;] => [return 10;] "sourcemap.SourceMap.testSwitchExpression"
[20;] => [return 20;] "sourcemap.SourceMap.testSwitchExpression"
[SourceMap] => [m_reversed__java_util_Comparator]
[SourceMap] => [return /**@type {Comparator<T>}*/ (Comparator.m_reversed__$default__java_util_Comparator__java_util_Comparator(this));] "sourcemap.SourceMap.reversed"
[SourceMap] => [m_thenComparing__java_util_Comparator__java_util_Comparator]
Expand Down

0 comments on commit 98ecc6b

Please sign in to comment.