Create descriptors directly in Android Extensions (compiler plugin)

This commit is contained in:
Yan Zhulanow
2015-11-06 18:34:58 +03:00
parent 3d8df88ab2
commit d88c2249b8
26 changed files with 757 additions and 660 deletions
@@ -2324,6 +2324,15 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
}
Collection<ExpressionCodegenExtension> codegenExtensions = ExpressionCodegenExtension.Companion.getInstances(state.getProject());
if (!codegenExtensions.isEmpty()) {
ExpressionCodegenExtension.Context context = new ExpressionCodegenExtension.Context(typeMapper, v);
for (ExpressionCodegenExtension extension : codegenExtensions) {
StackValue stackValue = extension.applyFunction(receiver, resolvedCall, context);
if (stackValue != null) return stackValue;
}
}
Callable callable = resolveToCallable(fd, superCall, resolvedCall);
return callable.invokeMethodWithArguments(resolvedCall, receiver, this);
@@ -2385,15 +2394,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
if (!(resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor)) { // otherwise already
receiver = StackValue.receiver(resolvedCall, receiver, this, callableMethod);
Collection<ExpressionCodegenExtension> codegenExtensions = ExpressionCodegenExtension.Companion.getInstances(state.getProject());
if (!codegenExtensions.isEmpty()) {
ExpressionCodegenExtension.Context context = new ExpressionCodegenExtension.Context(typeMapper, v);
for (ExpressionCodegenExtension extension : codegenExtensions) {
if (extension.applyFunction(receiver, resolvedCall, context)) return;
}
}
receiver.put(receiver.type, v);
}
@@ -25,10 +25,10 @@ import org.jetbrains.kotlin.codegen.ClassBuilder
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.resolve.*
public interface ExpressionCodegenExtension {
companion object : ProjectExtensionDescriptor<ExpressionCodegenExtension>("org.jetbrains.kotlin.expressionCodegenExtension", javaClass<ExpressionCodegenExtension>())
companion object : ProjectExtensionDescriptor<ExpressionCodegenExtension>(
"org.jetbrains.kotlin.expressionCodegenExtension", ExpressionCodegenExtension::class.java)
public class Context(
public val typeMapper: JetTypeMapper,
@@ -42,10 +42,10 @@ public interface ExpressionCodegenExtension {
public fun applyProperty(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: Context): StackValue? = null
/**
* Used for generating custom byte code for the function call. This function has non-lazy semantics.
* Returns true if the stack was modified.
* Used for generating custom byte code for the function call. This function has lazy semantics.
* Returns new stack value.
*/
public fun applyFunction(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: Context): Boolean = false
public fun applyFunction(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: Context): StackValue? = null
public fun generateClassSyntheticParts(
classBuilder: ClassBuilder,
@@ -83,6 +83,7 @@ import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisCompletedHandlerExtension
import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtension
import org.jetbrains.kotlin.resolve.lazy.declarations.CliDeclarationProviderFactoryService
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService
import org.jetbrains.kotlin.utils.PathUtil
@@ -139,6 +140,7 @@ public class KotlinCoreEnvironment private constructor(
ExpressionCodegenExtension.registerExtensionPoint(project)
ClassBuilderInterceptorExtension.registerExtensionPoint(project)
AnalysisCompletedHandlerExtension.registerExtensionPoint(project)
PackageFragmentProviderExtension.registerExtensionPoint(project)
StorageComponentContainerContributor.registerExtensionPoint(project)
for (registrar in configuration.getList(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS)) {
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.load.java.lazy.ModuleClassResolverImpl
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer
import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtension
import org.jetbrains.kotlin.resolve.TargetEnvironment
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
@@ -77,9 +78,10 @@ public object JvmAnalyzerFacade : AnalyzerFacade<JvmPlatformParameters>() {
resolverForModule.componentProvider.get<JavaDescriptorResolver>()
}
val trace = CodeAnalyzerInitializer.getInstance(project).createTrace()
val container = createContainerForLazyResolveWithJava(
moduleContext,
CodeAnalyzerInitializer.getInstance(project).createTrace(),
trace,
declarationProviderFactory,
moduleContentScope,
moduleClassResolver,
@@ -89,7 +91,14 @@ public object JvmAnalyzerFacade : AnalyzerFacade<JvmPlatformParameters>() {
val resolveSession = container.get<ResolveSession>()
val javaDescriptorResolver = container.get<JavaDescriptorResolver>()
val providersForModule = listOf(resolveSession.getPackageFragmentProvider(), javaDescriptorResolver.packageFragmentProvider)
val providersForModule = arrayListOf(
resolveSession.packageFragmentProvider,
javaDescriptorResolver.packageFragmentProvider)
providersForModule += PackageFragmentProviderExtension.getInstances(project)
.map { it.getPackageFragmentProvider(project, moduleDescriptor, moduleContext.storageManager, trace, moduleInfo) }
.filterNotNull()
return ResolverForModule(CompositePackageFragmentProvider(providersForModule), container)
}
@@ -43,6 +43,7 @@ import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.BindingTrace;
import org.jetbrains.kotlin.resolve.TopDownAnalysisMode;
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisCompletedHandlerExtension;
import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtension;
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform;
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory;
@@ -135,6 +136,12 @@ public enum TopDownAnalyzerFacadeForJVM {
}
additionalProviders.add(container.getJavaDescriptorResolver().getPackageFragmentProvider());
for (PackageFragmentProviderExtension extension : PackageFragmentProviderExtension.Companion.getInstances(project)) {
PackageFragmentProvider provider = extension.getPackageFragmentProvider(
project, moduleContext.getModule(), moduleContext.getStorageManager(), trace, null);
if (provider != null) additionalProviders.add(provider);
}
container.getLazyTopDownAnalyzerForTopLevel().analyzeFiles(topDownAnalysisMode, allFiles, additionalProviders);
BindingContext bindingContext = trace.getBindingContext();
@@ -0,0 +1,39 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* 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 org.jetbrains.kotlin.resolve.jvm.extensions
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.storage.StorageManager
public interface PackageFragmentProviderExtension {
companion object : ProjectExtensionDescriptor<PackageFragmentProviderExtension>(
"org.jetbrains.kotlin.packageFragmentProviderExtension",
PackageFragmentProviderExtension::class.java
)
public fun getPackageFragmentProvider(
project: Project,
module: ModuleDescriptor,
storageManager: StorageManager,
trace: BindingTrace,
moduleInfo: ModuleInfo?
): PackageFragmentProvider?
}