Skip to content

Commit 6ecf2e8

Browse files
committed
Parcelable: Support Android Extensions experimental flag
1 parent 75d226a commit 6ecf2e8

File tree

6 files changed

+91
-8
lines changed

6 files changed

+91
-8
lines changed

idea/src/META-INF/android.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@
8585
<platformGradleDetector implementation="org.jetbrains.kotlin.android.configure.PlatformAndroidGradleDetector"/>
8686
<completionInformationProvider implementation="org.jetbrains.kotlin.AndroidExtensionsCompletionInformationProvider" />
8787

88-
<expressionCodegenExtension implementation="org.jetbrains.kotlin.android.parcel.ParcelableCodegenExtension"/>
89-
<syntheticResolveExtension implementation="org.jetbrains.kotlin.android.parcel.ParcelableResolveExtension"/>
88+
<expressionCodegenExtension implementation="org.jetbrains.kotlin.android.parcel.IDEParcelableCodegenExtension"/>
89+
<syntheticResolveExtension implementation="org.jetbrains.kotlin.android.parcel.IDEParcelableResolveExtension"/>
9090
<classBuilderFactoryInterceptorExtension implementation="org.jetbrains.kotlin.android.synthetic.codegen.ParcelableClinitClassBuilderInterceptorExtension"/>
9191

9292
<androidDexer implementation="org.jetbrains.kotlin.android.debugger.AndroidDexerImpl"/>

plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/parcel/ParcelableCodegenExtension.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
3939
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
4040
import org.jetbrains.kotlin.incremental.components.NoLookupLocation.*
4141
import org.jetbrains.kotlin.name.FqName
42+
import org.jetbrains.kotlin.psi.KtClassOrObject
43+
import org.jetbrains.kotlin.psi.KtElement
4244
import org.jetbrains.kotlin.resolve.DescriptorFactory
4345
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
4446
import org.jetbrains.kotlin.resolve.descriptorUtil.module
@@ -50,17 +52,23 @@ import org.jetbrains.org.objectweb.asm.Opcodes.*
5052
import org.jetbrains.org.objectweb.asm.Type
5153
import java.io.FileDescriptor
5254

