proguard.classfile.io.kotlin.KotlinMetadataWriter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of proguard-core Show documentation
Show all versions of proguard-core Show documentation
ProGuardCORE is a free library to read, analyze, modify, and write Java class files.
/*
* ProGuardCORE -- library to process Java bytecode.
*
* Copyright (c) 2002-2021 Guardsquare NV
*
* 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 proguard.classfile.io.kotlin;
import kotlinx.metadata.*;
import kotlinx.metadata.jvm.JvmFieldSignature;
import kotlinx.metadata.jvm.JvmMethodSignature;
import kotlinx.metadata.jvm.*;
import proguard.classfile.Clazz;
import proguard.classfile.FieldSignature;
import proguard.classfile.MethodSignature;
import proguard.classfile.ProgramClass;
import proguard.classfile.TypeConstants;
import proguard.classfile.attribute.Attribute;
import proguard.classfile.attribute.annotation.Annotation;
import proguard.classfile.attribute.annotation.ArrayElementValue;
import proguard.classfile.attribute.annotation.ConstantElementValue;
import proguard.classfile.attribute.annotation.ElementValue;
import proguard.classfile.attribute.annotation.visitor.AllAnnotationVisitor;
import proguard.classfile.attribute.annotation.visitor.AllElementValueVisitor;
import proguard.classfile.attribute.annotation.visitor.AnnotationTypeFilter;
import proguard.classfile.attribute.annotation.visitor.ElementValueVisitor;
import proguard.classfile.attribute.visitor.AllAttributeVisitor;
import proguard.classfile.attribute.visitor.AttributeNameFilter;
import proguard.classfile.editor.ConstantPoolEditor;
import proguard.classfile.editor.ConstantPoolShrinker;
import proguard.classfile.kotlin.*;
import proguard.classfile.kotlin.flags.*;
import proguard.classfile.kotlin.visitor.*;
import proguard.classfile.util.WarningPrinter;
import proguard.classfile.util.kotlin.KotlinMetadataInitializer.MetadataType;
import proguard.classfile.visitor.ClassVisitor;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import static java.util.stream.Collectors.joining;
import static kotlinx.metadata.FlagsKt.flagsOf;
import static kotlinx.metadata.jvm.KotlinClassHeader.COMPATIBLE_METADATA_VERSION;
import static proguard.classfile.kotlin.KotlinAnnotationArgument.*;
import static proguard.classfile.kotlin.KotlinConstants.*;
/**
* This class visitor writes the information stored in a Clazz's kotlinMetadata field
* to a @kotlin/Metadata annotation on the class.
*/
public class KotlinMetadataWriter
implements ClassVisitor,
KotlinMetadataVisitor,
// Implementation interfaces.
ElementValueVisitor
{
private final ClassVisitor extraClassVisitor;
private int k;
private int[] mv;
private int[] bv;
private String[] d1;
private String[] d2;
private int xi;
private String xs;
private String pn;
private ConstantPoolEditor constantPoolEditor;
private static ConstantPoolShrinker constantPoolShrinker = new ConstantPoolShrinker();
private MetadataType currentType;
private final BiConsumer errorHandler;
private boolean hasVisitedAny = false;
public KotlinMetadataWriter(WarningPrinter warningPrinter)
{
this(warningPrinter, null);
}
public KotlinMetadataWriter(WarningPrinter warningPrinter, ClassVisitor extraClassVisitor)
{
this((clazz, message) -> warningPrinter.print(clazz.getName(), message), extraClassVisitor);
}
public KotlinMetadataWriter(BiConsumer errorHandler)
{
this(errorHandler, null);
}
public KotlinMetadataWriter(BiConsumer errorHandler, ClassVisitor extraClassVisitor)
{
this.errorHandler = errorHandler;
this.extraClassVisitor = extraClassVisitor;
}
@Override
public void visitAnyClass(Clazz clazz)
{
clazz.kotlinMetadataAccept(this);
}
// Implementations for KotlinMetadataVisitor.
@Override
public void visitAnyKotlinMetadata(Clazz clazz, KotlinMetadata kotlinMetadata)
{
switch (kotlinMetadata.k)
{
case METADATA_KIND_CLASS:
kotlinMetadata.accept(clazz, new KotlinClassConstructor()); break;
case METADATA_KIND_FILE_FACADE:
kotlinMetadata.accept(clazz, new KotlinFileFacadeConstructor()); break;
case METADATA_KIND_SYNTHETIC_CLASS:
kotlinMetadata.accept(clazz, new KotlinSyntheticClassConstructor()); break;
case METADATA_KIND_MULTI_FILE_CLASS_FACADE:
kotlinMetadata.accept(clazz, new KotlinMultiFileFacadeConstructor()); break;
case METADATA_KIND_MULTI_FILE_CLASS_PART:
kotlinMetadata.accept(clazz, new KotlinMultiFilePartConstructor()); break;
}
// Pass the new data to the .read() method as a sanity check.
KotlinClassMetadata md = KotlinClassMetadata.read(new KotlinClassHeader(k, mv, bv, d1, d2, xs, pn, xi));
if (md == null)
{
String version = mv == null ? "unknown" : Arrays.stream(mv).mapToObj(Integer::toString).collect(joining("."));
errorHandler.accept(clazz,
"Encountered corrupt Kotlin metadata in class " +
clazz.getName() + " (version " + version + ")" +
". Not processing the metadata for this class.");
return;
}
this.constantPoolEditor = new ConstantPoolEditor((ProgramClass) clazz);
this.hasVisitedAny = false;
try
{
clazz.accept(new AllAttributeVisitor(
new AttributeNameFilter(Attribute.RUNTIME_VISIBLE_ANNOTATIONS,
new AllAnnotationVisitor(
new AnnotationTypeFilter(TYPE_KOTLIN_METADATA,
new AllElementValueVisitor(this))))));
}
catch (IllegalArgumentException e)
{
// It's possible that an exception is thrown by the MetadataType.valueOf calls if
// the kotlin.Metadata class was accidentally obfuscated.
errorHandler.accept(clazz, "Invalid Kotlin metadata annotation for " +
clazz.getName() +
" (invalid Kotlin metadata field names)." +
" Not writing the metadata for this class.");
}
// Clean up dangling Strings from the original metadata.
clazz.accept(constantPoolShrinker);
if (extraClassVisitor != null)
{
clazz.accept(extraClassVisitor);
}
}
// Implementations for ElementValueVisitor.
@Override
public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue)
{
this.hasVisitedAny = true;
this.currentType = MetadataType.valueOf(constantElementValue.getMethodName(clazz));
switch (currentType)
{
case k: constantElementValue.u2constantValueIndex = constantPoolEditor.addIntegerConstant(k); break;
case xi: constantElementValue.u2constantValueIndex = constantPoolEditor.addIntegerConstant(xi); break;
case xs: constantElementValue.u2constantValueIndex = constantPoolEditor.addUtf8Constant(xs); break;
case pn: constantElementValue.u2constantValueIndex = constantPoolEditor.addUtf8Constant(pn); break;
}
}
@Override
public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue)
{
this.hasVisitedAny = true;
this.currentType = MetadataType.valueOf(arrayElementValue.getMethodName(clazz));
switch (currentType)
{
case mv:
arrayElementValue.u2elementValuesCount = mv.length;
ElementValue[] newMvElementValues = new ElementValue[mv.length];
for (int k = 0; k < mv.length; k++)
{
newMvElementValues[k] =
new ConstantElementValue('I',
0,
constantPoolEditor.addIntegerConstant(mv[k]));
}
arrayElementValue.elementValues = newMvElementValues;
break;
case bv:
arrayElementValue.u2elementValuesCount = bv.length;
ElementValue[] newBvElementValues = new ElementValue[bv.length];
for (int k = 0; k < bv.length; k++)
{
newBvElementValues[k] =
new ConstantElementValue('I',
0,
constantPoolEditor.addIntegerConstant(bv[k]));
}
arrayElementValue.elementValues = newBvElementValues;
break;
case d1:
arrayElementValue.u2elementValuesCount = d1.length;
ElementValue[] newD1ElementValues = new ElementValue[d1.length];
for (int k = 0; k < d1.length; k++)
{
newD1ElementValues[k] =
new ConstantElementValue('s',
0,
constantPoolEditor.addUtf8Constant(d1[k]));
}
arrayElementValue.elementValues = newD1ElementValues;
break;
case d2:
arrayElementValue.u2elementValuesCount = d2.length;
ElementValue[] newD2ElementValues = new ElementValue[d2.length];
for (int k = 0; k < d2.length; k++)
{
newD2ElementValues[k] =
new ConstantElementValue('s',
0,
constantPoolEditor.addUtf8Constant(d2[k]));
}
arrayElementValue.elementValues = newD2ElementValues;
break;
}
}
private class ContractConstructor
implements KotlinContractVisitor
{
private KmFunctionVisitor kmdFunctionVisitor;
ContractConstructor(KmFunctionVisitor kmdFunctionVisitor)
{
this.kmdFunctionVisitor = kmdFunctionVisitor;
}
// Implementations for KotlinContractVisitor.
@Override
public void visitContract(Clazz clazz,
KotlinMetadata kotlinMetadata,
KotlinFunctionMetadata kotlinFunctionMetadata,
KotlinContractMetadata kotlinContractMetadata)
{
KmContractVisitor kmContractVisitor = kmdFunctionVisitor.visitContract();
kotlinContractMetadata.effectsAccept(clazz,
kotlinMetadata,
kotlinFunctionMetadata,
new EffectConstructor(kmContractVisitor));
kmContractVisitor.visitEnd();
}
}
private class EffectConstructor
implements KotlinEffectVisitor
{
private final KmContractVisitor kmContractVisitor;
private EffectConstructor(KmContractVisitor kmContractVisitor) { this.kmContractVisitor = kmContractVisitor; }
// Implementations for KotlinEffectVisitor.
@Override
public void visitEffect(Clazz clazz,
KotlinMetadata kotlinMetadata,
KotlinFunctionMetadata kotlinFunctionMetadata,
KotlinContractMetadata kotlinContractMetadata,
KotlinEffectMetadata kotlinEffectMetadata)
{
KmEffectVisitor kmEffectVisitor = kmContractVisitor.visitEffect(toKmEffectType(kotlinEffectMetadata.effectType),
toKmEffectInvocationKind(kotlinEffectMetadata.invocationKind));
kotlinEffectMetadata.conclusionOfConditionalEffectAccept(clazz,
new EffectExprConstructor(kmEffectVisitor));
kotlinEffectMetadata.constructorArgumentAccept(clazz,
new EffectExprConstructor(kmEffectVisitor));
kmEffectVisitor.visitEnd();
}
}
private class EffectExprConstructor
implements KotlinEffectExprVisitor
{
private KmEffectExpressionVisitor effectExprVis;
private KmEffectVisitor effectVis;
private EffectExprConstructor(KmEffectVisitor effectVis) { this.effectVis = effectVis; }
private KmEffectExpressionVisitor nestedExprVis;
private EffectExprConstructor(KmEffectExpressionVisitor nestedExprVis) { this.nestedExprVis = nestedExprVis; }
// Implementations for KotlinEffectExprVisitor.
@Override
public void visitAnyEffectExpression(Clazz clazz,
KotlinEffectMetadata kotlinEffectMetadata,
KotlinEffectExpressionMetadata kotlinEffectExpressionMetadata)
{
effectExprVis.visit(convertEffectExpressionFlags(kotlinEffectExpressionMetadata.flags),
kotlinEffectExpressionMetadata.parameterIndex);
if (kotlinEffectExpressionMetadata.hasConstantValue)
{
effectExprVis.visitConstantValue(kotlinEffectExpressionMetadata.constantValue);
}
kotlinEffectExpressionMetadata.andRightHandSideAccept(clazz,
kotlinEffectMetadata,
new EffectExprConstructor(effectExprVis));
kotlinEffectExpressionMetadata.orRightHandSideAccept(clazz,
kotlinEffectMetadata,
new EffectExprConstructor(effectExprVis));
kotlinEffectExpressionMetadata.typeOfIsAccept(clazz,
new TypeConstructor(effectExprVis));
effectExprVis.visitEnd();
}
@Override
public void visitAndRHSExpression(Clazz clazz,
KotlinEffectMetadata kotlinEffectMetadata,
KotlinEffectExpressionMetadata lhs,
KotlinEffectExpressionMetadata rhs)
{
effectExprVis = nestedExprVis.visitAndArgument();
visitAnyEffectExpression(clazz, kotlinEffectMetadata, rhs);
}
@Override
public void visitOrRHSExpression(Clazz clazz,
KotlinEffectMetadata kotlinEffectMetadata,
KotlinEffectExpressionMetadata lhs,
KotlinEffectExpressionMetadata rhs)
{
effectExprVis = nestedExprVis.visitOrArgument();
visitAnyEffectExpression(clazz, kotlinEffectMetadata, rhs);
}
@Override
public void visitConstructorArgExpression(Clazz clazz,
KotlinEffectMetadata kotlinEffectMetadata,
KotlinEffectExpressionMetadata kotlinEffectExpressionMetadata)
{
effectExprVis = effectVis.visitConstructorArgument();
visitAnyEffectExpression(clazz, kotlinEffectMetadata, kotlinEffectExpressionMetadata);
}
@Override
public void visitConclusionExpression(Clazz clazz,
KotlinEffectMetadata kotlinEffectMetadata,
KotlinEffectExpressionMetadata kotlinEffectExpressionMetadata)
{
effectExprVis = effectVis.visitConclusionOfConditionalEffect();
visitAnyEffectExpression(clazz, kotlinEffectMetadata, kotlinEffectExpressionMetadata);
}
}
private class KotlinDeclarationContainerConstructor
implements KotlinPropertyVisitor,
KotlinFunctionVisitor,
KotlinTypeAliasVisitor
{
KmDeclarationContainerVisitor kmdWriter;
KmPropertyVisitor kmdPropertyVisitor;
JvmDeclarationContainerExtensionVisitor extensionVisitor;
KotlinDeclarationContainerConstructor(KmDeclarationContainerVisitor classKmdWriter)
{
kmdWriter = classKmdWriter;
}
// Simplifications for KotlinPropertyVisitor.
@Override
public void visitAnyProperty(Clazz clazz,
KotlinDeclarationContainerMetadata kotlinDeclarationContainerMetadata,
KotlinPropertyMetadata kotlinPropertyMetadata)
{
kotlinPropertyMetadata.typeAccept(clazz,
kotlinDeclarationContainerMetadata,
new TypeConstructor(kmdPropertyVisitor));
kotlinPropertyMetadata.receiverTypeAccept(clazz,
kotlinDeclarationContainerMetadata,
new TypeConstructor(kmdPropertyVisitor));
kotlinPropertyMetadata.setterParametersAccept(clazz,
kotlinDeclarationContainerMetadata,
new ValueParameterConstructor(kmdPropertyVisitor));
kotlinPropertyMetadata.typeParametersAccept(clazz,
kotlinDeclarationContainerMetadata,
new TypeParameterConstructor(kmdPropertyVisitor));
kotlinPropertyMetadata.versionRequirementAccept(clazz,
kotlinDeclarationContainerMetadata,
new VersionRequirementConstructor(kmdPropertyVisitor));
JvmPropertyExtensionVisitor ext =
(JvmPropertyExtensionVisitor) kmdPropertyVisitor.visitExtensions(JvmPropertyExtensionVisitor.TYPE);
JvmMethodSignature getterSignature = toKotlinJvmMethodSignature(kotlinPropertyMetadata.getterSignature);
JvmMethodSignature setterSignature = toKotlinJvmMethodSignature(kotlinPropertyMetadata.setterSignature);
JvmFieldSignature backingFieldSignature = toKotlinJvmFieldSignature(kotlinPropertyMetadata.backingFieldSignature);
ext.visit(convertPropertyJvmFlags(kotlinPropertyMetadata.flags),
backingFieldSignature,
getterSignature,
setterSignature);
if (kotlinPropertyMetadata.syntheticMethodForAnnotations != null)
{
ext.visitSyntheticMethodForAnnotations(
toKotlinJvmMethodSignature(kotlinPropertyMetadata.syntheticMethodForAnnotations)
);
}
ext.visitEnd();
kmdPropertyVisitor.visitEnd();
}
@Override
public void visitProperty(Clazz clazz,
KotlinDeclarationContainerMetadata kotlinDeclarationContainerMetadata,
KotlinPropertyMetadata kotlinPropertyMetadata)
{
kmdPropertyVisitor =
kmdWriter.visitProperty(convertPropertyFlags(kotlinPropertyMetadata.flags),
kotlinPropertyMetadata.name,
convertPropertyAccessorFlags(kotlinPropertyMetadata.getterFlags),
convertPropertyAccessorFlags(kotlinPropertyMetadata.setterFlags));
visitAnyProperty(clazz, kotlinDeclarationContainerMetadata, kotlinPropertyMetadata);
}
@Override
public void visitDelegatedProperty(Clazz clazz,
KotlinDeclarationContainerMetadata kotlinDeclarationContainerMetadata,
KotlinPropertyMetadata kotlinPropertyMetadata)
{
kmdPropertyVisitor =
extensionVisitor.visitLocalDelegatedProperty(convertPropertyFlags(kotlinPropertyMetadata.flags),
kotlinPropertyMetadata.name,
convertPropertyAccessorFlags(kotlinPropertyMetadata.getterFlags),
convertPropertyAccessorFlags(kotlinPropertyMetadata.setterFlags));
visitAnyProperty(clazz, kotlinDeclarationContainerMetadata, kotlinPropertyMetadata);
}
// Simplifications for KotlinFunctionVisitor.
@Override
public void visitAnyFunction(Clazz clazz, KotlinMetadata kotlinMetadata, KotlinFunctionMetadata kotlinFunctionMetadata) {}
@Override
public void visitFunction(Clazz clazz,
KotlinDeclarationContainerMetadata kotlinDeclarationContainerMetadata,
KotlinFunctionMetadata kotlinFunctionMetadata)
{
KmFunctionVisitor kmdFunctionVisitor =
kmdWriter.visitFunction(convertFunctionFlags(kotlinFunctionMetadata.flags),
kotlinFunctionMetadata.name);
kotlinFunctionMetadata.valueParametersAccept(clazz,
kotlinDeclarationContainerMetadata,
new ValueParameterConstructor(kmdFunctionVisitor));
kotlinFunctionMetadata.returnTypeAccept(clazz,
kotlinDeclarationContainerMetadata,
new TypeConstructor(kmdFunctionVisitor));
kotlinFunctionMetadata.receiverTypeAccept(clazz,
kotlinDeclarationContainerMetadata,
new TypeConstructor(kmdFunctionVisitor));
kotlinFunctionMetadata.typeParametersAccept(clazz,
kotlinDeclarationContainerMetadata,
new TypeParameterConstructor(kmdFunctionVisitor));
kotlinFunctionMetadata.versionRequirementAccept(clazz,
kotlinDeclarationContainerMetadata,
new VersionRequirementConstructor(kmdFunctionVisitor));
kotlinFunctionMetadata.contractsAccept(clazz,
kotlinDeclarationContainerMetadata,
new ContractConstructor(kmdFunctionVisitor));
JvmFunctionExtensionVisitor ext =
(JvmFunctionExtensionVisitor) kmdFunctionVisitor.visitExtensions(JvmFunctionExtensionVisitor.TYPE);
JvmMethodSignature jvmMethodSignature = toKotlinJvmMethodSignature(kotlinFunctionMetadata.jvmSignature);
ext.visit(jvmMethodSignature);
if (kotlinFunctionMetadata.lambdaClassOriginName != null)
{
ext.visitLambdaClassOriginName(kotlinFunctionMetadata.lambdaClassOriginName);
}
ext.visitEnd();
kmdFunctionVisitor.visitEnd();
}
// Implementations for KotlinTypeAliasVisitor
@Override
public void visitTypeAlias(Clazz clazz,
KotlinDeclarationContainerMetadata kotlinDeclarationContainerMetadata,
KotlinTypeAliasMetadata kotlinTypeAliasMetadata)
{
KmTypeAliasVisitor kmdAliasVisitor =
kmdWriter.visitTypeAlias(convertTypeAliasFlags(kotlinTypeAliasMetadata.flags),
kotlinTypeAliasMetadata.name);
kotlinTypeAliasMetadata.typeParametersAccept(clazz,
kotlinDeclarationContainerMetadata,
new TypeParameterConstructor(kmdAliasVisitor));
kotlinTypeAliasMetadata.underlyingTypeAccept(clazz,
kotlinDeclarationContainerMetadata,
new TypeConstructor(kmdAliasVisitor));
kotlinTypeAliasMetadata.expandedTypeAccept(clazz,
kotlinDeclarationContainerMetadata,
new TypeConstructor(kmdAliasVisitor));
kotlinTypeAliasMetadata.versionRequirementAccept(clazz,
kotlinDeclarationContainerMetadata,
new VersionRequirementConstructor(kmdAliasVisitor));
kotlinTypeAliasMetadata.annotationsAccept(clazz,
new AnnotationConstructor(kmdAliasVisitor::visitAnnotation));
kmdAliasVisitor.visitEnd();
}
// Implementations for KotlinMetadataVisitor.
public void visitAnyKotlinMetadata(Clazz clazz, KotlinMetadata kotlinMetadata) {}
}
/**
* This utility class constructs the protobuf (d1 and d2 arrays) for Kotlin class (k == 1) metadata.
*/
private class KotlinClassConstructor
extends KotlinDeclarationContainerConstructor
implements KotlinMetadataVisitor,
// Implementation interfaces.
KotlinConstructorVisitor
{
KotlinClassMetadata.Class.Writer classKmdWriter;
KotlinClassConstructor()
{
this(new KotlinClassMetadata.Class.Writer());
}
private KotlinClassConstructor(KotlinClassMetadata.Class.Writer classKmdWriter)
{
super(classKmdWriter);
this.classKmdWriter = classKmdWriter;
}
// Implementations for KotlinMetadataVisitor.
@Override
public void visitKotlinClassMetadata(Clazz clazz, KotlinClassKindMetadata kotlinClassKindMetadata)
{
classKmdWriter.visit(convertClassFlags(kotlinClassKindMetadata.flags),
kotlinClassKindMetadata.className.replace('$','.'));
if (kotlinClassKindMetadata.companionObjectName != null)
{
classKmdWriter.visitCompanionObject(kotlinClassKindMetadata.companionObjectName);
}
kotlinClassKindMetadata.propertiesAccept(clazz, this);
kotlinClassKindMetadata.functionsAccept(clazz, this);
kotlinClassKindMetadata.typeAliasesAccept(clazz, this);
for (String enumEntry : kotlinClassKindMetadata.enumEntryNames)
{
classKmdWriter.visitEnumEntry(enumEntry);
}
for (String nestedClass : kotlinClassKindMetadata.nestedClassNames)
{
classKmdWriter.visitNestedClass(nestedClass);
}
for (String sealedSubClass : kotlinClassKindMetadata.sealedSubclassNames)
{
classKmdWriter.visitSealedSubclass(sealedSubClass.replace('$', '.'));
}
kotlinClassKindMetadata.constructorsAccept(clazz, this);
kotlinClassKindMetadata.superTypesAccept(clazz, new TypeConstructor(classKmdWriter));
kotlinClassKindMetadata.typeParametersAccept(clazz, new TypeParameterConstructor(classKmdWriter));
kotlinClassKindMetadata.versionRequirementAccept(clazz, new VersionRequirementConstructor(classKmdWriter));
// Extensions.
JvmClassExtensionVisitor ext =
(JvmClassExtensionVisitor) classKmdWriter.visitExtensions(JvmClassExtensionVisitor.TYPE);
extensionVisitor = ext;
kotlinClassKindMetadata.delegatedPropertiesAccept(clazz, this);
if (kotlinClassKindMetadata.anonymousObjectOriginName != null)
{
ext.visitAnonymousObjectOriginName(kotlinClassKindMetadata.anonymousObjectOriginName);
}
ext.visitEnd();
// Finish.
classKmdWriter.visitEnd();
// Finally store the protobuf contents in the fields of the enclosing class.
KotlinClassHeader header = classKmdWriter.write(COMPATIBLE_METADATA_VERSION,
kotlinClassKindMetadata.xi).getHeader();
k = header.getKind();
mv = header.getMetadataVersion();
bv = header.getBytecodeVersion();
d1 = header.getData1();
d2 = header.getData2();
xi = header.getExtraInt();
xs = header.getExtraString();
pn = header.getPackageName();
}
// Implementations for KotlinConstructorVisitor.
@Override
public void visitConstructor(Clazz clazz,
KotlinClassKindMetadata kotlinClassKindMetadata,
KotlinConstructorMetadata kotlinConstructorMetadata)
{
KmConstructorVisitor constructorVis =
classKmdWriter.visitConstructor(convertConstructorFlags(kotlinConstructorMetadata.flags));
kotlinConstructorMetadata.valueParametersAccept(clazz,
kotlinClassKindMetadata,
new ValueParameterConstructor(constructorVis));
kotlinConstructorMetadata.versionRequirementAccept(clazz,
kotlinClassKindMetadata,
new VersionRequirementConstructor(constructorVis));
// Extensions.
if (kotlinConstructorMetadata.jvmSignature != null)
{
JvmConstructorExtensionVisitor constExtVis =
(JvmConstructorExtensionVisitor)constructorVis.visitExtensions(JvmConstructorExtensionVisitor.TYPE);
JvmMethodSignature jvmMethodSignature = toKotlinJvmMethodSignature(kotlinConstructorMetadata.jvmSignature);
constExtVis.visit(jvmMethodSignature);
}
// Finish.
constructorVis.visitEnd();
}
private int convertClassFlags(KotlinClassFlags flags)
{
Set flagSet = new HashSet<>();
flagSet.addAll(convertCommonFlags(flags.common));
flagSet.addAll(convertVisibilityFlags(flags.visibility));
flagSet.addAll(convertModalityFlags(flags.modality));
if (flags.isUsualClass) flagSet.add(Flag.Class.IS_CLASS);
if (flags.isInterface) flagSet.add(Flag.Class.IS_INTERFACE);
if (flags.isEnumClass) flagSet.add(Flag.Class.IS_ENUM_CLASS);
if (flags.isEnumEntry) flagSet.add(Flag.Class.IS_ENUM_ENTRY);
if (flags.isAnnotationClass) flagSet.add(Flag.Class.IS_ANNOTATION_CLASS);
if (flags.isObject) flagSet.add(Flag.Class.IS_OBJECT);
if (flags.isCompanionObject) flagSet.add(Flag.Class.IS_COMPANION_OBJECT);
if (flags.isInner) flagSet.add(Flag.Class.IS_INNER);
if (flags.isData) flagSet.add(Flag.Class.IS_DATA);
if (flags.isExternal) flagSet.add(Flag.Class.IS_EXTERNAL);
if (flags.isExpect) flagSet.add(Flag.Class.IS_EXPECT);
if (flags.isInline) flagSet.add(Flag.Class.IS_INLINE);
if (flags.isFun) flagSet.add(Flag.Class.IS_FUN);
return flagsOf(flagSet.toArray(new Flag[0]));
}
private int convertConstructorFlags(KotlinConstructorFlags flags)
{
Set flagSet = new HashSet<>();
flagSet.addAll(convertCommonFlags(flags.common));
flagSet.addAll(convertVisibilityFlags(flags.visibility));
if (flags.isPrimary) flagSet.add(Flag.Constructor.IS_PRIMARY);
if (flags.isSecondary) flagSet.add(Flag.Constructor.IS_SECONDARY);
if (flags.hasNonStableParameterNames) flagSet.add(Flag.Constructor.HAS_NON_STABLE_PARAMETER_NAMES);
return flagsOf(flagSet.toArray(new Flag[0]));
}
}
private class ValueParameterConstructor
implements KotlinValueParameterVisitor
{
private KmValueParameterVisitor valParamVis;
private KmConstructorVisitor constructorVis;
ValueParameterConstructor(KmConstructorVisitor constructorVis) { this.constructorVis = constructorVis; }
private KmPropertyVisitor propertyVis;
ValueParameterConstructor(KmPropertyVisitor propertyVis) { this.propertyVis = propertyVis; }
private KmFunctionVisitor functionVis;
ValueParameterConstructor(KmFunctionVisitor functionVis) { this.functionVis = functionVis; }
// Implementations for KotlinValueParameterVisitor.
@Override
public void visitAnyValueParameter(Clazz clazz,
KotlinValueParameterMetadata kotlinValueParameterMetadata) {}
@Override
public void visitConstructorValParameter(Clazz clazz,
KotlinClassKindMetadata kotlinClassKindMetadata,
KotlinConstructorMetadata kotlinConstructorMetadata,
KotlinValueParameterMetadata kotlinValueParameterMetadata)
{
valParamVis =
constructorVis.visitValueParameter(convertValueParameterFlags(kotlinValueParameterMetadata.flags),
kotlinValueParameterMetadata.parameterName);
kotlinValueParameterMetadata.typeAccept(clazz,
kotlinClassKindMetadata,
kotlinConstructorMetadata,
new TypeConstructor(valParamVis));
valParamVis.visitEnd();
}
@Override
public void visitPropertyValParameter(Clazz clazz,
KotlinDeclarationContainerMetadata kotlinDeclarationContainerMetadata,
KotlinPropertyMetadata kotlinPropertyMetadata,
KotlinValueParameterMetadata kotlinValueParameterMetadata)
{
valParamVis =
propertyVis.visitSetterParameter(convertValueParameterFlags(kotlinValueParameterMetadata.flags),
kotlinValueParameterMetadata.parameterName);
kotlinValueParameterMetadata.typeAccept(clazz,
kotlinDeclarationContainerMetadata,
kotlinPropertyMetadata,
new TypeConstructor(valParamVis));
valParamVis.visitEnd();
}
@Override
public void visitFunctionValParameter(Clazz clazz,
KotlinMetadata kotlinMetadata,
KotlinFunctionMetadata kotlinFunctionMetadata,
KotlinValueParameterMetadata kotlinValueParameterMetadata)
{
valParamVis =
functionVis.visitValueParameter(convertValueParameterFlags(kotlinValueParameterMetadata.flags),
kotlinValueParameterMetadata.parameterName);
kotlinValueParameterMetadata.typeAccept(clazz,
kotlinMetadata,
kotlinFunctionMetadata,
new TypeConstructor(valParamVis));
valParamVis.visitEnd();
}
}
private class TypeConstructor
implements KotlinTypeVisitor
{
private KmTypeVisitor typeVis;
private KmTypeVisitor nestedTypeVis;
TypeConstructor(KmTypeVisitor nestedTypeVis) { this.nestedTypeVis = nestedTypeVis; }
private KmValueParameterVisitor valParamVis;
TypeConstructor(KmValueParameterVisitor valParamVis) { this.valParamVis = valParamVis; }
private KmClassVisitor classVis;
TypeConstructor(KmClassVisitor classVis) { this.classVis = classVis; }
private KmPropertyVisitor propertyVis;
TypeConstructor(KmPropertyVisitor propertyVis) { this.propertyVis = propertyVis; }
private KmFunctionVisitor functionVis;
TypeConstructor(KmFunctionVisitor functionVis) { this.functionVis = functionVis; }
private KmTypeAliasVisitor aliasVis;
TypeConstructor(KmTypeAliasVisitor aliasVis) { this.aliasVis = aliasVis; }
private KmTypeParameterVisitor typeParamVis;
TypeConstructor(KmTypeParameterVisitor typeParamVis) { this.typeParamVis = typeParamVis; }
private KmEffectExpressionVisitor effectExpressionVis;
TypeConstructor(KmEffectExpressionVisitor effectExpressionVis) { this.effectExpressionVis = effectExpressionVis; }
// Implementations for KotlinTypeVisitor.
@Override
public void visitTypeUpperBound(Clazz clazz,
KotlinTypeMetadata boundedType,
KotlinTypeMetadata upperBound)
{
typeVis = nestedTypeVis.visitFlexibleTypeUpperBound(convertTypeFlags(boundedType.flags), upperBound.flexibilityID);
visitAnyType(clazz, upperBound);
}
@Override
public void visitAbbreviation(Clazz clazz,
KotlinTypeMetadata abbreviatedType,
KotlinTypeMetadata abbreviation)
{
typeVis = nestedTypeVis.visitAbbreviatedType(convertTypeFlags(abbreviatedType.flags));
visitAnyType(clazz, abbreviation);
}
@Override
public void visitParameterUpperBound(Clazz clazz,
KotlinTypeParameterMetadata boundedTypeParameter,
KotlinTypeMetadata upperBound)
{
typeVis = typeParamVis.visitUpperBound(convertTypeFlags(upperBound.flags));
visitAnyType(clazz, upperBound);
}
@Override
public void visitTypeOfIsExpression(Clazz clazz,
KotlinEffectExpressionMetadata kotlinEffectExprMetadata,
KotlinTypeMetadata typeOfIs)
{
typeVis = effectExpressionVis.visitIsInstanceType(convertTypeFlags(typeOfIs.flags));
visitAnyType(clazz, typeOfIs);
}
@Override
public void visitTypeArgument(Clazz clazz,
KotlinTypeMetadata kotlinTypeMetadata,
KotlinTypeMetadata typeArgument)
{
typeVis = nestedTypeVis.visitArgument(convertTypeFlags(typeArgument.flags), toKmVariance(typeArgument.variance));
visitAnyType(clazz, typeArgument);
}
@Override
public void visitStarProjection(Clazz clazz,
KotlinTypeMetadata typeWithStarArg)
{
nestedTypeVis.visitStarProjection();
}
@Override
public void visitOuterClass(Clazz clazz,
KotlinTypeMetadata innerClass,
KotlinTypeMetadata outerClass)
{
typeVis = nestedTypeVis.visitOuterType(convertTypeFlags(outerClass.flags));
visitAnyType(clazz, outerClass);
}
@Override
public void visitConstructorValParamType(Clazz clazz,
KotlinDeclarationContainerMetadata kotlinDeclarationContainerMetadata,
KotlinConstructorMetadata kotlinConstructorMetadata,
KotlinValueParameterMetadata kotlinValueParameterMetadata,
KotlinTypeMetadata kotlinTypeMetadata)
{
typeVis = valParamVis.visitType(convertTypeFlags(kotlinTypeMetadata.flags));
visitAnyType(clazz, kotlinTypeMetadata);
}
@Override
public void visitConstructorValParamVarArgType(Clazz clazz,
KotlinDeclarationContainerMetadata kotlinDeclarationContainerMetadata,
KotlinConstructorMetadata kotlinConstructorMetadata,
KotlinValueParameterMetadata kotlinValueParameterMetadata,
KotlinTypeMetadata kotlinTypeMetadata)
{
typeVis = valParamVis.visitType(convertTypeFlags(kotlinTypeMetadata.flags));
visitAnyType(clazz, kotlinTypeMetadata);
}
@Override
public void visitSuperType(Clazz clazz,
KotlinClassKindMetadata kotlinMetadata,
KotlinTypeMetadata kotlinTypeMetadata)
{
typeVis = classVis.visitSupertype(convertTypeFlags(kotlinTypeMetadata.flags));
visitAnyType(clazz, kotlinTypeMetadata);
}
@Override
public void visitPropertyType(Clazz clazz,
KotlinDeclarationContainerMetadata kotlinDeclarationContainerMetadata,
KotlinPropertyMetadata kotlinPropertyMetadata,
KotlinTypeMetadata kotlinTypeMetadata)
{
typeVis = propertyVis.visitReturnType(convertTypeFlags(kotlinTypeMetadata.flags));
visitAnyType(clazz, kotlinTypeMetadata);
}
@Override
public void visitPropertyReceiverType(Clazz clazz,
KotlinDeclarationContainerMetadata kotlinDeclarationContainerMetadata,
KotlinPropertyMetadata kotlinPropertyMetadata,
KotlinTypeMetadata kotlinTypeMetadata)
{
typeVis = propertyVis.visitReceiverParameterType(convertTypeFlags(kotlinTypeMetadata.flags));
visitAnyType(clazz, kotlinTypeMetadata);
}
@Override
public void visitPropertyValParamType(Clazz clazz,
KotlinDeclarationContainerMetadata kotlinDeclarationContainerMetadata,
KotlinPropertyMetadata kotlinPropertyMetadata,
KotlinValueParameterMetadata kotlinValueParameterMetadata,
KotlinTypeMetadata kotlinTypeMetadata)
{
typeVis = valParamVis.visitType(convertTypeFlags(kotlinTypeMetadata.flags));
visitAnyType(clazz, kotlinTypeMetadata);
}
@Override
public void visitPropertyValParamVarArgType(Clazz clazz,
KotlinDeclarationContainerMetadata kotlinDeclarationContainerMetadata,
KotlinPropertyMetadata kotlinPropertyMetadata,
KotlinValueParameterMetadata kotlinValueParameterMetadata,
KotlinTypeMetadata kotlinTypeMetadata)
{
typeVis = valParamVis.visitVarargElementType(convertTypeFlags(kotlinTypeMetadata.flags));
visitAnyType(clazz, kotlinTypeMetadata);
}
@Override
public void visitFunctionReturnType(Clazz clazz,
KotlinMetadata kotlinMetadata,
KotlinFunctionMetadata kotlinFunctionMetadata,
KotlinTypeMetadata kotlinTypeMetadata)
{
typeVis = functionVis.visitReturnType(convertTypeFlags(kotlinTypeMetadata.flags));
visitAnyType(clazz, kotlinTypeMetadata);
}
@Override
public void visitFunctionReceiverType(Clazz clazz,
KotlinMetadata kotlinMetadata,
KotlinFunctionMetadata kotlinFunctionMetadata,
KotlinTypeMetadata kotlinTypeMetadata)
{
typeVis = functionVis.visitReceiverParameterType(convertTypeFlags(kotlinTypeMetadata.flags));
visitAnyType(clazz, kotlinTypeMetadata);
}
@Override
public void visitFunctionValParamType(Clazz clazz,
KotlinMetadata kotlinMetadata,
KotlinFunctionMetadata kotlinFunctionMetadata,
KotlinValueParameterMetadata kotlinValueParameterMetadata,
KotlinTypeMetadata kotlinTypeMetadata)
{
typeVis = valParamVis.visitType(convertTypeFlags(kotlinTypeMetadata.flags));
visitAnyType(clazz, kotlinTypeMetadata);
}
@Override
public void visitFunctionValParamVarArgType(Clazz clazz,
KotlinMetadata kotlinMetadata,
KotlinFunctionMetadata kotlinFunctionMetadata,
KotlinValueParameterMetadata kotlinValueParameterMetadata,
KotlinTypeMetadata kotlinTypeMetadata)
{
typeVis = valParamVis.visitVarargElementType(convertTypeFlags(kotlinTypeMetadata.flags));
visitAnyType(clazz, kotlinTypeMetadata);
}
@Override
public void visitAliasUnderlyingType(Clazz clazz,
KotlinDeclarationContainerMetadata kotlinDeclarationContainerMetadata,
KotlinTypeAliasMetadata kotlinTypeAliasMetadata,
KotlinTypeMetadata kotlinTypeMetadata)
{
typeVis = aliasVis.visitUnderlyingType(convertTypeFlags(kotlinTypeMetadata.flags));
visitAnyType(clazz, kotlinTypeMetadata);
}
@Override
public void visitAliasExpandedType(Clazz clazz,
KotlinDeclarationContainerMetadata kotlinDeclarationContainerMetadata,
KotlinTypeAliasMetadata kotlinTypeAliasMetadata,
KotlinTypeMetadata kotlinTypeMetadata)
{
typeVis = aliasVis.visitExpandedType(convertTypeFlags(kotlinTypeMetadata.flags));
visitAnyType(clazz, kotlinTypeMetadata);
}
// Small helper methods.
@Override
public void visitAnyType(Clazz clazz, KotlinTypeMetadata kotlinTypeMetadata)
{
if (kotlinTypeMetadata.className != null)
{
// Transform the class name back to the Kotlin metadata format.
String className = kotlinTypeMetadata.className.replace(TypeConstants. INNER_CLASS_SEPARATOR,
KotlinConstants.INNER_CLASS_SEPARATOR);
typeVis.visitClass(className);
}
if (kotlinTypeMetadata.typeParamID >= 0)
{
typeVis.visitTypeParameter(kotlinTypeMetadata.typeParamID);
}
if (kotlinTypeMetadata.aliasName != null)
{
typeVis.visitTypeAlias(kotlinTypeMetadata.aliasName);
}
kotlinTypeMetadata.abbreviationAccept( clazz, new TypeConstructor(typeVis));
kotlinTypeMetadata.outerClassAccept( clazz, new TypeConstructor(typeVis));
kotlinTypeMetadata.typeArgumentsAccept(clazz, new TypeConstructor(typeVis));
kotlinTypeMetadata.upperBoundsAccept( clazz, new TypeConstructor(typeVis));
// Extensions.
JvmTypeExtensionVisitor typeExtVis =
(JvmTypeExtensionVisitor)typeVis.visitExtensions(JvmTypeExtensionVisitor.TYPE);
typeExtVis.visit(kotlinTypeMetadata.isRaw);
kotlinTypeMetadata.annotationsAccept(clazz,
new AnnotationConstructor(typeExtVis::visitAnnotation));
typeExtVis.visitEnd();
typeVis.visitEnd();
}
}
private class TypeParameterConstructor
implements KotlinTypeParameterVisitor
{
private KmTypeParameterVisitor typeParamVis;
private KmClassVisitor classVis;
TypeParameterConstructor(KmClassVisitor classVis) { this.classVis = classVis; }
private KmPropertyVisitor propertyVis;
TypeParameterConstructor(KmPropertyVisitor propertyVis) { this.propertyVis = propertyVis; }
private KmFunctionVisitor functionVis;
TypeParameterConstructor(KmFunctionVisitor functionVis) { this.functionVis = functionVis; }
private KmTypeAliasVisitor aliasVis;
TypeParameterConstructor(KmTypeAliasVisitor aliasVis) { this.aliasVis = aliasVis; }
// Implementations for KotlinTypeParameterVisitor.
@Override
public void visitClassTypeParameter(Clazz clazz,
KotlinClassKindMetadata kotlinMetadata,
KotlinTypeParameterMetadata kotlinTypeParameterMetadata)
{
typeParamVis = classVis.visitTypeParameter(convertTypeParameterFlags(kotlinTypeParameterMetadata.flags),
kotlinTypeParameterMetadata.name,
kotlinTypeParameterMetadata.id,
toKmVariance(kotlinTypeParameterMetadata.variance));
visitAnyTypeParameter(clazz, kotlinTypeParameterMetadata);
}
@Override
public void visitPropertyTypeParameter(Clazz clazz,
KotlinDeclarationContainerMetadata kotlinDeclarationContainerMetadata,
KotlinPropertyMetadata kotlinPropertyMetadata,
KotlinTypeParameterMetadata kotlinTypeParameterMetadata)
{
typeParamVis = propertyVis.visitTypeParameter(convertTypeParameterFlags(kotlinTypeParameterMetadata.flags),
kotlinTypeParameterMetadata.name,
kotlinTypeParameterMetadata.id,
toKmVariance(kotlinTypeParameterMetadata.variance));
visitAnyTypeParameter(clazz, kotlinTypeParameterMetadata);
}
@Override
public void visitFunctionTypeParameter(Clazz clazz,
KotlinMetadata kotlinMetadata,
KotlinFunctionMetadata kotlinFunctionMetadata,
KotlinTypeParameterMetadata kotlinTypeParameterMetadata)
{
typeParamVis = functionVis.visitTypeParameter(convertTypeParameterFlags(kotlinTypeParameterMetadata.flags),
kotlinTypeParameterMetadata.name,
kotlinTypeParameterMetadata.id,
toKmVariance(kotlinTypeParameterMetadata.variance));
visitAnyTypeParameter(clazz, kotlinTypeParameterMetadata);
}
@Override
public void visitAliasTypeParameter(Clazz clazz,
KotlinDeclarationContainerMetadata kotlinDeclarationContainerMetadata,
KotlinTypeAliasMetadata kotlinTypeAliasMetadata,
KotlinTypeParameterMetadata kotlinTypeParameterMetadata)
{
typeParamVis = aliasVis.visitTypeParameter(convertTypeParameterFlags(kotlinTypeParameterMetadata.flags),
kotlinTypeParameterMetadata.name,
kotlinTypeParameterMetadata.id,
toKmVariance(kotlinTypeParameterMetadata.variance));
visitAnyTypeParameter(clazz, kotlinTypeParameterMetadata);
}
// Small helper methods.
@Override
public void visitAnyTypeParameter(Clazz clazz, KotlinTypeParameterMetadata kotlinTypeParameterMetadata)
{
kotlinTypeParameterMetadata.upperBoundsAccept(clazz,
new TypeConstructor(typeParamVis));
// Extensions.
JvmTypeParameterExtensionVisitor typeParamExtVis =
(JvmTypeParameterExtensionVisitor)typeParamVis.visitExtensions(JvmTypeParameterExtensionVisitor.TYPE);
kotlinTypeParameterMetadata.annotationsAccept(clazz,
new AnnotationConstructor(typeParamExtVis::visitAnnotation));
typeParamExtVis.visitEnd();
typeParamVis.visitEnd();
}
}
/**
* This utility class constructs the protobuf (d1 and d2 arrays) for Kotlin file facade (k == 2) metadata.
*/
private class KotlinFileFacadeConstructor
extends KotlinDeclarationContainerConstructor
implements KotlinMetadataVisitor
{
private final KotlinClassMetadata.FileFacade.Writer facadeKmdWriter;
KotlinFileFacadeConstructor()
{
this(new KotlinClassMetadata.FileFacade.Writer());
}
private KotlinFileFacadeConstructor(KotlinClassMetadata.FileFacade.Writer facadeKmdWriter)
{
super(facadeKmdWriter);
this.facadeKmdWriter = facadeKmdWriter;
}
// Implementations for KotlinMetadataVisitor.
@Override
public void visitKotlinFileFacadeMetadata(Clazz clazz, KotlinFileFacadeKindMetadata kotlinFileFacadeKindMetadata)
{
kotlinFileFacadeKindMetadata.propertiesAccept(clazz, this);
kotlinFileFacadeKindMetadata.functionsAccept(clazz, this);
kotlinFileFacadeKindMetadata.typeAliasesAccept(clazz, this);
JvmPackageExtensionVisitor ext =
(JvmPackageExtensionVisitor) kmdWriter.visitExtensions(JvmPackageExtensionVisitor.TYPE);
extensionVisitor = ext;
kotlinFileFacadeKindMetadata.delegatedPropertiesAccept(clazz, this);
ext.visitEnd();
facadeKmdWriter.visitEnd();
// Finally store the protobuf contents in the fields of the enclosing class.
KotlinClassHeader header = facadeKmdWriter.write(COMPATIBLE_METADATA_VERSION,
kotlinFileFacadeKindMetadata.xi).getHeader();
k = header.getKind();
mv = header.getMetadataVersion();
bv = header.getBytecodeVersion();
d1 = header.getData1();
d2 = header.getData2();
xi = header.getExtraInt();
xs = header.getExtraString();
pn = header.getPackageName();
}
}
/**
* This utility class constructs the protobuf (d1 and d2 arrays) for Kotlin synthetic class (k == 3) metadata.
*/
private class KotlinSyntheticClassConstructor
implements KotlinMetadataVisitor,
// Implementation interfaces.
KotlinFunctionVisitor
{
private KotlinSyntheticClassKindMetadata md;
private final KotlinClassMetadata.SyntheticClass.Writer kmdWriter;
KotlinSyntheticClassConstructor()
{
this.kmdWriter = new KotlinClassMetadata.SyntheticClass.Writer();
}
// Implementations for KotlinMetadataVisitor.
@Override
public void visitAnyKotlinMetadata(Clazz clazz, KotlinMetadata kotlinMetadata) {}
@Override
public void visitKotlinSyntheticClassMetadata(Clazz clazz, KotlinSyntheticClassKindMetadata kotlinSyntheticClassKindMetadata)
{
this.md = kotlinSyntheticClassKindMetadata;
md.functionsAccept(clazz, this);
kmdWriter.visitEnd();
// Finally store the protobuf contents in the fields of the enclosing class.
KotlinClassHeader header = kmdWriter.write(COMPATIBLE_METADATA_VERSION,
kotlinSyntheticClassKindMetadata.xi).getHeader();
k = header.getKind();
mv = header.getMetadataVersion();
bv = header.getBytecodeVersion();
d1 = header.getData1();
d2 = header.getData2();
xi = header.getExtraInt();
xs = header.getExtraString();
pn = header.getPackageName();
}
// Implementations for KotlinFunctionVisitor.
@Override
public void visitAnyFunction(Clazz clazz,
KotlinMetadata kotlinMetadata,
KotlinFunctionMetadata kotlinFunctionMetadata) {}
@Override
public void visitSyntheticFunction(Clazz clazz,
KotlinSyntheticClassKindMetadata kotlinSyntheticClassKindMetadata,
KotlinFunctionMetadata kotlinFunctionMetadata)
{
KmFunctionVisitor kmdFunctionVisitor =
kmdWriter.visitFunction(convertFunctionFlags(kotlinFunctionMetadata.flags),
kotlinFunctionMetadata.name);
kotlinFunctionMetadata.valueParametersAccept(clazz,
kotlinSyntheticClassKindMetadata,
new ValueParameterConstructor(kmdFunctionVisitor));
kotlinFunctionMetadata.returnTypeAccept(clazz,
kotlinSyntheticClassKindMetadata,
new TypeConstructor(kmdFunctionVisitor));
kotlinFunctionMetadata.receiverTypeAccept(clazz,
kotlinSyntheticClassKindMetadata,
new TypeConstructor(kmdFunctionVisitor));
kotlinFunctionMetadata.typeParametersAccept(clazz,
kotlinSyntheticClassKindMetadata,
new TypeParameterConstructor(kmdFunctionVisitor));
kotlinFunctionMetadata.versionRequirementAccept(clazz,
kotlinSyntheticClassKindMetadata,
new VersionRequirementConstructor(kmdFunctionVisitor));
kotlinFunctionMetadata.contractsAccept(clazz,
kotlinSyntheticClassKindMetadata,
new ContractConstructor(kmdFunctionVisitor));
JvmFunctionExtensionVisitor ext =
(JvmFunctionExtensionVisitor) kmdFunctionVisitor.visitExtensions(JvmFunctionExtensionVisitor.TYPE);
JvmMethodSignature jvmMethodSignature = toKotlinJvmMethodSignature(kotlinFunctionMetadata.jvmSignature);
ext.visit(jvmMethodSignature);
if (kotlinFunctionMetadata.lambdaClassOriginName != null)
{
ext.visitLambdaClassOriginName(kotlinFunctionMetadata.lambdaClassOriginName);
}
ext.visitEnd();
kmdFunctionVisitor.visitEnd();
}
}
/**
* This utility class constructs the d1 array for Kotlin file facade (k == 2) metadata.
*/
private class KotlinMultiFileFacadeConstructor
implements KotlinMetadataVisitor
{
// Implementations for KotlinMetadataVisitor.
@Override
public void visitAnyKotlinMetadata(Clazz clazz, KotlinMetadata kotlinMetadata) {}
@Override
public void visitKotlinMultiFileFacadeMetadata(Clazz clazz, KotlinMultiFileFacadeKindMetadata kotlinMultiFileFacadeKindMetadata)
{
KotlinClassHeader header =
new KotlinClassMetadata.MultiFileClassFacade.Writer()
.write(kotlinMultiFileFacadeKindMetadata.partClassNames,
COMPATIBLE_METADATA_VERSION,
kotlinMultiFileFacadeKindMetadata.xi).getHeader();
k = header.getKind();
mv = header.getMetadataVersion();
bv = header.getBytecodeVersion();
d1 = header.getData1();
d2 = header.getData2();
xi = header.getExtraInt();
xs = header.getExtraString();
pn = header.getPackageName();
}
}
/**
* This utility class constructs the protobuf (d1 and d2 arrays) for Kotlin file facade (k == 2) metadata.
*/
private class KotlinMultiFilePartConstructor
extends KotlinDeclarationContainerConstructor
implements KotlinMetadataVisitor
{
private final KotlinClassMetadata.MultiFileClassPart.Writer multiPartKmdWriter;
KotlinMultiFilePartConstructor()
{
this(new KotlinClassMetadata.MultiFileClassPart.Writer());
}
private KotlinMultiFilePartConstructor(KotlinClassMetadata.MultiFileClassPart.Writer multiPartKmdWriter)
{
super(multiPartKmdWriter);
this.multiPartKmdWriter = multiPartKmdWriter;
}
// Implementations for KotlinMetadataVisitor
@Override
public void visitKotlinMultiFilePartMetadata(Clazz clazz, KotlinMultiFilePartKindMetadata kotlinMultiFilePartKindMetadata)
{
kotlinMultiFilePartKindMetadata.propertiesAccept( clazz, this);
kotlinMultiFilePartKindMetadata.functionsAccept( clazz, this);
kotlinMultiFilePartKindMetadata.typeAliasesAccept(clazz, this);
JvmPackageExtensionVisitor ext =
(JvmPackageExtensionVisitor) multiPartKmdWriter.visitExtensions(JvmPackageExtensionVisitor.TYPE);
extensionVisitor = ext;
kotlinMultiFilePartKindMetadata.delegatedPropertiesAccept(clazz, this);
ext.visitEnd();
multiPartKmdWriter.visitEnd();
// Finally store the protobuf contents in the fields of the enclosing class.
KotlinClassHeader header = multiPartKmdWriter.write(kotlinMultiFilePartKindMetadata.facadeName,
COMPATIBLE_METADATA_VERSION,
kotlinMultiFilePartKindMetadata.xi).getHeader();
k = header.getKind();
mv = header.getMetadataVersion();
bv = header.getBytecodeVersion();
d1 = header.getData1();
d2 = header.getData2();
xi = header.getExtraInt();
xs = header.getExtraString();
pn = header.getPackageName();
}
}
private class VersionRequirementConstructor
implements KotlinVersionRequirementVisitor
{
private KmVersionRequirementVisitor versionReqVis;
private KmConstructorVisitor constructorVis;
VersionRequirementConstructor(KmConstructorVisitor constructorVis) { this.constructorVis = constructorVis; }
private KmClassVisitor classVis;
VersionRequirementConstructor(KmClassVisitor classVis) { this.classVis = classVis; }
private KmPropertyVisitor propertyVis;
VersionRequirementConstructor(KmPropertyVisitor propertyVis) { this.propertyVis = propertyVis; }
private KmFunctionVisitor functionVis;
VersionRequirementConstructor(KmFunctionVisitor functionVis) { this.functionVis = functionVis; }
private KmTypeAliasVisitor aliasVis;
VersionRequirementConstructor(KmTypeAliasVisitor aliasVis) { this.aliasVis = aliasVis; }
// Implementations for KotlinVersionRequirementVisitor.
@Override
public void visitClassVersionRequirement(Clazz clazz,
KotlinMetadata kotlinMetadata,
KotlinVersionRequirementMetadata kotlinVersionRequirementMetadata)
{
versionReqVis = classVis.visitVersionRequirement();
}
@Override
public void visitConstructorVersionRequirement(Clazz clazz,
KotlinMetadata kotlinMetadata,
KotlinConstructorMetadata kotlinConstructorMetadata,
KotlinVersionRequirementMetadata kotlinVersionRequirementMetadata)
{
versionReqVis = constructorVis.visitVersionRequirement();
visitAnyVersionRequirement(clazz, kotlinVersionRequirementMetadata);
}
@Override
public void visitPropertyVersionRequirement(Clazz clazz,
KotlinDeclarationContainerMetadata kotlinDeclarationContainerMetadata,
KotlinPropertyMetadata kotlinPropertyMetadata,
KotlinVersionRequirementMetadata kotlinVersionRequirementMetadata)
{
versionReqVis = propertyVis.visitVersionRequirement();
visitAnyVersionRequirement(clazz, kotlinVersionRequirementMetadata);
}
@Override
public void visitFunctionVersionRequirement(Clazz clazz,
KotlinMetadata kotlinMetadata,
KotlinFunctionMetadata kotlinFunctionMetadata,
KotlinVersionRequirementMetadata kotlinVersionRequirementMetadata)
{
versionReqVis = functionVis.visitVersionRequirement();
visitAnyVersionRequirement(clazz, kotlinVersionRequirementMetadata);
}
public void visitTypeAliasVersionRequirement(Clazz clazz,
KotlinMetadata kotlinMetadata,
KotlinTypeAliasMetadata kotlinTypeAliasMetadata,
KotlinVersionRequirementMetadata kotlinVersionRequirementMetadata)
{
versionReqVis = aliasVis.visitVersionRequirement();
visitAnyVersionRequirement(clazz, kotlinVersionRequirementMetadata);
}
// Small helper methods.
@Override
public void visitAnyVersionRequirement(Clazz clazz,
KotlinVersionRequirementMetadata kotlinVersionRequirementMetadata)
{
versionReqVis.visit(toKmVersionRequirementVersionKind(kotlinVersionRequirementMetadata.kind),
toKmVersionRequirementLevel(kotlinVersionRequirementMetadata.level),
kotlinVersionRequirementMetadata.errorCode,
kotlinVersionRequirementMetadata.message);
versionReqVis.visitVersion(kotlinVersionRequirementMetadata.major,
kotlinVersionRequirementMetadata.minor,
kotlinVersionRequirementMetadata.patch);
versionReqVis.visitEnd();
}
}
// Small helper methods.
private static JvmMethodSignature toKotlinJvmMethodSignature(MethodSignature jvmMethodSignature)
{
if (jvmMethodSignature == null)
{
return null;
}
return new JvmMethodSignature(jvmMethodSignature.method, jvmMethodSignature.descriptor.toString());
}
private static JvmFieldSignature toKotlinJvmFieldSignature(FieldSignature jvmFieldSignature)
{
if (jvmFieldSignature == null)
{
return null;
}
return new JvmFieldSignature(jvmFieldSignature.memberName, jvmFieldSignature.descriptor);
}
private static KmVersionRequirementVersionKind toKmVersionRequirementVersionKind(KotlinVersionRequirementVersionKind kotlinVersionRequirementVersionKind)
{
switch(kotlinVersionRequirementVersionKind)
{
case API_VERSION: return KmVersionRequirementVersionKind.API_VERSION;
case COMPILER_VERSION: return KmVersionRequirementVersionKind.COMPILER_VERSION;
case LANGUAGE_VERSION: return KmVersionRequirementVersionKind.LANGUAGE_VERSION;
default: throw new UnsupportedOperationException("Encountered unknown enum value for KotlinVersionRequirementVersionKind.");
}
}
private static KmVersionRequirementLevel toKmVersionRequirementLevel(KotlinVersionRequirementLevel kotlinVersionRequirementLevel)
{
switch(kotlinVersionRequirementLevel)
{
case ERROR: return KmVersionRequirementLevel.ERROR;
case HIDDEN: return KmVersionRequirementLevel.HIDDEN;
case WARNING: return KmVersionRequirementLevel.WARNING;
default: throw new UnsupportedOperationException("Encountered unknown enum value for KotlinVersionRequirementLevel.");
}
}
private static KmEffectType toKmEffectType(KotlinEffectType effectType)
{
switch(effectType)
{
case CALLS: return KmEffectType.CALLS;
case RETURNS_CONSTANT: return KmEffectType.RETURNS_CONSTANT;
case RETURNS_NOT_NULL: return KmEffectType.RETURNS_NOT_NULL;
default: throw new UnsupportedOperationException("Encountered unknown enum value for KotlinEffectType.");
}
}
private static KmEffectInvocationKind toKmEffectInvocationKind(KotlinEffectInvocationKind invocationKind)
{
if (invocationKind == null)
{
return null;
}
switch(invocationKind)
{
case AT_MOST_ONCE: return KmEffectInvocationKind.AT_MOST_ONCE;
case EXACTLY_ONCE: return KmEffectInvocationKind.EXACTLY_ONCE;
case AT_LEAST_ONCE: return KmEffectInvocationKind.AT_LEAST_ONCE;
default: throw new UnsupportedOperationException("Encountered unknown enum value for KmEffectInvocationKind.");
}
}
// Helper classes to convert Kotlin annotations
private static class AnnotationConstructor implements KotlinAnnotationVisitor
{
private final Consumer consumer;
public AnnotationConstructor(Consumer consumer)
{
this.consumer = consumer;
}
@Override
public void visitAnyAnnotation(Clazz clazz, KotlinAnnotatable annotatable, KotlinAnnotation annotation)
{
Map> arguments = new HashMap<>();
annotation.argumentsAccept(clazz, annotatable, new AnnotationArgumentConstructor(arguments::put));
this.consumer.accept(new KmAnnotation(annotation.className, arguments));
}
}
private static class AnnotationArgumentConstructor implements KotlinAnnotationArgumentVisitor
{
private final BiConsumer> consumer;
public AnnotationArgumentConstructor(BiConsumer> consumer)
{
this.consumer = consumer;
}
@Override
public void visitAnyArgument(Clazz clazz,
KotlinAnnotatable annotatable,
KotlinAnnotation annotation,
KotlinAnnotationArgument argument,
Value value) { }
@Override
public void visitByteArgument(Clazz clazz,
KotlinAnnotatable annotatable,
KotlinAnnotation annotation,
KotlinAnnotationArgument argument,
ByteValue value)
{
this.consumer.accept(argument.name, new KmAnnotationArgument.ByteValue(value.value));
}
@Override
public void visitCharArgument(Clazz clazz,
KotlinAnnotatable annotatable,
KotlinAnnotation annotation,
KotlinAnnotationArgument argument,
CharValue value)
{
this.consumer.accept(argument.name, new KmAnnotationArgument.CharValue(value.value));
}
@Override
public void visitShortArgument(Clazz clazz,
KotlinAnnotatable annotatable,
KotlinAnnotation annotation,
KotlinAnnotationArgument argument,
ShortValue value)
{
this.consumer.accept(argument.name, new KmAnnotationArgument.ShortValue(value.value));
}
@Override
public void visitIntArgument(Clazz clazz,
KotlinAnnotatable annotatable,
KotlinAnnotation annotation,
KotlinAnnotationArgument argument,
IntValue value)
{
this.consumer.accept(argument.name, new KmAnnotationArgument.IntValue(value.value));
}
@Override
public void visitLongArgument(Clazz clazz,
KotlinAnnotatable annotatable,
KotlinAnnotation annotation,
KotlinAnnotationArgument argument,
LongValue value)
{
this.consumer.accept(argument.name, new KmAnnotationArgument.LongValue(value.value));
}
@Override
public void visitFloatArgument(Clazz clazz,
KotlinAnnotatable annotatable,
KotlinAnnotation annotation,
KotlinAnnotationArgument argument,
FloatValue value)
{
this.consumer.accept(argument.name, new KmAnnotationArgument.FloatValue(value.value));
}
@Override
public void visitDoubleArgument(Clazz clazz,
KotlinAnnotatable annotatable,
KotlinAnnotation annotation,
KotlinAnnotationArgument argument,
DoubleValue value)
{
this.consumer.accept(argument.name, new KmAnnotationArgument.DoubleValue(value.value));
}
@Override
public void visitBooleanArgument(Clazz clazz,
KotlinAnnotatable annotatable,
KotlinAnnotation annotation,
KotlinAnnotationArgument argument,
BooleanValue value)
{
this.consumer.accept(argument.name, new KmAnnotationArgument.BooleanValue(value.value));
}
@Override
public void visitUByteArgument(Clazz clazz,
KotlinAnnotatable annotatable,
KotlinAnnotation annotation,
KotlinAnnotationArgument argument,
UByteValue value)
{
this.consumer.accept(argument.name, new KmAnnotationArgument.UByteValue(value.value));
}
@Override
public void visitUShortArgument(Clazz clazz,
KotlinAnnotatable annotatable,
KotlinAnnotation annotation,
KotlinAnnotationArgument argument,
UShortValue value)
{
this.consumer.accept(argument.name, new KmAnnotationArgument.UShortValue(value.value));
}
@Override
public void visitUIntArgument(Clazz clazz,
KotlinAnnotatable annotatable,
KotlinAnnotation annotation,
KotlinAnnotationArgument argument,
UIntValue value)
{
this.consumer.accept(argument.name, new KmAnnotationArgument.UIntValue(value.value));
}
@Override
public void visitULongArgument(Clazz clazz,
KotlinAnnotatable annotatable,
KotlinAnnotation annotation,
KotlinAnnotationArgument argument,
ULongValue value)
{
this.consumer.accept(argument.name, new KmAnnotationArgument.ULongValue(value.value));
}
@Override
public void visitStringArgument(Clazz clazz,
KotlinAnnotatable annotatable,
KotlinAnnotation annotation,
KotlinAnnotationArgument argument,
StringValue value)
{
this.consumer.accept(argument.name, new KmAnnotationArgument.StringValue(value.value));
}
@Override
public void visitClassArgument(Clazz clazz,
KotlinAnnotatable annotatable,
KotlinAnnotation annotation,
KotlinAnnotationArgument argument,
KotlinAnnotationArgument.ClassValue value)
{
this.consumer.accept(argument.name, new KmAnnotationArgument.KClassValue(value.className));
}
@Override
public void visitEnumArgument(Clazz clazz,
KotlinAnnotatable annotatable,
KotlinAnnotation annotation,
KotlinAnnotationArgument argument,
EnumValue value)
{
this.consumer.accept(argument.name, new KmAnnotationArgument.EnumValue(value.className, value.enumEntryName));
}
@Override
public void visitAnnotationArgument(Clazz clazz,
KotlinAnnotatable annotatable,
KotlinAnnotation annotation,
KotlinAnnotationArgument argument,
AnnotationValue value)
{
value.annotationAccept(
clazz,
annotatable,
new AnnotationConstructor(
kmAnnotation -> this.consumer.accept(
argument.name, new KmAnnotationArgument.AnnotationValue(kmAnnotation)
)
)
);
}
@Override
public void visitArrayArgument(Clazz clazz,
KotlinAnnotatable annotatable,
KotlinAnnotation annotation,
KotlinAnnotationArgument argument,
ArrayValue value)
{
List> elements = new ArrayList<>();
value.elementsAccept(
clazz,
annotatable,
annotation,
argument,
new AnnotationArgumentConstructor((__, element) -> elements.add(element))
);
this.consumer.accept(argument.name, new KmAnnotationArgument.ArrayValue(elements));
}
}
private static KmVariance toKmVariance(KotlinTypeVariance variance)
{
switch(variance)
{
case IN: return KmVariance.IN;
case INVARIANT: return KmVariance.INVARIANT;
case OUT: return KmVariance.OUT;
default: throw new UnsupportedOperationException("Encountered unknown enum value for KmVariance.");
}
}
private Set convertCommonFlags(KotlinCommonFlags flags)
{
Set flagSet = new HashSet<>();
if (flags.hasAnnotations) flagSet.add(Flag.HAS_ANNOTATIONS);
return flagSet;
}
private Set convertVisibilityFlags(KotlinVisibilityFlags flags)
{
Set flagSet = new HashSet<>();
if (flags.isInternal) flagSet.add(Flag.IS_INTERNAL);
if (flags.isLocal) flagSet.add(Flag.IS_LOCAL);
if (flags.isPrivate) flagSet.add(Flag.IS_PRIVATE);
if (flags.isProtected) flagSet.add(Flag.IS_PROTECTED);
if (flags.isPublic) flagSet.add(Flag.IS_PUBLIC);
if (flags.isPrivateToThis) flagSet.add(Flag.IS_PRIVATE_TO_THIS);
return flagSet;
}
private Set convertModalityFlags(KotlinModalityFlags flags)
{
Set flagSet = new HashSet<>();
if (flags.isAbstract) flagSet.add(Flag.IS_ABSTRACT);
if (flags.isFinal) flagSet.add(Flag.IS_FINAL);
if (flags.isOpen) flagSet.add(Flag.IS_OPEN);
if (flags.isSealed) flagSet.add(Flag.IS_SEALED);
return flagSet;
}
private int convertFunctionFlags(KotlinFunctionFlags flags)
{
Set flagSet = new HashSet<>();
flagSet.addAll(convertCommonFlags(flags.common));
flagSet.addAll(convertVisibilityFlags(flags.visibility));
flagSet.addAll(convertModalityFlags(flags.modality));
if (flags.isDeclaration) flagSet.add(Flag.Function.IS_DECLARATION);
if (flags.isFakeOverride) flagSet.add(Flag.Function.IS_FAKE_OVERRIDE);
if (flags.isDelegation) flagSet.add(Flag.Function.IS_DELEGATION);
if (flags.isSynthesized) flagSet.add(Flag.Function.IS_SYNTHESIZED);
if (flags.isOperator) flagSet.add(Flag.Function.IS_OPERATOR);
if (flags.isInfix) flagSet.add(Flag.Function.IS_INFIX);
if (flags.isInline) flagSet.add(Flag.Function.IS_INLINE);
if (flags.isTailrec) flagSet.add(Flag.Function.IS_TAILREC);
if (flags.isExternal) flagSet.add(Flag.Function.IS_EXTERNAL);
if (flags.isSuspend) flagSet.add(Flag.Function.IS_SUSPEND);
return flagsOf(flagSet.toArray(new Flag[0]));
}
private int convertTypeFlags(KotlinTypeFlags flags)
{
Set flagSet = new HashSet<>();
flagSet.addAll(convertCommonFlags(flags.common));
if (flags.isNullable) flagSet.add(Flag.Type.IS_NULLABLE);
if (flags.isSuspend) flagSet.add(Flag.Type.IS_SUSPEND);
return flagsOf(flagSet.toArray(new Flag[0]));
}
private int convertTypeParameterFlags(KotlinTypeParameterFlags flags)
{
Set flagSet = new HashSet<>();
flagSet.addAll(convertCommonFlags(flags.common));
if (flags.isReified) flagSet.add(Flag.TypeParameter.IS_REIFIED);
return flagsOf(flagSet.toArray(new Flag[0]));
}
private int convertTypeAliasFlags(KotlinTypeAliasFlags flags)
{
Set flagSet = new HashSet<>();
flagSet.addAll(convertCommonFlags(flags.common));
flagSet.addAll(convertVisibilityFlags(flags.visibility));
return flagsOf(flagSet.toArray(new Flag[0]));
}
private int convertPropertyFlags(KotlinPropertyFlags flags)
{
Set flagSet = new HashSet<>();
flagSet.addAll(convertCommonFlags(flags.common));
flagSet.addAll(convertVisibilityFlags(flags.visibility));
flagSet.addAll(convertModalityFlags(flags.modality));
if (flags.isDeclared) flagSet.add(Flag.Property.IS_DECLARATION);
if (flags.isFakeOverride) flagSet.add(Flag.Property.IS_FAKE_OVERRIDE);
if (flags.isDelegation) flagSet.add(Flag.Property.IS_DELEGATION);
if (flags.isSynthesized) flagSet.add(Flag.Property.IS_SYNTHESIZED);
if (flags.isVar) flagSet.add(Flag.Property.IS_VAR);
if (flags.hasGetter) flagSet.add(Flag.Property.HAS_GETTER);
if (flags.hasSetter) flagSet.add(Flag.Property.HAS_SETTER);
if (flags.isConst) flagSet.add(Flag.Property.IS_CONST);
if (flags.isLateinit) flagSet.add(Flag.Property.IS_LATEINIT);
if (flags.hasConstant) flagSet.add(Flag.Property.HAS_CONSTANT);
if (flags.isExternal) flagSet.add(Flag.Property.IS_EXTERNAL);
if (flags.isDelegated) flagSet.add(Flag.Property.IS_DELEGATED);
if (flags.isExpect) flagSet.add(Flag.Property.IS_EXPECT);
return flagsOf(flagSet.toArray(new Flag[0]));
}
private int convertPropertyJvmFlags(KotlinPropertyFlags flags)
{
return flags.isMovedFromInterfaceCompanion ?
flagsOf(JvmFlag.Property.IS_MOVED_FROM_INTERFACE_COMPANION) :
0;
}
private int convertPropertyAccessorFlags(KotlinPropertyAccessorFlags flags)
{
Set flagSet = new HashSet<>();
flagSet.addAll(convertCommonFlags(flags.common));
flagSet.addAll(convertVisibilityFlags(flags.visibility));
flagSet.addAll(convertModalityFlags(flags.modality));
if (! flags.isDefault) flagSet.add(Flag.PropertyAccessor.IS_NOT_DEFAULT);
if (flags.isInline) flagSet.add(Flag.PropertyAccessor.IS_INLINE);
if (flags.isExternal) flagSet.add(Flag.PropertyAccessor.IS_EXTERNAL);
return flagsOf(flagSet.toArray(new Flag[0]));
}
private int convertValueParameterFlags(KotlinValueParameterFlags flags)
{
Set flagSet = new HashSet<>();
flagSet.addAll(convertCommonFlags(flags.common));
if (flags.hasDefaultValue) flagSet.add(Flag.ValueParameter.DECLARES_DEFAULT_VALUE);
if (flags.isNoInline) flagSet.add(Flag.ValueParameter.IS_NOINLINE);
if (flags.isCrossInline) flagSet.add(Flag.ValueParameter.IS_CROSSINLINE);
return flagsOf(flagSet.toArray(new Flag[0]));
}
private int convertEffectExpressionFlags(KotlinEffectExpressionFlags flags)
{
Set flagSet = new HashSet<>();
if (flags.isNullCheckPredicate) flagSet.add(Flag.EffectExpression.IS_NULL_CHECK_PREDICATE);
if (flags.isNegated) flagSet.add(Flag.EffectExpression.IS_NEGATED);
return flagsOf(flagSet.toArray(new Flag[0]));
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy