|  | // Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file | 
|  | // for details. All rights reserved. Use of this source code is governed by a | 
|  | // BSD-style license that can be found in the LICENSE file. | 
|  |  | 
|  | package com.android.tools.r8.kotlin; | 
|  |  | 
|  | import com.android.tools.r8.graph.AppView; | 
|  | import com.android.tools.r8.graph.DexClass; | 
|  | import com.android.tools.r8.graph.DexType; | 
|  | import com.android.tools.r8.naming.NamingLens; | 
|  | import com.android.tools.r8.shaking.AppInfoWithLiveness; | 
|  | import com.android.tools.r8.utils.DescriptorUtils; | 
|  | import com.android.tools.r8.utils.StringUtils; | 
|  | import java.util.ArrayList; | 
|  | import java.util.List; | 
|  | import java.util.ListIterator; | 
|  | import kotlinx.metadata.jvm.KotlinClassHeader; | 
|  | import kotlinx.metadata.jvm.KotlinClassMetadata; | 
|  |  | 
|  | public final class KotlinClassFacade extends KotlinInfo<KotlinClassMetadata.MultiFileClassFacade> { | 
|  |  | 
|  | // TODO(b/151194869): is it better to maintain List<DexType>? | 
|  | List<String> partClassNames; | 
|  |  | 
|  | static KotlinClassFacade fromKotlinClassMetadata( | 
|  | KotlinClassMetadata kotlinClassMetadata, DexClass clazz) { | 
|  | assert kotlinClassMetadata instanceof KotlinClassMetadata.MultiFileClassFacade; | 
|  | KotlinClassMetadata.MultiFileClassFacade multiFileClassFacade = | 
|  | (KotlinClassMetadata.MultiFileClassFacade) kotlinClassMetadata; | 
|  | return new KotlinClassFacade(multiFileClassFacade, clazz); | 
|  | } | 
|  |  | 
|  | private KotlinClassFacade(KotlinClassMetadata.MultiFileClassFacade metadata, DexClass clazz) { | 
|  | super(metadata, clazz); | 
|  | } | 
|  |  | 
|  | @Override | 
|  | void processMetadata(KotlinClassMetadata.MultiFileClassFacade metadata) { | 
|  | // Part Class names are stored in `d1`, which is immutable. Make a copy instead. | 
|  | partClassNames = new ArrayList<>(metadata.getPartClassNames()); | 
|  | // No API to explore metadata details, hence nothing further to do. | 
|  | } | 
|  |  | 
|  | @Override | 
|  | void rewrite(AppView<AppInfoWithLiveness> appView, NamingLens lens) { | 
|  | ListIterator<String> partClassIterator = partClassNames.listIterator(); | 
|  | KotlinMetadataSynthesizer synthesizer = new KotlinMetadataSynthesizer(appView, lens, this); | 
|  | while (partClassIterator.hasNext()) { | 
|  | String partClassName = partClassIterator.next(); | 
|  | partClassIterator.remove(); | 
|  | DexType partClassType = appView.dexItemFactory().createType( | 
|  | DescriptorUtils.getDescriptorFromClassBinaryName(partClassName)); | 
|  | String renamedPartClassName = synthesizer.toRenamedBinaryName(partClassType); | 
|  | if (renamedPartClassName != null) { | 
|  | partClassIterator.add(renamedPartClassName); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | @Override | 
|  | KotlinClassHeader createHeader() { | 
|  | KotlinClassMetadata.MultiFileClassFacade.Writer writer = | 
|  | new KotlinClassMetadata.MultiFileClassFacade.Writer(); | 
|  | return writer.write(partClassNames).getHeader(); | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public Kind getKind() { | 
|  | return Kind.Facade; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public boolean isClassFacade() { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public KotlinClassFacade asClassFacade() { | 
|  | return this; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public String toString(String indent) { | 
|  | return indent + "MetaData.MultiFileClassFacade(" + StringUtils.join(partClassNames, ", ") + ")"; | 
|  | } | 
|  | } |