53-
class ParcelableCodegenExtension : ExpressionCodegenExtension {
55+
open class ParcelableCodegenExtension : ExpressionCodegenExtension {
5456
private companion object {
5557
private val FILE_DESCRIPTOR_FQNAME = FqName(FileDescriptor::class.java.canonicalName)
5658
private val PARCELER_FQNAME = FqName(Parceler::class.java.canonicalName)
5759

5860
fun KotlinType.isParceler() = constructor.declarationDescriptor?.fqNameSafe == PARCELER_FQNAME
5961
}
6062

63+
protected open fun isExperimental(element: KtElement) = true
64+
6165
override fun generateClassSyntheticParts(codegen: ImplementationBodyCodegen) {
6266
val parcelableClass = codegen.descriptor
6367
if (!parcelableClass.isMagicParcelable) return
68+
69+
val sourceElement = (codegen.myClass as? KtClassOrObject) ?: return
70+
if (!isExperimental(sourceElement)) return
71+
6472
assert(parcelableClass.kind == ClassKind.CLASS || parcelableClass.kind == ClassKind.OBJECT)
6573

6674
val propertiesToSerialize = getPropertiesToSerialize(codegen, parcelableClass)

plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/parcel/ParcelableResolveExtension.kt

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,16 @@ import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
2626
import org.jetbrains.kotlin.name.ClassId
2727
import org.jetbrains.kotlin.name.FqName
2828
import org.jetbrains.kotlin.name.Name
29+
import org.jetbrains.kotlin.psi.KtElement
2930
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
3031
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
3132
import org.jetbrains.kotlin.resolve.descriptorUtil.module
3233
import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension
34+
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
3335
import org.jetbrains.kotlin.types.KotlinType
3436
import org.jetbrains.kotlin.types.SimpleType
3537

36-
class ParcelableResolveExtension : SyntheticResolveExtension {
38+
open class ParcelableResolveExtension : SyntheticResolveExtension {
3739
companion object {
3840
fun resolveParcelClassType(module: ModuleDescriptor): SimpleType {
3941
return module.findClassAcrossModuleDependencies(
@@ -72,6 +74,8 @@ class ParcelableResolveExtension : SyntheticResolveExtension {
7274
}
7375
}
7476

77+
protected open fun isExperimental(element: KtElement) = true
78+
7579
override fun getSyntheticCompanionObjectNameIfNeeded(thisDescriptor: ClassDescriptor) = null
7680

7781
override fun generateSyntheticMethods(
@@ -80,9 +84,22 @@ class ParcelableResolveExtension : SyntheticResolveExtension {
8084
fromSupertypes: List<SimpleFunctionDescriptor>,
8185
result: MutableCollection<SimpleFunctionDescriptor>
8286
) {
83-
if (name.asString() == DESCRIBE_CONTENTS.methodName && clazz.isMagicParcelable && result.none { it.isDescribeContents() }) {
87+
fun isExperimental(): Boolean {
88+
val sourceElement = (clazz.source as? PsiSourceElement)?.psi as? KtElement ?: return false
89+
return isExperimental(sourceElement)
90+
}
91+
92+
if (name.asString() == DESCRIBE_CONTENTS.methodName
93+
&& clazz.isMagicParcelable
94+
&& isExperimental()
95+
&& result.none { it.isDescribeContents() }
96+
) {
8497
result += createMethod(clazz, DESCRIBE_CONTENTS, clazz.builtIns.intType)
85-
} else if (name.asString() == WRITE_TO_PARCEL.methodName && clazz.isMagicParcelable && result.none { it.isWriteToParcel() }) {
98+
} else if (name.asString() == WRITE_TO_PARCEL.methodName
99+
&& clazz.isMagicParcelable
100+
&& isExperimental()
101+
&& result.none { it.isWriteToParcel() }
102+
) {
86103
val builtIns = clazz.builtIns
87104
val parcelClassType = resolveParcelClassType(clazz.module)
88105
result += createMethod(clazz, WRITE_TO_PARCEL, builtIns.unitType, "parcel" to parcelClassType, "flags" to builtIns.intType)

plugins/android-extensions/android-extensions-compiler/src/org/jetbrains/kotlin/android/synthetic/AndroidComponentRegistrar.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,14 @@ class AndroidComponentRegistrar : ComponentRegistrar {
9090
}
9191

9292
override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
93-
registerParcelExtensions(project)
94-
9593
val applicationPackage = configuration.get(AndroidConfigurationKeys.PACKAGE)
9694
val variants = configuration.get(AndroidConfigurationKeys.VARIANT)?.mapNotNull { parseVariant(it) } ?: emptyList()
9795
val isExperimental = configuration.get(AndroidConfigurationKeys.EXPERIMENTAL) == "true"
9896

97+
if (isExperimental) {
98+
registerParcelExtensions(project)
99+
}
100+
99101
if (variants.isNotEmpty() && !applicationPackage.isNullOrBlank()) {
100102
val layoutXmlFileManager = CliAndroidLayoutXmlFileManager(project, applicationPackage!!, variants)
101103
project.registerService(AndroidLayoutXmlFileManager::class.java, layoutXmlFileManager)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2010-2017 JetBrains s.r.o.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.jetbrains.kotlin.android.parcel
18+
19+
import org.jetbrains.kotlin.android.synthetic.idea.androidExtensionsIsExperimental
20+
import org.jetbrains.kotlin.idea.caches.resolve.getModuleInfo
21+
import org.jetbrains.kotlin.psi.KtElement
22+
23+
class IDEParcelableCodegenExtension : ParcelableCodegenExtension() {
24+
override fun isExperimental(element: KtElement): Boolean {
25+
val moduleInfo = element.getModuleInfo()
26+
return moduleInfo.androidExtensionsIsExperimental
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2010-2017 JetBrains s.r.o.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.jetbrains.kotlin.android.parcel
18+
19+
import org.jetbrains.kotlin.android.synthetic.idea.androidExtensionsIsExperimental
20+
import org.jetbrains.kotlin.idea.caches.resolve.getModuleInfo
21+
import org.jetbrains.kotlin.psi.KtElement
22+
23+
class IDEParcelableResolveExtension : ParcelableResolveExtension() {
24+
override fun isExperimental(element: KtElement): Boolean {
25+
val moduleInfo = element.getModuleInfo()
26+
return moduleInfo.androidExtensionsIsExperimental
27+
}
28+
}

0 commit comments

Comments
 (0)