Skip to content

Commit

Permalink
[JS] Cleanup around instanceof related synthetic members and pass.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 561190552
  • Loading branch information
rluble authored and copybara-github committed Aug 30, 2023
1 parent 65fe51a commit db8f18e
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ public MethodDescriptor getIsInstanceMethodDescriptor() {
.setEnclosingTypeDescriptor(getMetadataTypeDeclaration().toUnparameterizedTypeDescriptor())
.setParameterTypeDescriptors(TypeDescriptors.getUnknownType())
.setReturnTypeDescriptor(PrimitiveTypes.BOOLEAN)
.setOrigin(MethodOrigin.INSTANCE_OF_SUPPORT_METHOD)
.setOrigin(MethodOrigin.SYNTHETIC_INSTANCE_OF_SUPPORT_METHOD)
.setStatic(true)
.build();
}
Expand All @@ -412,7 +412,7 @@ public MethodDescriptor getMarkImplementorMethodDescriptor() {
.setEnclosingTypeDescriptor(getMetadataTypeDeclaration().toUnparameterizedTypeDescriptor())
.setParameterTypeDescriptors(TypeDescriptors.get().nativeFunction)
.setReturnTypeDescriptor(PrimitiveTypes.VOID)
.setOrigin(MethodOrigin.INSTANCE_OF_SUPPORT_METHOD)
.setOrigin(MethodOrigin.SYNTHETIC_INSTANCE_OF_SUPPORT_METHOD)
.setStatic(true)
.build();
}
Expand All @@ -424,7 +424,7 @@ public FieldDescriptor getIsInstanceMarkerField() {
.setName(isJsFunctionImplementation() ? "$is" : "$implements")
.setEnclosingTypeDescriptor(this)
.setTypeDescriptor(PrimitiveTypes.BOOLEAN)
.setOrigin(FieldOrigin.INSTANCE_OF_SUPPORT_FIELD)
.setOrigin(FieldOrigin.SYNTHETIC_INSTANCE_OF_SUPPORT_FIELD)
.build();
}

