Initial support of descriptor loading at runtime

This commit is contained in:
Alexander Udalov
2014-08-21 14:23:01 +04:00
parent be954f2c27
commit 356f54b5df
34 changed files with 4142 additions and 49 deletions
@@ -23,8 +23,23 @@ import org.jetbrains.kotlin.load.java.structure.JavaAnnotationOwner;
import org.jetbrains.kotlin.name.FqName;
import java.util.Collection;
import java.util.Collections;
public interface ExternalAnnotationResolver {
ExternalAnnotationResolver EMPTY = new ExternalAnnotationResolver() {
@Nullable
@Override
public JavaAnnotation findExternalAnnotation(@NotNull JavaAnnotationOwner owner, @NotNull FqName fqName) {
return null;
}
@NotNull
@Override
public Collection<JavaAnnotation> findExternalAnnotations(@NotNull JavaAnnotationOwner owner) {
return Collections.emptyList();
}
};
@Nullable
JavaAnnotation findExternalAnnotation(@NotNull JavaAnnotationOwner owner, @NotNull FqName fqName);
@@ -28,6 +28,53 @@ import java.util.Collections;
import java.util.List;
public interface ExternalSignatureResolver {
ExternalSignatureResolver DO_NOTHING = new ExternalSignatureResolver() {
@NotNull
@Override
public PropagatedMethodSignature resolvePropagatedSignature(
@NotNull JavaMethod method,
@NotNull ClassDescriptor owner,
@NotNull JetType returnType,
@Nullable JetType receiverType,
@NotNull List<ValueParameterDescriptor> valueParameters,
@NotNull List<TypeParameterDescriptor> typeParameters
) {
return new PropagatedMethodSignature(
returnType, receiverType, valueParameters, typeParameters, Collections.<String>emptyList(), false,
Collections.<FunctionDescriptor>emptyList()
);
}
@NotNull
@Override
public AlternativeMethodSignature resolveAlternativeMethodSignature(
@NotNull JavaMember methodOrConstructor,
boolean hasSuperMethods,
@Nullable JetType returnType,
@Nullable JetType receiverType,
@NotNull List<ValueParameterDescriptor> valueParameters,
@NotNull List<TypeParameterDescriptor> typeParameters,
boolean hasStableParameterNames
) {
return new AlternativeMethodSignature(
returnType, receiverType, valueParameters, typeParameters, Collections.<String>emptyList(), hasStableParameterNames
);
}
@NotNull
@Override
public AlternativeFieldSignature resolveAlternativeFieldSignature(
@NotNull JavaField field, @NotNull JetType returnType, boolean isVar
) {
return new AlternativeFieldSignature(returnType, null);
}
@Override
public void reportSignatureErrors(@NotNull CallableMemberDescriptor descriptor, @NotNull List<String> signatureErrors) {
throw new UnsupportedOperationException("Should not be called");
}
};
abstract class MemberSignature {
private final List<String> signatureErrors;
@@ -29,6 +29,30 @@ import org.jetbrains.kotlin.load.java.structure.JavaMethod;
import org.jetbrains.kotlin.name.FqName;
public interface JavaResolverCache {
JavaResolverCache EMPTY = new JavaResolverCache() {
@Nullable
@Override
public ClassDescriptor getClassResolvedFromSource(@NotNull FqName fqName) {
return null;
}
@Override
public void recordMethod(@NotNull JavaMethod method, @NotNull SimpleFunctionDescriptor descriptor) {
}
@Override
public void recordConstructor(@NotNull JavaElement element, @NotNull ConstructorDescriptor descriptor) {
}
@Override
public void recordField(@NotNull JavaField field, @NotNull PropertyDescriptor descriptor) {
}
@Override
public void recordClass(@NotNull JavaClass javaClass, @NotNull ClassDescriptor descriptor) {
}
};
@Nullable
ClassDescriptor getClassResolvedFromSource(@NotNull FqName fqName);
@@ -24,6 +24,18 @@ import org.jetbrains.kotlin.load.java.structure.JavaMethod;
import java.util.List;
public interface MethodSignatureChecker {
MethodSignatureChecker DO_NOTHING = new MethodSignatureChecker() {
@Override
public void checkSignature(
@NotNull JavaMethod method,
boolean reportSignatureErrors,
@NotNull SimpleFunctionDescriptor descriptor,
@NotNull List<String> signatureErrors,
@NotNull List<FunctionDescriptor> superFunctions
) {
}
};
void checkSignature(
@NotNull JavaMethod method,
boolean reportSignatureErrors,
@@ -16,15 +16,23 @@
package org.jetbrains.kotlin.load.java.components
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.types.JetType
import org.jetbrains.kotlin.load.java.structure.JavaMethod
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor
import org.jetbrains.kotlin.load.java.structure.JavaMethod
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.types.JetType
public trait SamConversionResolver {
public default object EMPTY : SamConversionResolver {
override fun <D : FunctionDescriptor> resolveSamAdapter(original: D) = null
override fun resolveSamConstructor(name: Name, scope: JetScope) = null
override fun resolveFunctionTypeIfSamInterface(
classDescriptor: JavaClassDescriptor, resolveMethod: (JavaMethod) -> FunctionDescriptor
): JetType? = null
}
public fun resolveSamConstructor(name: Name, scope: JetScope): SamConstructorDescriptor?
public fun <D : FunctionDescriptor> resolveSamAdapter(original: D): D?
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.load.java.structure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.ReadOnly;
import java.util.Collection;
import java.util.List;
@@ -30,6 +31,7 @@ public interface JavaClassifierType extends JavaType {
JavaTypeSubstitutor getSubstitutor();
@NotNull
@ReadOnly
Collection<JavaClassifierType> getSupertypes();
@NotNull
@@ -38,5 +40,6 @@ public interface JavaClassifierType extends JavaType {
boolean isRaw();
@NotNull
@ReadOnly
List<JavaType> getTypeArguments();
}
@@ -22,6 +22,19 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
public interface JavaPropertyInitializerEvaluator {
JavaPropertyInitializerEvaluator DO_NOTHING = new JavaPropertyInitializerEvaluator() {
@Nullable
@Override
public CompileTimeConstant<?> getInitializerConstant(@NotNull JavaField field, @NotNull PropertyDescriptor descriptor) {
return null;
}
@Override
public boolean isNotNullCompileTimeConstant(@NotNull JavaField field) {
return false;
}
};
@Nullable
CompileTimeConstant<?> getInitializerConstant(@NotNull JavaField field, @NotNull PropertyDescriptor descriptor);
@@ -18,11 +18,13 @@ package org.jetbrains.kotlin.load.java.structure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.ReadOnly;
import java.util.Collection;
public interface JavaTypeParameter extends JavaClassifier {
@NotNull
@ReadOnly
Collection<JavaClassifierType> getUpperBounds();
@Nullable
@@ -17,10 +17,12 @@
package org.jetbrains.kotlin.load.java.structure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.ReadOnly;
import java.util.List;
public interface JavaTypeParameterListOwner extends JavaElement {
@NotNull
@ReadOnly
List<JavaTypeParameter> getTypeParameters();
}
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="descriptor.loader.java" exported="" />
<orderEntry type="module" module-name="descriptors" exported="" />
<orderEntry type="module" module-name="serialization" exported="" />
<orderEntry type="module" module-name="serialization.jvm" exported="" />
<orderEntry type="module" module-name="util.runtime" />
</component>
</module>
@@ -0,0 +1,112 @@
/*
* 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.di;
import org.jetbrains.kotlin.descriptors.ModuleDescriptor;
import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver;
import org.jetbrains.kotlin.load.java.components.ExternalSignatureResolver;
import org.jetbrains.kotlin.load.java.components.MethodSignatureChecker;
import org.jetbrains.kotlin.load.java.components.JavaResolverCache;
import org.jetbrains.kotlin.load.java.components.ExternalAnnotationResolver;
import org.jetbrains.kotlin.load.java.structure.JavaPropertyInitializerEvaluator;
import org.jetbrains.kotlin.load.java.components.SamConversionResolver;
import org.jetbrains.kotlin.load.java.components.RuntimeErrorReporter;
import org.jetbrains.kotlin.load.java.components.RuntimeSourceElementFactory;
import org.jetbrains.kotlin.load.java.lazy.SingleModuleClassResolver;
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
import org.jetbrains.kotlin.load.java.reflect.ReflectJavaClassFinder;
import org.jetbrains.kotlin.load.kotlin.reflect.ReflectKotlinClassFinder;
import org.jetbrains.kotlin.load.java.lazy.LazyJavaPackageFragmentProvider;
import org.jetbrains.kotlin.load.java.lazy.GlobalJavaResolverContext;
import org.jetbrains.kotlin.load.kotlin.DeserializedDescriptorResolver;
import org.jetbrains.kotlin.load.kotlin.DeserializationComponentsForJava;
import org.jetbrains.kotlin.load.kotlin.JavaClassDataFinder;
import org.jetbrains.kotlin.load.kotlin.BinaryClassAnnotationAndConstantLoaderImpl;
import org.jetbrains.annotations.NotNull;
import javax.annotation.PreDestroy;
/* This file is generated by org.jetbrains.kotlin.generators.injectors.InjectorsPackage. DO NOT EDIT! */
@SuppressWarnings("all")
public class InjectorForRuntimeDescriptorLoader {
private final ClassLoader classLoader;
private final ModuleDescriptor moduleDescriptor;
private final JavaDescriptorResolver javaDescriptorResolver;
private final ExternalSignatureResolver externalSignatureResolver;
private final MethodSignatureChecker methodSignatureChecker;
private final JavaResolverCache javaResolverCache;
private final ExternalAnnotationResolver externalAnnotationResolver;
private final JavaPropertyInitializerEvaluator javaPropertyInitializerEvaluator;
private final SamConversionResolver samConversionResolver;
private final RuntimeErrorReporter runtimeErrorReporter;
private final RuntimeSourceElementFactory runtimeSourceElementFactory;
private final SingleModuleClassResolver singleModuleClassResolver;
private final LockBasedStorageManager lockBasedStorageManager;
private final ReflectJavaClassFinder reflectJavaClassFinder;
private final ReflectKotlinClassFinder reflectKotlinClassFinder;
private final LazyJavaPackageFragmentProvider lazyJavaPackageFragmentProvider;
private final GlobalJavaResolverContext globalJavaResolverContext;
private final DeserializedDescriptorResolver deserializedDescriptorResolver;
private final DeserializationComponentsForJava deserializationComponentsForJava;
private final JavaClassDataFinder javaClassDataFinder;
private final BinaryClassAnnotationAndConstantLoaderImpl binaryClassAnnotationAndConstantLoader;
public InjectorForRuntimeDescriptorLoader(
@NotNull ClassLoader classLoader,
@NotNull ModuleDescriptor moduleDescriptor
) {
this.classLoader = classLoader;
this.moduleDescriptor = moduleDescriptor;
this.lockBasedStorageManager = new LockBasedStorageManager();
this.reflectJavaClassFinder = new ReflectJavaClassFinder(classLoader);
this.reflectKotlinClassFinder = new ReflectKotlinClassFinder(classLoader);
this.runtimeErrorReporter = RuntimeErrorReporter.INSTANCE$;
this.deserializedDescriptorResolver = new DeserializedDescriptorResolver(runtimeErrorReporter);
this.externalAnnotationResolver = ExternalAnnotationResolver.EMPTY;
this.externalSignatureResolver = ExternalSignatureResolver.DO_NOTHING;
this.methodSignatureChecker = MethodSignatureChecker.DO_NOTHING;
this.javaResolverCache = JavaResolverCache.EMPTY;
this.javaPropertyInitializerEvaluator = JavaPropertyInitializerEvaluator.DO_NOTHING;
this.samConversionResolver = SamConversionResolver.EMPTY;
this.runtimeSourceElementFactory = RuntimeSourceElementFactory.INSTANCE$;
this.singleModuleClassResolver = new SingleModuleClassResolver();
this.globalJavaResolverContext = new GlobalJavaResolverContext(lockBasedStorageManager, reflectJavaClassFinder, reflectKotlinClassFinder, deserializedDescriptorResolver, externalAnnotationResolver, externalSignatureResolver, runtimeErrorReporter, methodSignatureChecker, javaResolverCache, javaPropertyInitializerEvaluator, samConversionResolver, runtimeSourceElementFactory, singleModuleClassResolver);
this.lazyJavaPackageFragmentProvider = new LazyJavaPackageFragmentProvider(globalJavaResolverContext, getModuleDescriptor());
this.javaDescriptorResolver = new JavaDescriptorResolver(lazyJavaPackageFragmentProvider, getModuleDescriptor());
this.javaClassDataFinder = new JavaClassDataFinder(reflectKotlinClassFinder, deserializedDescriptorResolver);
this.binaryClassAnnotationAndConstantLoader = new BinaryClassAnnotationAndConstantLoaderImpl(getModuleDescriptor(), lockBasedStorageManager, reflectKotlinClassFinder, runtimeErrorReporter);
this.deserializationComponentsForJava = new DeserializationComponentsForJava(lockBasedStorageManager, getModuleDescriptor(), javaClassDataFinder, binaryClassAnnotationAndConstantLoader, lazyJavaPackageFragmentProvider);
singleModuleClassResolver.setResolver(javaDescriptorResolver);
deserializedDescriptorResolver.setComponents(deserializationComponentsForJava);
}
@PreDestroy
public void destroy() {
}
public ModuleDescriptor getModuleDescriptor() {
return this.moduleDescriptor;
}
public JavaDescriptorResolver getJavaDescriptorResolver() {
return this.javaDescriptorResolver;
}
}
@@ -0,0 +1,43 @@
/*
* 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.load.java.components
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
public object RuntimeErrorReporter : ErrorReporter {
// TODO: specialized exceptions
override fun reportIncompleteHierarchy(descriptor: ClassDescriptor, unresolvedSuperClasses: MutableList<String>) {
throw IllegalStateException("Incomplete hierarchy for class ${descriptor.getName()}, unresolved classes $unresolvedSuperClasses")
}
override fun reportIncompatibleAbiVersion(kotlinClass: KotlinJvmBinaryClass, actualVersion: Int) {
throw IllegalStateException("Incompatible ABI version of ${kotlinClass.getClassId()}: $actualVersion " +
"(expected version is ${JvmAbi.VERSION})")
}
override fun reportCannotInferVisibility(descriptor: CallableMemberDescriptor) {
// TODO: use DescriptorRenderer
throw IllegalStateException("Cannot infer visibility for class ${descriptor.getName()}")
}
override fun reportLoadingError(message: String, exception: Exception?) {
throw IllegalStateException(message, exception)
}
}
@@ -0,0 +1,30 @@
/*
* 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.load.java.components
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
import org.jetbrains.kotlin.load.java.sources.JavaSourceElementFactory
import org.jetbrains.kotlin.load.java.structure.JavaElement
import org.jetbrains.kotlin.load.java.structure.reflect.ReflectJavaElement
// NOTE: currently source elements for descriptors at runtime are stored primarily for easier debugging experience.
// Consider not storing them if this proves to have significant performance implications
public object RuntimeSourceElementFactory : JavaSourceElementFactory {
private class RuntimeSourceElement(override val javaElement: ReflectJavaElement) : JavaSourceElement
override fun source(javaElement: JavaElement) = RuntimeSourceElement(javaElement as ReflectJavaElement)
}
@@ -0,0 +1,45 @@
/*
* 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.load.java.reflect
import org.jetbrains.kotlin.load.java.JavaClassFinder
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.JavaPackage
import org.jetbrains.kotlin.load.java.structure.reflect.ReflectJavaClass
import org.jetbrains.kotlin.load.java.structure.reflect.ReflectJavaPackage
import org.jetbrains.kotlin.name.ClassId
public class ReflectJavaClassFinder(private val classLoader: ClassLoader) : JavaClassFinder {
override fun findClass(classId: ClassId): JavaClass? {
val klass = classLoader.tryLoadClass(classId.asSingleFqName().asString())
return if (klass != null) ReflectJavaClass(klass) else null
}
override fun findPackage(fqName: FqName): JavaPackage? {
// We don't know which packages our class loader has and has not, so we behave as if it contains any package in the world
return ReflectJavaPackage(fqName)
}
}
fun ClassLoader.tryLoadClass(fqName: String) =
try {
loadClass(fqName)
}
catch (e: ClassNotFoundException) {
null
}
@@ -0,0 +1,98 @@
/*
* 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.load.java.structure.reflect
import java.lang.reflect.Modifier
import org.jetbrains.kotlin.load.java.structure.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.emptyOrSingletonList
public class ReflectJavaClass(private val klass: Class<*>) : ReflectJavaElement(), JavaClass {
override fun getInnerClasses(): Collection<JavaClass> {
// TODO
return listOf()
}
override fun getFqName(): FqName? {
// TODO: can there be primitive types, arrays?
return getOuterClass()?.getFqName()?.child(Name.identifier(klass.getSimpleName())) ?: FqName(klass.getName())
}
override fun getOuterClass(): JavaClass? {
val container = klass.getDeclaringClass()
return if (container != null) ReflectJavaClass(container) else null
}
override fun getSupertypes(): Collection<JavaClassifierType> {
// TODO: also call getSuperclass() / getInterfaces() for classes without generic signature
val supertypes = emptyOrSingletonList(klass.getGenericSuperclass()) + klass.getGenericInterfaces()
return supertypes.map { supertype -> ReflectJavaClassifierType(supertype) }
}
override fun getMethods(): Collection<JavaMethod> {
// TODO
return listOf()
}
override fun getFields(): Collection<JavaField> {
// TODO
return listOf()
}
override fun getConstructors(): Collection<JavaConstructor> {
// TODO
return listOf()
}
override fun getDefaultType() = ReflectJavaClassifierType(klass)
// TODO: drop OriginKind?
override fun getOriginKind() = JavaClass.OriginKind.COMPILED
override fun createImmediateType(substitutor: JavaTypeSubstitutor): JavaType {
// TODO
throw UnsupportedOperationException()
}
override fun getName(): Name {
// TODO: can there be primitive types, arrays?
return Name.identifier(klass.getSimpleName())
}
override fun getAnnotations(): Collection<JavaAnnotation> {
// TODO
return listOf()
}
override fun findAnnotation(fqName: FqName): JavaAnnotation? {
// TODO
return null
}
override fun getTypeParameters() = klass.getTypeParameters().map { ReflectJavaTypeParameter(it!!) }
override fun isInterface() = klass.isInterface()
override fun isAnnotationType() = klass.isAnnotation()
override fun isEnum() = klass.isEnum()
override fun isAbstract() = Modifier.isAbstract(klass.getModifiers())
override fun isStatic() = Modifier.isStatic(klass.getModifiers())
override fun isFinal() = Modifier.isFinal(klass.getModifiers())
override fun getVisibility() = calculateVisibility(klass.getModifiers())
}
@@ -0,0 +1,50 @@
/*
* 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.load.java.structure.reflect
import org.jetbrains.kotlin.load.java.structure.JavaClassifier
import org.jetbrains.kotlin.load.java.structure.JavaClassifierType
import org.jetbrains.kotlin.load.java.structure.JavaType
import org.jetbrains.kotlin.load.java.structure.JavaTypeSubstitutor
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
import java.lang.reflect.TypeVariable
public class ReflectJavaClassifierType(val classifierType: Type) : ReflectJavaType(), JavaClassifierType {
override fun getClassifier(): JavaClassifier? {
return when (classifierType) {
is Class<*> -> ReflectJavaClass(classifierType)
is TypeVariable<*> -> ReflectJavaTypeParameter(classifierType)
// TODO
is ParameterizedType -> ReflectJavaClass(classifierType.getRawType() as Class<*>)
else -> throw UnsupportedOperationException("Unsupported type (${classifierType.javaClass}): $classifierType")
}
}
override fun getSubstitutor(): JavaTypeSubstitutor = throw UnsupportedOperationException()
override fun getSupertypes(): Collection<JavaClassifierType> = throw UnsupportedOperationException()
override fun getPresentableText(): String = classifierType.toString()
override fun isRaw(): Boolean = with(classifierType) { this is Class<*> && getTypeParameters().isNotEmpty() }
override fun getTypeArguments(): List<JavaType> {
// TODO
return listOf()
}
}
@@ -0,0 +1,21 @@
/*
* 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.load.java.structure.reflect
import org.jetbrains.kotlin.load.java.structure.JavaElement
public abstract class ReflectJavaElement : JavaElement
@@ -0,0 +1,36 @@
/*
* 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.load.java.structure.reflect
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.load.java.structure.JavaPackage
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.name.Name
public class ReflectJavaPackage(private val fqName: FqName) : ReflectJavaElement(), JavaPackage {
override fun getFqName() = fqName
override fun getClasses(nameFilter: (Name) -> Boolean): Collection<JavaClass> {
// A package at runtime can't know what classes it has and has not
return listOf()
}
override fun getSubPackages(): Collection<JavaPackage> {
// A package at runtime can't know what sub packages it has and has not
return listOf()
}
}
@@ -0,0 +1,24 @@
/*
* 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.load.java.structure.reflect
import org.jetbrains.kotlin.load.java.structure.JavaType
import org.jetbrains.kotlin.load.java.structure.JavaArrayType
public abstract class ReflectJavaType : JavaType {
override fun createArrayType(): JavaArrayType = throw UnsupportedOperationException()
}
@@ -0,0 +1,50 @@
/*
* 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.load.java.structure.reflect
import org.jetbrains.kotlin.load.java.structure.JavaType
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameterListOwner
import org.jetbrains.kotlin.name.Name
import java.lang.reflect.TypeVariable
public class ReflectJavaTypeParameter(
private val typeVariable: TypeVariable<*>
) : ReflectJavaElement(), JavaTypeParameter {
override fun getUpperBounds(): List<ReflectJavaClassifierType> {
val bounds = typeVariable.getBounds().map { bound -> ReflectJavaClassifierType(bound) }
if (bounds.singleOrNull()?.classifierType == javaClass<Any>()) return emptyList()
return bounds
}
override fun getOwner(): JavaTypeParameterListOwner? {
// TODO
throw UnsupportedOperationException()
}
override fun getType(): JavaType {
// TODO
throw UnsupportedOperationException()
}
override fun getTypeProvider() = ReflectJavaTypeProvider
override fun getName() = Name.identifier(typeVariable.getName())
override fun equals(other: Any?) = other is ReflectJavaTypeParameter && typeVariable == other.typeVariable
override fun hashCode() = typeVariable.hashCode()
}
@@ -0,0 +1,42 @@
/*
* 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.load.java.structure.reflect
import org.jetbrains.kotlin.load.java.structure.JavaTypeProvider
import org.jetbrains.kotlin.load.java.structure.JavaType
import org.jetbrains.kotlin.load.java.structure.JavaWildcardType
public object ReflectJavaTypeProvider : JavaTypeProvider {
override fun createJavaLangObjectType(): JavaType {
return ReflectJavaClassifierType(javaClass<Any>())
}
override fun createUpperBoundWildcard(bound: JavaType): JavaWildcardType {
// TODO
throw UnsupportedOperationException()
}
override fun createLowerBoundWildcard(bound: JavaType): JavaWildcardType {
// TODO
throw UnsupportedOperationException()
}
override fun createUnboundedWildcard(): JavaWildcardType {
// TODO
throw UnsupportedOperationException()
}
}
@@ -0,0 +1,38 @@
/*
* 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.load.java.structure.reflect
import java.lang.reflect.Modifier
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.load.java.JavaVisibilities
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.FqName
private fun calculateVisibility(modifiers: Int): Visibility {
return when {
Modifier.isPublic(modifiers) -> Visibilities.PUBLIC
Modifier.isPrivate(modifiers) -> Visibilities.PRIVATE
Modifier.isProtected(modifiers) ->
if (Modifier.isStatic(modifiers)) JavaVisibilities.PROTECTED_STATIC_VISIBILITY else JavaVisibilities.PROTECTED_AND_PACKAGE
else -> JavaVisibilities.PACKAGE_VISIBILITY
}
}
val Class<*>.classId: ClassId
get() = getDeclaringClass()?.classId?.createNestedClassId(Name.identifier(getSimpleName())) ?: ClassId.topLevel(FqName(getName()))
@@ -0,0 +1,55 @@
/*
* 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.load.kotlin.reflect
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.load.java.structure.reflect.classId
import org.jetbrains.kotlin.load.kotlin.header.ReadKotlinClassHeaderAnnotationVisitor
public class ReflectKotlinClass(private val klass: Class<*>) : KotlinJvmBinaryClass {
private val classHeader: KotlinClassHeader
{
val headerReader = ReadKotlinClassHeaderAnnotationVisitor()
loadClassAnnotations(headerReader)
val header = headerReader.createHeader()
if (header == null) {
// This exception must be caught in the caller
throw NotAKotlinClass()
}
classHeader = header
}
class NotAKotlinClass : RuntimeException()
override fun getClassId(): ClassId = klass.classId
override fun loadClassAnnotations(visitor: KotlinJvmBinaryClass.AnnotationVisitor) {
// TODO
visitor.visitEnd()
}
override fun visitMembers(visitor: KotlinJvmBinaryClass.MemberVisitor) {
// TODO
}
override fun getClassHeader() = classHeader
}
@@ -0,0 +1,46 @@
/*
* 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.load.kotlin.reflect
import org.jetbrains.kotlin.load.java.reflect.tryLoadClass
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
import org.jetbrains.kotlin.name.ClassId
public class ReflectKotlinClassFinder(private val classLoader: ClassLoader) : KotlinClassFinder {
private fun findKotlinClass(fqName: String): KotlinJvmBinaryClass? {
return classLoader.tryLoadClass(fqName)?.let { try {
ReflectKotlinClass(it)
}
catch (e: ReflectKotlinClass.NotAKotlinClass) {
null
} }
}
override fun findKotlinClass(classId: ClassId) = findKotlinClass(classId.toRuntimeFqName())
override fun findKotlinClass(javaClass: JavaClass): KotlinJvmBinaryClass? {
// TODO: go through javaClass's class loader
return findKotlinClass(javaClass.getFqName()?.asString() ?: return null)
}
}
private fun ClassId.toRuntimeFqName(): String {
val className = getRelativeClassName().asString().replace('.', '$')
return if (getPackageFqName().isRoot()) className else "${getPackageFqName()}.$className"
}
@@ -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.load.kotlin.reflect
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.di.InjectorForRuntimeDescriptorLoader
public class RuntimeModuleData private(private val injector: InjectorForRuntimeDescriptorLoader) {
public val module: ModuleDescriptor get() = injector.getModuleDescriptor()
class object {
public fun create(classLoader: ClassLoader): RuntimeModuleData {
val module = ModuleDescriptorImpl(Name.special("<runtime module for $classLoader>"), listOf(), JavaToKotlinClassMap.INSTANCE)
module.addDependencyOnModule(module)
module.addDependencyOnModule(KotlinBuiltIns.getInstance().getBuiltInsModule())
val injector = InjectorForRuntimeDescriptorLoader(classLoader, module)
module.initialize(injector.getJavaDescriptorResolver().packageFragmentProvider)
return RuntimeModuleData(injector)
}
}
}
+1
View File
@@ -7,6 +7,7 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="descriptors.runtime" />
<orderEntry type="module" module-name="reflection" />
</component>
</module>