Expand All @@ -440,7 +440,7 @@ public MethodDescriptor getCopyMethodDescriptor() {
.setParameterTypeDescriptors(
TypeDescriptors.getUnknownType(), TypeDescriptors.getUnknownType())
.setReturnTypeDescriptor(PrimitiveTypes.VOID)
.setOrigin(MethodOrigin.INSTANCE_OF_SUPPORT_METHOD)
.setOrigin(MethodOrigin.SYNTHETIC_INSTANCE_OF_SUPPORT_METHOD)
.setStatic(true)
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public enum FieldOrigin implements MemberDescriptor.Origin {
SYNTHETIC_CAPTURE_FIELD("$captured_"),
SYNTHETIC_BACKING_FIELD("$static_"),
SYNTHETIC_ORDINAL_FIELD("$ordinal_"),
INSTANCE_OF_SUPPORT_FIELD(""),
SYNTHETIC_INSTANCE_OF_SUPPORT_FIELD(""),
;

private final String prefix;
Expand All @@ -69,8 +69,8 @@ public String getPrefix() {
}

@Override
public boolean isInstanceOfSupportMember() {
return this == INSTANCE_OF_SUPPORT_FIELD;
public boolean isSyntheticInstanceOfSupportMember() {
return this == SYNTHETIC_INSTANCE_OF_SUPPORT_FIELD;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public interface Origin {
String getPrefix();

/** Returns whether this member is supporting the implementation of the instanceof operation. */
boolean isInstanceOfSupportMember();
boolean isSyntheticInstanceOfSupportMember();
}

/** Return JsInfo from the member's annotation. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public enum MethodOrigin implements MemberDescriptor.Origin {
SYNTHETIC_LAMBDA_ADAPTOR_CONSTRUCTOR("<synthetic: lambda_adaptor_ctor>"),
SYNTHETIC_CLASS_LITERAL_GETTER,
SYNTHETIC_STRING_LITERAL_GETTER,
INSTANCE_OF_SUPPORT_METHOD,
SYNTHETIC_INSTANCE_OF_SUPPORT_METHOD,
GENERALIZING_BRIDGE, // Bridges a more general signature to a more specific one.
SPECIALIZING_BRIDGE, // Bridges a more specific signature to a more general one.
DEFAULT_METHOD_BRIDGE, // Bridges to a default method interface.
Expand Down Expand Up @@ -169,8 +169,8 @@ public String getPrefix() {
}

@Override
public boolean isInstanceOfSupportMember() {
return this == INSTANCE_OF_SUPPORT_METHOD;
public boolean isSyntheticInstanceOfSupportMember() {
return this == SYNTHETIC_INSTANCE_OF_SUPPORT_METHOD;
}
}

Expand Down Expand Up @@ -676,7 +676,7 @@ public String getMangledName() {
return getSimpleJsName();
}

if (getOrigin().isInstanceOfSupportMember()) {
if (getOrigin().isSyntheticInstanceOfSupportMember()) {
// Class support methods, like $isInstance and $markImplementor, should not be mangled.
return getName();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,8 +373,8 @@ private ImportCategory getImplicitImportCategory() {
return ImportCategory.LOADTIME;
}

if (getCurrentMember().getDescriptor().getOrigin().isInstanceOfSupportMember()) {
// InstanceOf support members, e.g. $isInstance, might not call $clinit hence all the
if (getCurrentMember().getDescriptor().getOrigin().isSyntheticInstanceOfSupportMember()) {
// Synthetic instanceOf support members, do not call $clinit hence all the
// types used in their implementation need to be imported as LOADTIME.
return ImportCategory.LOADTIME;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,10 @@ public void addType(
continue;
}

if (memberDescriptor.getOrigin().isInstanceOfSupportMember()) {
// InstanceOf support members should not be considered methods that are prunable if there
// are no references, since the references are hidden by the runtime. In the end
// InstanceOf support members are live whenever the type is live.
if (memberDescriptor.getOrigin().isSyntheticInstanceOfSupportMember()) {
// Synthetic instanceof support members should not be considered methods that are prunable
// if there are no references, since the references are hidden by the runtime. In the end
// instanceof support members are live whenever the type is live.
continue;
}

Expand Down Expand Up @@ -202,6 +202,10 @@ private static MemberInfo.Builder createMemberInfo(

private void collectReferencedTypesAndMethodInvocations(
Member member, MemberInfo.Builder memberInfoBuilder) {
// Setters and getters share the same member info for rta purposes but are traversed separately
// so when collecting references for the current member, a member info might already have
// been constructed for the corresponding accessor and its information is passed in the
// memberInfoBuilder.
Set<MethodInvocation> invokedMethods =
new LinkedHashSet<>(memberInfoBuilder.getInvokedMethodsList());

Expand Down Expand Up @@ -279,6 +283,14 @@ public void exitInvocation(Invocation node) {
return;
}

if (target.getOrigin().isSyntheticInstanceOfSupportMember()) {
// Don't record calls to synthetic instance of support members since these are not
// kept in the library info.
// NOTE: Explicit calls to `$isInstance` are part of the translation of the
// 'instanceof' operator; and because static calls have the type as a qualifier, the
// type will be considered referenced.
return;
}
// Only record a $clinit call if it is from a clinit itself. All other clinit calls are
// from the entry points of the class and doesn't need recording since RapidTypeAnalyser
// will make the clinit alive when it arrives to an entry point.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,19 @@
package com.google.j2cl.transpiler.passes;

import static com.google.common.base.Preconditions.checkState;
import static com.google.j2cl.transpiler.ast.MethodDescriptor.IS_INSTANCE_METHOD_NAME;

import com.google.j2cl.transpiler.ast.AbstractRewriter;
import com.google.j2cl.transpiler.ast.ArrayTypeDescriptor;
import com.google.j2cl.transpiler.ast.CompilationUnit;
import com.google.j2cl.transpiler.ast.DeclaredTypeDescriptor;
import com.google.j2cl.transpiler.ast.Expression;
import com.google.j2cl.transpiler.ast.InstanceOfExpression;
import com.google.j2cl.transpiler.ast.JsInfo;
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.NumberLiteral;
import com.google.j2cl.transpiler.ast.PrimitiveTypeDescriptor;
import com.google.j2cl.transpiler.ast.PrimitiveTypes;
import com.google.j2cl.transpiler.ast.RuntimeMethods;
import com.google.j2cl.transpiler.ast.TypeDescriptor;
import com.google.j2cl.transpiler.ast.TypeDescriptors;

/** Replaces instanceof expression with corresponding $isInstance method call. */
public class NormalizeInstanceOfs extends NormalizationPass {
Expand All @@ -60,21 +55,11 @@ public Node rewriteInstanceOfExpression(InstanceOfExpression expression) {

private static Node rewriteRegularInstanceOfExpression(
InstanceOfExpression instanceOfExpression) {
TypeDescriptor checkTypeDescriptor = instanceOfExpression.getTestTypeDescriptor();

MethodDescriptor isInstanceMethodDescriptor =
MethodDescriptor.newBuilder()
.setOriginalJsInfo(JsInfo.RAW)
.setStatic(true)
.setEnclosingTypeDescriptor(
checkTypeDescriptor.getMetadataTypeDeclaration().toUnparameterizedTypeDescriptor())
.setName(IS_INSTANCE_METHOD_NAME)
.setParameterTypeDescriptors(TypeDescriptors.get().javaLangObject)
.setReturnTypeDescriptor(PrimitiveTypes.BOOLEAN)
.build();
DeclaredTypeDescriptor checkTypeDescriptor =
(DeclaredTypeDescriptor) instanceOfExpression.getTestTypeDescriptor();

// TypeName.$isInstance(expr);
return MethodCall.Builder.from(isInstanceMethodDescriptor)
return MethodCall.Builder.from(checkTypeDescriptor.getIsInstanceMethodDescriptor())
.setArguments(instanceOfExpression.getExpression())
.build();
}
Expand Down

0 comments on commit db8f18e

Please sign in to comment.