Old implementation of JavaDescriptorResolver deleted

This commit is contained in:
Andrey Breslav
2014-02-05 09:51:32 +01:00
committed by Alexander Udalov
parent 9f918d48b5
commit aa0dde3a78
33 changed files with 0 additions and 3675 deletions
@@ -1,89 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.descriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassKind;
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptorLite;
import org.jetbrains.jet.lang.resolve.java.scope.JavaClassNonStaticMembersScope;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType;
import java.util.Collection;
/**
* @see org.jetbrains.jet.lang.resolve.lazy.descriptors.LazyClassDescriptor
*/
public class ClassDescriptorFromJvmBytecode extends MutableClassDescriptorLite implements JavaClassDescriptor {
private JetType functionTypeForSamInterface;
private JavaClassNonStaticMembersScope scopeForConstructorResolve;
private ConstructorDescriptor primaryConstructor;
private Collection<ConstructorDescriptor> constructors;
public ClassDescriptorFromJvmBytecode(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull Name name,
@NotNull ClassKind kind,
boolean isInner
) {
super(containingDeclaration, name, kind, isInner);
}
@NotNull
@Override
public Collection<ConstructorDescriptor> getConstructors() {
assert scopeForConstructorResolve != null;
if (constructors == null) {
constructors = scopeForConstructorResolve.getConstructors();
}
return constructors;
}
@Nullable
@Override
public ConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
if (primaryConstructor == null) {
for (ConstructorDescriptor constructor : getConstructors()) {
if (constructor.isPrimary()) {
if (primaryConstructor != null) {
throw new IllegalStateException(
"Class has more than one primary constructor: " + primaryConstructor + "\n" + constructor);
}
primaryConstructor = constructor;
}
}
}
return primaryConstructor;
}
public void setScopeForConstructorResolve(@NotNull JavaClassNonStaticMembersScope scopeForConstructorResolve) {
this.scopeForConstructorResolve = scopeForConstructorResolve;
}
@Override
@Nullable
public JetType getFunctionTypeForSamInterface() {
return functionTypeForSamInterface;
}
public void setFunctionTypeForSamInterface(@NotNull JetType functionTypeForSamInterface) {
this.functionTypeForSamInterface = functionTypeForSamInterface;
}
}
@@ -1,107 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.descriptor;
import com.intellij.util.NullableFunction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptorVisitor;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.descriptors.impl.DeclarationDescriptorImpl;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaPackageFragmentProvider;
import org.jetbrains.jet.lang.resolve.java.scope.JavaClassStaticMembersScope;
import org.jetbrains.jet.lang.resolve.java.scope.JavaPackageFragmentScope;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.types.TypeSubstitutor;
public class JavaPackageFragmentDescriptorImpl extends DeclarationDescriptorImpl implements JavaPackageFragmentDescriptor {
@Nullable
public static JavaPackageFragmentDescriptorImpl create(
@NotNull JavaPackageFragmentProvider provider,
@NotNull FqName fqName,
@NotNull NullableFunction<JavaPackageFragmentDescriptor, JavaPackageFragmentScope> scopeFactory
) {
JavaPackageFragmentDescriptorImpl descriptor = new JavaPackageFragmentDescriptorImpl(provider, fqName, scopeFactory);
return descriptor.memberScope == null ? null : descriptor;
}
private final JavaPackageFragmentProvider provider;
private final FqName fqName;
private final JavaPackageFragmentScope memberScope;
private JavaPackageFragmentDescriptorImpl(
@NotNull JavaPackageFragmentProvider provider,
@NotNull FqName fqName,
@NotNull NullableFunction<JavaPackageFragmentDescriptor, JavaPackageFragmentScope> scopeFactory
) {
super(Annotations.EMPTY, fqName.shortNameOrSpecial());
this.provider = provider;
this.fqName = fqName;
this.memberScope = scopeFactory.fun(this);
}
@NotNull
@Override
public Kind getKind() {
return memberScope instanceof JavaClassStaticMembersScope ? Kind.CLASS_STATICS : Kind.PROPER;
}
@NotNull
@Override
public JavaDescriptorResolver getJavaDescriptorResolver() {
return provider.getJavaDescriptorResolver();
}
@NotNull
@Override
public ModuleDescriptor getContainingDeclaration() {
return provider.getModule();
}
@Nullable
@Override
public DeclarationDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
return this;
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitPackageFragmentDescriptor(this, data);
}
@NotNull
@Override
public JavaPackageFragmentScope getMemberScope() {
return memberScope;
}
@NotNull
@Override
public FqName getFqName() {
return fqName;
}
@Override
@NotNull
public JavaPackageFragmentProvider getProvider() {
return provider;
}
}
@@ -31,7 +31,6 @@ import org.jetbrains.jet.lang.resolve.kotlin.DeserializedDescriptorResolver
import org.jetbrains.jet.lang.resolve.kotlin.KotlinClassFinder
import org.jetbrains.jet.lang.resolve.name.FqName
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass
import org.jetbrains.jet.lang.resolve.java.resolver.JavaClassResolver
import org.jetbrains.jet.lang.descriptors.ClassDescriptor
open class GlobalJavaResolverContext(
@@ -39,7 +39,6 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.util.*;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getFqNameSafe;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isEnumClassObject;
public final class DescriptorResolverUtils {
public static final FqName OBJECT_FQ_NAME = new FqName("java.lang.Object");
@@ -133,10 +132,6 @@ public final class DescriptorResolverUtils {
"valueOf(java.lang.String)".equals(signature);
}
public static boolean isCorrectOwnerForEnumMethod(@NotNull ClassOrPackageFragmentDescriptor ownerDescriptor, @NotNull JavaMethod method) {
return isEnumClassObject(ownerDescriptor) == shouldBeInEnumClassObject(method);
}
public static boolean isObjectMethodInInterface(@NotNull JavaMember member) {
return member.getContainingClass().isInterface() && member instanceof JavaMethod && isObjectMethod((JavaMethod) member);
}
@@ -1,165 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.resolver;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.constants.*;
import org.jetbrains.jet.lang.resolve.java.structure.*;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.JetTypeImpl;
import org.jetbrains.jet.lang.types.TypeProjectionImpl;
import org.jetbrains.jet.lang.types.TypeUtils;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.IGNORE_KOTLIN_SOURCES;
import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.INCLUDE_KOTLIN_SOURCES;
public final class JavaAnnotationArgumentResolver {
private JavaAnnotationResolver annotationResolver;
private JavaClassResolver classResolver;
private JavaTypeTransformer typeTransformer;
@Inject
public void setAnnotationResolver(JavaAnnotationResolver annotationResolver) {
this.annotationResolver = annotationResolver;
}
@Inject
public void setClassResolver(JavaClassResolver classResolver) {
this.classResolver = classResolver;
}
@Inject
public void setTypeTransformer(JavaTypeTransformer typeTransformer) {
this.typeTransformer = typeTransformer;
}
@Nullable
public CompileTimeConstant<?> resolveAnnotationArgument(
@NotNull FqName annotationFqName,
@NotNull JavaAnnotationArgument argument,
@NotNull PostponedTasks postponedTasks
) {
if (argument instanceof JavaLiteralAnnotationArgument) {
return ResolverPackage.resolveCompileTimeConstantValue(((JavaLiteralAnnotationArgument) argument).getValue(), true, null);
}
// Enum
else if (argument instanceof JavaReferenceAnnotationArgument) {
return resolveFromReference(((JavaReferenceAnnotationArgument) argument).resolve(), postponedTasks);
}
// Array
else if (argument instanceof JavaArrayAnnotationArgument) {
Name argumentName = argument.getName();
return resolveFromArray(
annotationFqName,
argumentName == null ? JavaAnnotationResolver.DEFAULT_ANNOTATION_MEMBER_NAME : argumentName,
((JavaArrayAnnotationArgument) argument).getElements(),
postponedTasks
);
}
// Annotation
else if (argument instanceof JavaAnnotationAsAnnotationArgument) {
return resolveFromAnnotation(((JavaAnnotationAsAnnotationArgument) argument).getAnnotation(), postponedTasks);
}
// Class<?>
else if (argument instanceof JavaClassObjectAnnotationArgument) {
return resolveFromJavaClassObjectType(((JavaClassObjectAnnotationArgument) argument).getReferencedType());
}
return null;
}
@Nullable
private CompileTimeConstant<?> resolveFromAnnotation(@NotNull JavaAnnotation value, @NotNull PostponedTasks taskList) {
AnnotationDescriptor descriptor = annotationResolver.resolveAnnotation(value, taskList);
return descriptor == null ? null : new AnnotationValue(descriptor);
}
@Nullable
private CompileTimeConstant<?> resolveFromArray(
@NotNull FqName annotationFqName,
@NotNull Name argumentName,
@NotNull List<JavaAnnotationArgument> elements,
@NotNull PostponedTasks taskList
) {
ClassDescriptor annotationClass = classResolver.resolveClass(annotationFqName, INCLUDE_KOTLIN_SOURCES, taskList);
if (annotationClass == null) return null;
//TODO: nullability issues
ValueParameterDescriptor valueParameter = DescriptorResolverUtils.getAnnotationParameterByName(argumentName, annotationClass);
if (valueParameter == null) return null;
List<CompileTimeConstant<?>> values = new ArrayList<CompileTimeConstant<?>>(elements.size());
for (JavaAnnotationArgument argument : elements) {
CompileTimeConstant<?> value = resolveAnnotationArgument(annotationFqName, argument, taskList);
values.add(value == null ? NullValue.NULL : value);
}
return new ArrayValue(values, valueParameter.getType(), true);
}
@Nullable
private CompileTimeConstant<?> resolveFromReference(@Nullable JavaElement element, @NotNull PostponedTasks taskList) {
if (!(element instanceof JavaField)) return null;
JavaField field = (JavaField) element;
if (!field.isEnumEntry()) return null;
FqName fqName = field.getContainingClass().getFqName();
if (fqName == null) return null;
ClassDescriptor enumClass = classResolver.resolveClass(fqName, INCLUDE_KOTLIN_SOURCES, taskList);
if (enumClass == null) return null;
ClassifierDescriptor classifier = enumClass.getUnsubstitutedInnerClassesScope().getClassifier(field.getName());
if (!(classifier instanceof ClassDescriptor)) return null;
return new EnumValue((ClassDescriptor) classifier);
}
@Nullable
private CompileTimeConstant<?> resolveFromJavaClassObjectType(@NotNull JavaType javaType) {
// Foo.class is never nullable
JetType type = TypeUtils.makeNotNullable(typeTransformer.transformToType(javaType, TypeVariableResolver.EMPTY));
ClassDescriptor jlClass = classResolver.resolveClass(JL_CLASS_FQ_NAME, IGNORE_KOTLIN_SOURCES);
if (jlClass == null) return null;
List<TypeProjectionImpl> arguments = Collections.singletonList(new TypeProjectionImpl(type));
JetTypeImpl javaClassType = new JetTypeImpl(
jlClass.getAnnotations(),
jlClass.getTypeConstructor(),
false,
arguments,
jlClass.getMemberScope(arguments)
);
return new JavaClassValue(javaClassType);
}
}
@@ -1,164 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.resolver;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationsImpl;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames;
import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap;
import org.jetbrains.jet.lang.resolve.java.structure.JavaAnnotation;
import org.jetbrains.jet.lang.resolve.java.structure.JavaAnnotationArgument;
import org.jetbrains.jet.lang.resolve.java.structure.JavaAnnotationOwner;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.INCLUDE_KOTLIN_SOURCES;
import static org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils.fqNameByClass;
public final class JavaAnnotationResolver {
private JavaClassResolver classResolver;
private JavaAnnotationArgumentResolver argumentResolver;
private ExternalAnnotationResolver externalAnnotationResolver;
public JavaAnnotationResolver() {
}
@Inject
public void setClassResolver(JavaClassResolver classResolver) {
this.classResolver = classResolver;
}
@Inject
public void setArgumentResolver(JavaAnnotationArgumentResolver argumentResolver) {
this.argumentResolver = argumentResolver;
}
@Inject
public void setExternalAnnotationResolver(ExternalAnnotationResolver externalAnnotationResolver) {
this.externalAnnotationResolver = externalAnnotationResolver;
}
private void resolveAnnotations(
@NotNull Collection<JavaAnnotation> annotations,
@NotNull PostponedTasks tasks,
@NotNull List<AnnotationDescriptor> result
) {
for (JavaAnnotation javaAnnotation : annotations) {
AnnotationDescriptor annotation = resolveAnnotation(javaAnnotation, tasks);
if (annotation != null) {
result.add(annotation);
}
}
}
@NotNull
public Annotations resolveAnnotations(@NotNull JavaAnnotationOwner owner, @NotNull PostponedTasks tasks) {
List<AnnotationDescriptor> result = new ArrayList<AnnotationDescriptor>();
resolveAnnotations(owner.getAnnotations(), tasks, result);
resolveAnnotations(externalAnnotationResolver.findExternalAnnotations(owner), tasks, result);
return new AnnotationsImpl(result);
}
@NotNull
public Annotations resolveAnnotations(@NotNull JavaAnnotationOwner owner) {
PostponedTasks postponedTasks = new PostponedTasks();
Annotations annotations = resolveAnnotations(owner, postponedTasks);
postponedTasks.performTasks();
return annotations;
}
@Nullable
public AnnotationDescriptor resolveAnnotation(@NotNull JavaAnnotation javaAnnotation, @NotNull PostponedTasks postponedTasks) {
final AnnotationDescriptorImpl annotation = new AnnotationDescriptorImpl();
FqName fqName = javaAnnotation.getFqName();
if (fqName == null) {
return null;
}
// Don't process internal jet annotations and jetbrains NotNull annotations
if (isSpecialAnnotation(fqName)) {
return null;
}
AnnotationDescriptor mappedClassDescriptor = JavaToKotlinClassMap.getInstance().mapToAnnotationClass(fqName);
if (mappedClassDescriptor != null) {
return mappedClassDescriptor;
}
final ClassDescriptor annotationClass = classResolver.resolveClass(fqName, INCLUDE_KOTLIN_SOURCES, postponedTasks);
if (annotationClass == null) {
return null;
}
postponedTasks.addTask(new Runnable() {
@Override
public void run() {
annotation.setAnnotationType(annotationClass.getDefaultType());
}
});
for (JavaAnnotationArgument argument : javaAnnotation.getArguments()) {
CompileTimeConstant value = argumentResolver.resolveAnnotationArgument(fqName, argument, postponedTasks);
if (value == null) continue;
Name name = argument.getName();
ValueParameterDescriptor descriptor = DescriptorResolverUtils.getAnnotationParameterByName(
name == null ? DEFAULT_ANNOTATION_MEMBER_NAME : name, annotationClass);
if (descriptor != null) {
annotation.setValueArgument(descriptor, value);
}
}
return annotation;
}
@Nullable
public JavaAnnotation findAnnotationWithExternal(@NotNull JavaAnnotationOwner owner, @NotNull FqName name) {
JavaAnnotation annotation = owner.findAnnotation(name);
if (annotation != null) {
return annotation;
}
return externalAnnotationResolver.findExternalAnnotation(owner, name);
}
public boolean hasNotNullAnnotation(@NotNull JavaAnnotationOwner owner) {
return findAnnotationWithExternal(owner, JETBRAINS_NOT_NULL_ANNOTATION) != null;
}
public boolean hasMutableAnnotation(@NotNull JavaAnnotationOwner owner) {
return findAnnotationWithExternal(owner, JETBRAINS_MUTABLE_ANNOTATION) != null;
}
public boolean hasReadonlyAnnotation(@NotNull JavaAnnotationOwner owner) {
return findAnnotationWithExternal(owner, JETBRAINS_READONLY_ANNOTATION) != null;
}
}
@@ -1,374 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.resolver;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.DescriptorFactory;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule;
import org.jetbrains.jet.lang.resolve.java.JavaClassFinder;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode;
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaClassDescriptor;
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaEnumClassObjectDescriptor;
import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils;
import org.jetbrains.jet.lang.resolve.java.scope.JavaClassNonStaticMembersScope;
import org.jetbrains.jet.lang.resolve.java.scope.JavaEnumClassObjectScope;
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod;
import org.jetbrains.jet.lang.resolve.kotlin.DeserializedDescriptorResolver;
import org.jetbrains.jet.lang.resolve.kotlin.KotlinClassFinder;
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import javax.inject.Inject;
import java.util.*;
import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.INCLUDE_KOTLIN_SOURCES;
import static org.jetbrains.jet.lang.resolve.name.SpecialNames.getClassObjectName;
public final class JavaClassResolver {
@NotNull
private final Map<FqNameUnsafe, ClassDescriptor> classDescriptorCache = new HashMap<FqNameUnsafe, ClassDescriptor>();
@NotNull
private final Set<FqNameUnsafe> unresolvedCache = new HashSet<FqNameUnsafe>();
private JavaResolverCache cache;
private JavaTypeParameterResolver typeParameterResolver;
private JavaMemberResolver memberResolver;
private JavaAnnotationResolver annotationResolver;
private JavaClassFinder javaClassFinder;
private JavaPackageFragmentProvider packageFragmentProvider;
private JavaSupertypeResolver supertypesResolver;
private JavaFunctionResolver functionResolver;
private DeserializedDescriptorResolver deserializedDescriptorResolver;
private KotlinClassFinder kotlinClassFinder;
public JavaClassResolver() {
}
@Inject
public void setCache(JavaResolverCache cache) {
this.cache = cache;
}
@Inject
public void setDeserializedDescriptorResolver(DeserializedDescriptorResolver deserializedDescriptorResolver) {
this.deserializedDescriptorResolver = deserializedDescriptorResolver;
}
@Inject
public void setTypeParameterResolver(JavaTypeParameterResolver typeParameterResolver) {
this.typeParameterResolver = typeParameterResolver;
}
@Inject
public void setMemberResolver(JavaMemberResolver memberResolver) {
this.memberResolver = memberResolver;
}
@Inject
public void setAnnotationResolver(JavaAnnotationResolver annotationResolver) {
this.annotationResolver = annotationResolver;
}
@Inject
public void setJavaClassFinder(JavaClassFinder javaClassFinder) {
this.javaClassFinder = javaClassFinder;
}
@Inject
public void setPackageFragmentProvider(JavaPackageFragmentProvider packageFragmentProvider) {
this.packageFragmentProvider = packageFragmentProvider;
}
@Inject
public void setSupertypesResolver(JavaSupertypeResolver supertypesResolver) {
this.supertypesResolver = supertypesResolver;
}
@Inject
public void setFunctionResolver(JavaFunctionResolver functionResolver) {
this.functionResolver = functionResolver;
}
@Inject
public void setKotlinClassFinder(KotlinClassFinder kotlinClassFinder) {
this.kotlinClassFinder = kotlinClassFinder;
}
@Nullable
public ClassDescriptor resolveClass(@NotNull FqName qualifiedName, @NotNull DescriptorSearchRule searchRule) {
PostponedTasks postponedTasks = new PostponedTasks();
ClassDescriptor classDescriptor = resolveClass(qualifiedName, searchRule, postponedTasks);
postponedTasks.performTasks();
return classDescriptor;
}
@Nullable
public ClassDescriptor resolveClass(
@NotNull FqName qualifiedName,
@NotNull DescriptorSearchRule searchRule,
@NotNull PostponedTasks tasks
) {
if (isTraitImplementation(qualifiedName)) {
return null;
}
ClassDescriptor builtinClassDescriptor = getKotlinBuiltinClassDescriptor(qualifiedName);
if (builtinClassDescriptor != null) {
return builtinClassDescriptor;
}
if (searchRule == INCLUDE_KOTLIN_SOURCES) {
ClassDescriptor kotlinClassDescriptor = cache.getClassResolvedFromSource(qualifiedName);
if (kotlinClassDescriptor != null) {
return kotlinClassDescriptor;
}
}
FqNameUnsafe fqName = javaClassToKotlinFqName(qualifiedName);
ClassDescriptor cachedDescriptor = classDescriptorCache.get(fqName);
if (cachedDescriptor != null) {
return cachedDescriptor;
}
if (unresolvedCache.contains(fqName)) {
return null;
}
return doResolveClass(qualifiedName, tasks);
}
private ClassDescriptor doResolveClass(@NotNull FqName qualifiedName, @NotNull PostponedTasks tasks) {
//TODO: correct scope
KotlinJvmBinaryClass kotlinClass = kotlinClassFinder.findKotlinClass(qualifiedName);
if (kotlinClass != null) {
ClassDescriptor deserializedDescriptor = deserializedDescriptorResolver.resolveClass(kotlinClass);
if (deserializedDescriptor != null) {
cache(javaClassToKotlinFqName(qualifiedName), deserializedDescriptor);
return deserializedDescriptor;
}
}
JavaClass javaClass = javaClassFinder.findClass(qualifiedName);
if (javaClass == null) {
cacheNegativeValue(javaClassToKotlinFqName(qualifiedName));
return null;
}
// Class may have been resolved previously by different Java resolver instance, and we are reusing its trace
ClassDescriptor alreadyResolved = cache.getClass(javaClass);
if (alreadyResolved != null) {
return alreadyResolved;
}
ClassOrPackageFragmentDescriptor containingDeclaration = resolveParentDescriptor(qualifiedName, javaClass.getOuterClass());
// class may be resolved during resolution of parent
ClassDescriptor cachedDescriptor = classDescriptorCache.get(javaClassToKotlinFqName(qualifiedName));
if (cachedDescriptor != null) {
return cachedDescriptor;
}
assert !unresolvedCache.contains(qualifiedName.toUnsafe())
: "We can resolve the class, so it can't be 'unresolved' during parent resolution";
checkFqNamesAreConsistent(javaClass, qualifiedName);
assert javaClass.getOriginKind() != JavaClass.OriginKind.KOTLIN_LIGHT_CLASS :
"Trying to resolve a light class as a regular PsiClass: " + javaClass.getFqName();
return doCreateClassDescriptor(qualifiedName, javaClass, tasks, containingDeclaration);
}
private void cacheNegativeValue(@NotNull FqNameUnsafe fqNameUnsafe) {
if (classDescriptorCache.containsKey(fqNameUnsafe)) {
throw new IllegalStateException("rewrite at " + fqNameUnsafe);
}
unresolvedCache.add(fqNameUnsafe);
}
private static boolean isTraitImplementation(@NotNull FqName qualifiedName) {
// TODO: only if -$$TImpl class is created by Kotlin
return qualifiedName.asString().endsWith(JvmAbi.TRAIT_IMPL_SUFFIX);
}
@NotNull
private JavaClassDescriptor doCreateClassDescriptor(
@NotNull FqName fqName,
@NotNull JavaClass javaClass,
@NotNull PostponedTasks taskList,
@NotNull ClassOrPackageFragmentDescriptor containingDeclaration
) {
ClassDescriptorFromJvmBytecode classDescriptor =
new ClassDescriptorFromJvmBytecode(containingDeclaration, javaClass.getName(), determineClassKind(javaClass), isInnerClass(javaClass));
cache(javaClassToKotlinFqName(fqName), classDescriptor);
JavaTypeParameterResolver.Initializer typeParameterInitializer = typeParameterResolver.resolveTypeParameters(classDescriptor, javaClass);
classDescriptor.setTypeParameterDescriptors(typeParameterInitializer.getDescriptors());
List<JetType> supertypes = new ArrayList<JetType>();
classDescriptor.setSupertypes(supertypes);
classDescriptor.setVisibility(javaClass.getVisibility());
classDescriptor.setModality(determineClassModality(javaClass));
classDescriptor.createTypeConstructor();
JavaClassNonStaticMembersScope scope = new JavaClassNonStaticMembersScope(classDescriptor, javaClass, memberResolver);
classDescriptor.setScopeForMemberLookup(scope);
classDescriptor.setScopeForConstructorResolve(scope);
typeParameterInitializer.initialize();
// TODO: ugly hack: tests crash if initializeTypeParameters called with class containing proper supertypes
List<TypeParameterDescriptor> classTypeParameters = classDescriptor.getTypeConstructor().getParameters();
supertypes.addAll(supertypesResolver.getSupertypes(classDescriptor, javaClass, classTypeParameters));
if (javaClass.isEnum()) {
JavaEnumClassObjectDescriptor enumClassObject = createEnumClassObject(classDescriptor, javaClass);
createEnumSyntheticMethods(enumClassObject, classDescriptor.getDefaultType());
cache(getFqNameForClassObject(javaClass), enumClassObject);
classDescriptor.getBuilder().setClassObjectDescriptor(enumClassObject);
}
classDescriptor.setAnnotations(annotationResolver.resolveAnnotations(javaClass, taskList));
cache.recordClass(javaClass, classDescriptor);
JavaMethod samInterfaceMethod = SingleAbstractMethodUtils.getSamInterfaceMethod(javaClass);
if (samInterfaceMethod != null) {
SimpleFunctionDescriptor abstractMethod = resolveFunctionOfSamInterface(samInterfaceMethod, classDescriptor);
classDescriptor.setFunctionTypeForSamInterface(SingleAbstractMethodUtils.getFunctionTypeForAbstractMethod(abstractMethod));
}
return classDescriptor;
}
@NotNull
public static FqNameUnsafe getFqNameForClassObject(@NotNull JavaClass javaClass) {
FqName fqName = javaClass.getFqName();
assert fqName != null : "Reading java class with no qualified name";
return fqName.toUnsafe().child(getClassObjectName(javaClass.getName()));
}
@NotNull
private SimpleFunctionDescriptor resolveFunctionOfSamInterface(
@NotNull JavaMethod samInterfaceMethod,
@NotNull JavaClassDescriptor samInterface
) {
JavaClass methodContainer = samInterfaceMethod.getContainingClass();
FqName containerFqName = methodContainer.getFqName();
assert containerFqName != null : "qualified name is null for " + methodContainer;
if (DescriptorUtils.getFqName(samInterface).equalsTo(containerFqName)) {
SimpleFunctionDescriptor abstractMethod = functionResolver.resolveFunctionMutely(samInterfaceMethod, samInterface);
assert abstractMethod != null : "couldn't resolve method " + samInterfaceMethod;
return abstractMethod;
}
else {
return findFunctionWithMostSpecificReturnType(TypeUtils.getAllSupertypes(samInterface.getDefaultType()));
}
}
private void cache(@NotNull FqNameUnsafe fqName, @Nullable ClassDescriptor classDescriptor) {
if (classDescriptor == null) {
cacheNegativeValue(fqName);
}
else {
ClassDescriptor oldValue = classDescriptorCache.put(fqName, classDescriptor);
assert oldValue == null;
}
}
private void checkFqNamesAreConsistent(@NotNull JavaClass javaClass, @NotNull FqName desiredFqName) {
FqName fqName = javaClass.getFqName();
assert desiredFqName.equals(fqName) : "Inconsistent FQ names: " + fqName + ", " + desiredFqName;
FqNameUnsafe correctedName = javaClassToKotlinFqName(fqName);
if (classDescriptorCache.containsKey(correctedName) || unresolvedCache.contains(correctedName)) {
throw new IllegalStateException("Cache already contains FQ name: " + fqName.asString());
}
}
@NotNull
private ClassOrPackageFragmentDescriptor resolveParentDescriptor(@NotNull FqName childClassFQName, JavaClass parentClass) {
if (parentClass != null) {
FqName parentFqName = parentClass.getFqName();
ClassDescriptor parentClassDescriptor = resolveClass(parentFqName, INCLUDE_KOTLIN_SOURCES);
if (parentClassDescriptor == null) {
throw new IllegalStateException("Could not resolve " + parentFqName + " required to be parent for " + childClassFQName);
}
return parentClassDescriptor;
}
else {
FqName parentFqName = childClassFQName.parent();
PackageFragmentDescriptor parentPackage = packageFragmentProvider.getPackageFragment(parentFqName);
if (parentPackage == null) {
throw new IllegalStateException("Could not resolve " + parentFqName + " required to be parent for " + childClassFQName);
}
return parentPackage;
}
}
// This method replaces "object" segments of FQ name to "<class-object-for-...>"
@NotNull
private static FqNameUnsafe javaClassToKotlinFqName(@NotNull FqName rawFqName) {
List<Name> correctedSegments = new ArrayList<Name>();
for (Name segment : rawFqName.pathSegments()) {
if (JvmAbi.CLASS_OBJECT_CLASS_NAME.equals(segment.asString())) {
assert !correctedSegments.isEmpty();
Name previous = correctedSegments.get(correctedSegments.size() - 1);
correctedSegments.add(getClassObjectName(previous));
}
else {
correctedSegments.add(segment);
}
}
return FqNameUnsafe.fromSegments(correctedSegments);
}
@NotNull
private JavaEnumClassObjectDescriptor createEnumClassObject(@NotNull ClassDescriptor enumClass, @NotNull JavaClass javaClass) {
JavaEnumClassObjectDescriptor classObject = new JavaEnumClassObjectDescriptor(enumClass);
classObject.setSupertypes(Collections.singleton(KotlinBuiltIns.getInstance().getAnyType()));
classObject.setModality(Modality.FINAL);
classObject.setVisibility(DescriptorUtils.getSyntheticClassObjectVisibility());
classObject.setTypeParameterDescriptors(Collections.<TypeParameterDescriptor>emptyList());
classObject.createTypeConstructor();
JavaEnumClassObjectScope scope = new JavaEnumClassObjectScope(classObject, javaClass, memberResolver);
WritableScopeImpl writableScope =
new WritableScopeImpl(scope, classObject, RedeclarationHandler.THROW_EXCEPTION, "Enum class object scope");
writableScope.changeLockLevel(WritableScope.LockLevel.BOTH);
classObject.setScopeForMemberLookup(writableScope);
return classObject;
}
}
@@ -1,212 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.resolver;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl;
import org.jetbrains.jet.lang.resolve.java.JavaVisibilities;
import org.jetbrains.jet.lang.resolve.java.structure.JavaArrayType;
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod;
import org.jetbrains.jet.lang.resolve.java.structure.JavaType;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import javax.inject.Inject;
import java.util.*;
import static org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils.createSamAdapterConstructor;
import static org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils.isSamAdapterNecessary;
public final class JavaConstructorResolver {
private JavaResolverCache cache;
private JavaTypeTransformer typeTransformer;
private JavaValueParameterResolver valueParameterResolver;
private ExternalSignatureResolver externalSignatureResolver;
public JavaConstructorResolver() {
}
@Inject
public void setCache(JavaResolverCache cache) {
this.cache = cache;
}
@Inject
public void setTypeTransformer(JavaTypeTransformer typeTransformer) {
this.typeTransformer = typeTransformer;
}
@Inject
public void setValueParameterResolver(JavaValueParameterResolver valueParameterResolver) {
this.valueParameterResolver = valueParameterResolver;
}
@Inject
public void setExternalSignatureResolver(ExternalSignatureResolver externalSignatureResolver) {
this.externalSignatureResolver = externalSignatureResolver;
}
@NotNull
public Collection<ConstructorDescriptor> resolveConstructors(@NotNull JavaClass javaClass, @NotNull ClassDescriptor containingClass) {
Collection<ConstructorDescriptor> result = new ArrayList<ConstructorDescriptor>();
Collection<JavaMethod> constructors = javaClass.getConstructors();
if (constructors.isEmpty()) {
ConstructorDescriptor defaultConstructor = resolveDefaultConstructor(javaClass, containingClass);
if (defaultConstructor != null) {
result.add(defaultConstructor);
}
}
else {
for (JavaMethod constructor : constructors) {
ConstructorDescriptor descriptor = resolveConstructor(constructor, containingClass, javaClass.isStatic());
result.add(descriptor);
ConstructorDescriptor samAdapter = resolveSamAdapter(descriptor);
if (samAdapter != null) {
result.add(samAdapter);
}
}
}
for (ConstructorDescriptor constructor : result) {
((ConstructorDescriptorImpl) constructor).setReturnType(containingClass.getDefaultType());
}
return result;
}
@Nullable
private ConstructorDescriptor resolveDefaultConstructor(@NotNull JavaClass javaClass, @NotNull ClassDescriptor containingClass) {
ConstructorDescriptor alreadyResolved = cache.getConstructor(javaClass);
if (alreadyResolved != null) {
return alreadyResolved;
}
boolean isAnnotation = javaClass.isAnnotationType();
if (javaClass.isInterface() && !isAnnotation) return null;
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(
containingClass,
Annotations.EMPTY,
true);
List<TypeParameterDescriptor> typeParameters = containingClass.getTypeConstructor().getParameters();
List<ValueParameterDescriptor> valueParameters;
if (isAnnotation) {
TypeVariableResolver typeVariableResolver = new TypeVariableResolverImpl(typeParameters, containingClass);
valueParameters = resolveAnnotationParameters(javaClass, constructorDescriptor, typeVariableResolver);
}
else {
valueParameters = Collections.emptyList();
}
constructorDescriptor.initialize(typeParameters, valueParameters, getConstructorVisibility(containingClass), javaClass.isStatic());
cache.recordConstructor(javaClass, constructorDescriptor);
return constructorDescriptor;
}
@NotNull
private List<ValueParameterDescriptor> resolveAnnotationParameters(
@NotNull JavaClass javaClass,
@NotNull ConstructorDescriptor constructorDescriptor,
@NotNull TypeVariableResolver typeVariableResolver
) {
// A constructor for an annotation type takes all the "methods" in the @interface as parameters
Collection<JavaMethod> methods = javaClass.getMethods();
List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(methods.size());
int index = 0;
for (Iterator<JavaMethod> iterator = methods.iterator(); iterator.hasNext(); ) {
JavaMethod method = iterator.next();
assert method.getValueParameters().isEmpty() : "Annotation method can't have parameters: " + method;
JavaType returnType = method.getReturnType();
assert returnType != null : "Annotation method has no return type: " + method;
// We take the following heuristic convention:
// if the last method of the @interface is an array, we convert it into a vararg
JetType varargElementType = null;
if (!iterator.hasNext() && returnType instanceof JavaArrayType) {
JavaType componentType = ((JavaArrayType) returnType).getComponentType();
varargElementType = typeTransformer.transformToType(componentType, typeVariableResolver);
}
result.add(new ValueParameterDescriptorImpl(
constructorDescriptor,
index,
Annotations.EMPTY,
method.getName(),
// Parameters of annotation constructors in Java are never nullable
TypeUtils.makeNotNullable(typeTransformer.transformToType(returnType, typeVariableResolver)),
method.hasAnnotationParameterDefaultValue(),
varargElementType == null ? null : TypeUtils.makeNotNullable(varargElementType)));
index++;
}
return result;
}
@NotNull
private ConstructorDescriptor resolveConstructor(
@NotNull JavaMethod constructor,
@NotNull ClassDescriptor classDescriptor,
boolean isStaticClass
) {
ConstructorDescriptor alreadyResolved = cache.getConstructor(constructor);
if (alreadyResolved != null) {
return alreadyResolved;
}
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(
classDescriptor,
Annotations.EMPTY, // TODO
false);
List<TypeParameterDescriptor> typeParameters = classDescriptor.getTypeConstructor().getParameters();
List<ValueParameterDescriptor> valueParameters = valueParameterResolver.resolveValueParameters(
constructorDescriptor, constructor,
new TypeVariableResolverImpl(typeParameters, classDescriptor)
);
ExternalSignatureResolver.AlternativeMethodSignature effectiveSignature = externalSignatureResolver
.resolveAlternativeMethodSignature(constructor, false, null, null, valueParameters,
Collections.<TypeParameterDescriptor>emptyList());
constructorDescriptor
.initialize(typeParameters, effectiveSignature.getValueParameters(), constructor.getVisibility(), isStaticClass);
List<String> signatureErrors = effectiveSignature.getErrors();
if (!signatureErrors.isEmpty()) {
externalSignatureResolver.reportSignatureErrors(constructorDescriptor, signatureErrors);
}
cache.recordConstructor(constructor, constructorDescriptor);
return constructorDescriptor;
}
}
@@ -1,246 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.resolver;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.descriptor.*;
import org.jetbrains.jet.lang.resolve.java.scope.NamedMembers;
import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod;
import org.jetbrains.jet.lang.resolve.java.structure.JavaType;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import javax.inject.Inject;
import java.util.*;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*;
import static org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils.resolveOverrides;
import static org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils.*;
public final class JavaFunctionResolver {
private JavaTypeTransformer typeTransformer;
private JavaResolverCache cache;
private JavaTypeParameterResolver typeParameterResolver;
private JavaValueParameterResolver valueParameterResolver;
private JavaAnnotationResolver annotationResolver;
private ExternalSignatureResolver externalSignatureResolver;
private ErrorReporter errorReporter;
private MethodSignatureChecker signatureChecker;
@Inject
public void setTypeTransformer(JavaTypeTransformer typeTransformer) {
this.typeTransformer = typeTransformer;
}
@Inject
public void setCache(JavaResolverCache cache) {
this.cache = cache;
}
@Inject
public void setTypeParameterResolver(JavaTypeParameterResolver typeParameterResolver) {
this.typeParameterResolver = typeParameterResolver;
}
@Inject
public void setValueParameterResolver(JavaValueParameterResolver valueParameterResolver) {
this.valueParameterResolver = valueParameterResolver;
}
@Inject
public void setAnnotationResolver(JavaAnnotationResolver annotationResolver) {
this.annotationResolver = annotationResolver;
}
@Inject
public void setExternalSignatureResolver(ExternalSignatureResolver externalSignatureResolver) {
this.externalSignatureResolver = externalSignatureResolver;
}
@Inject
public void setErrorReporter(ErrorReporter errorReporter) {
this.errorReporter = errorReporter;
}
@Inject
public void setSignatureChecker(MethodSignatureChecker signatureChecker) {
this.signatureChecker = signatureChecker;
}
@Nullable
SimpleFunctionDescriptor resolveFunctionMutely(@NotNull JavaMethod method, @NotNull ClassOrPackageFragmentDescriptor owner) {
return resolveMethodToFunctionDescriptor(method, owner, false);
}
@Nullable
private SimpleFunctionDescriptor resolveMethodToFunctionDescriptor(
@NotNull JavaMethod method,
@NotNull ClassOrPackageFragmentDescriptor ownerDescriptor,
boolean record
) {
if (!DescriptorResolverUtils.isCorrectOwnerForEnumMethod(ownerDescriptor, method)) {
return null;
}
JavaType returnJavaType = method.getReturnType();
if (returnJavaType == null) {
// This means that the method is a constructor
return null;
}
SimpleFunctionDescriptor alreadyResolved = cache.getMethod(method);
if (alreadyResolved != null) {
return alreadyResolved;
}
SimpleFunctionDescriptorImpl functionDescriptorImpl = new JavaMethodDescriptor(
ownerDescriptor,
annotationResolver.resolveAnnotations(method),
method.getName()
);
JavaTypeParameterResolver.Initializer typeParameterInitializer = typeParameterResolver.resolveTypeParameters(functionDescriptorImpl, method);
typeParameterInitializer.initialize();
List<TypeParameterDescriptor> methodTypeParameters = typeParameterInitializer.getDescriptors();
TypeVariableResolver typeVariableResolver = new TypeVariableResolverImpl(methodTypeParameters, functionDescriptorImpl);
List<ValueParameterDescriptor> valueParameters =
valueParameterResolver.resolveValueParameters(functionDescriptorImpl, method, typeVariableResolver);
JetType returnType = makeReturnType(returnJavaType, method, typeVariableResolver);
List<String> signatureErrors;
List<FunctionDescriptor> superFunctions;
ExternalSignatureResolver.AlternativeMethodSignature effectiveSignature;
if (ownerDescriptor instanceof PackageFragmentDescriptor) {
superFunctions = Collections.emptyList();
effectiveSignature = externalSignatureResolver
.resolveAlternativeMethodSignature(method, false, returnType, null, valueParameters, methodTypeParameters);
signatureErrors = effectiveSignature.getErrors();
}
else if (ownerDescriptor instanceof ClassDescriptor) {
ExternalSignatureResolver.PropagatedMethodSignature propagated = externalSignatureResolver
.resolvePropagatedSignature(method, (ClassDescriptor) ownerDescriptor, returnType, null, valueParameters,
methodTypeParameters);
superFunctions = propagated.getSuperMethods();
effectiveSignature = externalSignatureResolver
.resolveAlternativeMethodSignature(method, !superFunctions.isEmpty(), propagated.getReturnType(),
propagated.getReceiverType(), propagated.getValueParameters(),
propagated.getTypeParameters());
signatureErrors = new ArrayList<String>(propagated.getErrors());
signatureErrors.addAll(effectiveSignature.getErrors());
}
else {
throw new IllegalStateException("Unknown class or package descriptor: " + ownerDescriptor);
}
functionDescriptorImpl.initialize(
effectiveSignature.getReceiverType(),
DescriptorUtils.getExpectedThisObjectIfNeeded(ownerDescriptor),
effectiveSignature.getTypeParameters(),
effectiveSignature.getValueParameters(),
effectiveSignature.getReturnType(),
Modality.convertFromFlags(method.isAbstract(), !method.isFinal()),
method.getVisibility()
/*TODO what if user annotate it with inline?*/
);
if (record) {
cache.recordMethod(method, functionDescriptorImpl);
}
signatureChecker.checkSignature(method, record, functionDescriptorImpl, signatureErrors, superFunctions);
return functionDescriptorImpl;
}
@NotNull
public Set<FunctionDescriptor> resolveFunctionGroupForClass(@NotNull NamedMembers members, @NotNull ClassOrPackageFragmentDescriptor owner) {
Name methodName = members.getName();
Set<SimpleFunctionDescriptor> functionsFromCurrent = new HashSet<SimpleFunctionDescriptor>();
for (JavaMethod method : members.getMethods()) {
SimpleFunctionDescriptor function = resolveMethodToFunctionDescriptor(method, owner, true);
if (function != null) {
functionsFromCurrent.add(function);
SimpleFunctionDescriptor samAdapter = resolveSamAdapter(function);
if (samAdapter != null) {
functionsFromCurrent.add(samAdapter);
}
}
}
if (owner instanceof JavaPackageFragmentDescriptor) {
SamConstructorDescriptor samConstructor = resolveSamConstructor((JavaPackageFragmentDescriptor) owner, members);
if (samConstructor != null) {
functionsFromCurrent.add(samConstructor);
}
}
Set<FunctionDescriptor> functions = new HashSet<FunctionDescriptor>();
if (owner instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) owner;
Collection<SimpleFunctionDescriptor> functionsFromSupertypes = getFunctionsFromSupertypes(methodName, classDescriptor);
functions.addAll(resolveOverrides(methodName, functionsFromSupertypes, functionsFromCurrent, classDescriptor, errorReporter));
}
if (isEnumClassObject(owner)) {
for (FunctionDescriptor functionDescriptor : functionsFromCurrent) {
if (!(isEnumValueOfMethod(functionDescriptor) || isEnumValuesMethod(functionDescriptor))) {
functions.add(functionDescriptor);
}
}
}
else {
functions.addAll(functionsFromCurrent);
}
return functions;
}
@NotNull
private JetType makeReturnType(
@NotNull JavaType returnType,
@NotNull JavaMethod method,
@NotNull TypeVariableResolver typeVariableResolver
) {
TypeUsage typeUsage = annotationResolver.hasReadonlyAnnotation(method) && !annotationResolver.hasMutableAnnotation(method)
? TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT
: TypeUsage.MEMBER_SIGNATURE_COVARIANT;
JetType transformedType = typeTransformer.transformToType(returnType, typeUsage, typeVariableResolver);
// Annotation arguments are never null in Java
if (method.getContainingClass().isAnnotationType() || annotationResolver.hasNotNullAnnotation(method)) {
return TypeUtils.makeNotNullable(transformedType);
}
else {
return transformedType;
}
}
}
@@ -1,76 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.resolver;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule;
import org.jetbrains.jet.lang.resolve.java.scope.NamedMembers;
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
import org.jetbrains.jet.lang.resolve.name.FqName;
import javax.inject.Inject;
import java.util.Collection;
import java.util.Set;
public class JavaMemberResolver {
private JavaClassResolver classResolver;
private JavaFunctionResolver functionResolver;
private JavaPropertyResolver propertyResolver;
private JavaConstructorResolver constructorResolver;
@Inject
public void setClassResolver(JavaClassResolver classResolver) {
this.classResolver = classResolver;
}
@Inject
public void setFunctionResolver(JavaFunctionResolver functionResolver) {
this.functionResolver = functionResolver;
}
@Inject
public void setPropertyResolver(JavaPropertyResolver propertyResolver) {
this.propertyResolver = propertyResolver;
}
@Inject
public void setConstructorResolver(JavaConstructorResolver constructorResolver) {
this.constructorResolver = constructorResolver;
}
@Nullable
public ClassDescriptor resolveClass(@NotNull FqName qualifiedName, @NotNull DescriptorSearchRule searchRule) {
return classResolver.resolveClass(qualifiedName, searchRule);
}
@NotNull
public Set<FunctionDescriptor> resolveFunctionGroupForClass(@NotNull NamedMembers members, @NotNull ClassOrPackageFragmentDescriptor owner) {
return functionResolver.resolveFunctionGroupForClass(members, owner);
}
@NotNull
public Set<VariableDescriptor> resolveFieldGroup(@NotNull NamedMembers members, @NotNull ClassOrPackageFragmentDescriptor ownerDescriptor) {
return propertyResolver.resolveFieldGroup(members, ownerDescriptor);
}
@NotNull
public Collection<ConstructorDescriptor> resolveConstructors(@NotNull JavaClass javaClass, @NotNull ClassDescriptor classDescriptor) {
return constructorResolver.resolveConstructors(javaClass, classDescriptor);
}
}
@@ -1,191 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.resolver;
import com.google.common.collect.Maps;
import com.intellij.util.NullableFunction;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor;
import org.jetbrains.jet.lang.resolve.java.JavaClassFinder;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils;
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaPackageFragmentDescriptor;
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaPackageFragmentDescriptorImpl;
import org.jetbrains.jet.lang.resolve.java.scope.JavaClassStaticMembersScope;
import org.jetbrains.jet.lang.resolve.java.scope.JavaFullPackageScope;
import org.jetbrains.jet.lang.resolve.java.scope.JavaPackageFragmentScope;
import org.jetbrains.jet.lang.resolve.java.scope.JavaPurePackageScope;
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
import org.jetbrains.jet.lang.resolve.java.structure.JavaPackage;
import org.jetbrains.jet.lang.resolve.kotlin.DeserializedDescriptorResolver;
import org.jetbrains.jet.lang.resolve.kotlin.KotlinClassFinder;
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import javax.inject.Inject;
import java.util.*;
public final class JavaPackageFragmentProviderImpl implements JavaPackageFragmentProvider {
@NotNull
private final Map<FqName, JavaPackageFragmentDescriptorImpl> packageFragments = Maps.newHashMap();
private JavaDescriptorResolver javaDescriptorResolver;
private JavaClassFinder javaClassFinder;
private JavaResolverCache cache;
private JavaMemberResolver memberResolver;
private DeserializedDescriptorResolver deserializedDescriptorResolver;
private KotlinClassFinder kotlinClassFinder;
private ModuleDescriptor module;
@Inject
public void setJavaDescriptorResolver(@NotNull JavaDescriptorResolver javaDescriptorResolver) {
this.javaDescriptorResolver = javaDescriptorResolver;
}
@Inject
public void setKotlinClassFinder(KotlinClassFinder kotlinClassFinder) {
this.kotlinClassFinder = kotlinClassFinder;
}
@Inject
public void setJavaClassFinder(JavaClassFinder javaClassFinder) {
this.javaClassFinder = javaClassFinder;
}
@Inject
public void setCache(JavaResolverCache cache) {
this.cache = cache;
}
@Inject
public void setMemberResolver(@NotNull JavaMemberResolver memberResolver) {
this.memberResolver = memberResolver;
}
@Inject
public void setDeserializedDescriptorResolver(DeserializedDescriptorResolver deserializedDescriptorResolver) {
this.deserializedDescriptorResolver = deserializedDescriptorResolver;
}
@Inject
public void setModule(ModuleDescriptor module) {
this.module = module;
}
@Override
@NotNull
public JavaDescriptorResolver getJavaDescriptorResolver() {
return javaDescriptorResolver;
}
@NotNull
@Override
public List<PackageFragmentDescriptor> getPackageFragments(@NotNull FqName fqName) {
return ContainerUtil.<PackageFragmentDescriptor>createMaybeSingletonList(getPackageFragment(fqName));
}
@NotNull
@Override
public Collection<FqName> getSubPackagesOf(@NotNull FqName fqName) {
JavaPackageFragmentDescriptorImpl packageFragment = getPackageFragment(fqName);
if (packageFragment == null) {
return Collections.emptyList();
}
return packageFragment.getMemberScope().getSubPackages();
}
@Override
@Nullable
public JavaPackageFragmentDescriptorImpl getPackageFragment(@NotNull final FqName fqName) {
if (packageFragments.containsKey(fqName)) {
return packageFragments.get(fqName);
}
JavaPackageFragmentDescriptorImpl packageFragment = JavaPackageFragmentDescriptorImpl.create(
this, fqName, new NullableFunction<JavaPackageFragmentDescriptor, JavaPackageFragmentScope>() {
@Override
@Nullable
public JavaPackageFragmentScope fun(JavaPackageFragmentDescriptor packageFragment) {
return createPackageScope(fqName, packageFragment);
}
});
packageFragments.put(fqName, packageFragment);
return packageFragment;
}
@Nullable
private JavaPackageFragmentScope createPackageScope(
@NotNull FqName fqName,
@NotNull PackageFragmentDescriptor packageFragment
) {
JavaPackage javaPackage = javaClassFinder.findPackage(fqName);
if (javaPackage != null) {
FqName packageClassFqName = PackageClassUtils.getPackageClassFqName(fqName);
KotlinJvmBinaryClass kotlinClass = kotlinClassFinder.findKotlinClass(packageClassFqName);
if (kotlinClass != null) {
JetScope kotlinPackageScope = deserializedDescriptorResolver.createKotlinPackageScope(packageFragment, kotlinClass);
if (kotlinPackageScope != null) {
return new JavaFullPackageScope(packageFragment, kotlinPackageScope,
new JavaPurePackageScope(packageFragment, javaPackage, fqName, memberResolver,
/* includeCompiledKotlinClasses = */ false));
}
}
return new JavaPurePackageScope(packageFragment, javaPackage, fqName, memberResolver,
/* includeCompiledKotlinClasses = */ true);
}
JavaClass javaClass = javaClassFinder.findClass(fqName);
if (javaClass != null && DescriptorResolverUtils.isJavaClassVisibleAsPackage(javaClass)) {
return new JavaClassStaticMembersScope(packageFragment, javaClass, memberResolver);
}
return null;
}
@Override
@NotNull
public Collection<Name> getClassNamesInPackage(@NotNull FqName packageName) {
JavaPackage javaPackage = javaClassFinder.findPackage(packageName);
if (javaPackage == null) return Collections.emptyList();
Collection<JavaClass> classes = DescriptorResolverUtils.getClassesInPackage(javaPackage);
List<Name> result = new ArrayList<Name>(classes.size());
for (JavaClass javaClass : classes) {
if (!DescriptorResolverUtils.isCompiledKotlinPackageClass(javaClass)) {
result.add(javaClass.getName());
}
}
return result;
}
@Override
@NotNull
public ModuleDescriptor getModule() {
return module;
}
}
@@ -1,146 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.resolver;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.impl.PropertyDescriptorImpl;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaPropertyDescriptor;
import org.jetbrains.jet.lang.resolve.java.scope.NamedMembers;
import org.jetbrains.jet.lang.resolve.java.structure.JavaField;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import javax.inject.Inject;
import java.util.*;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isEnumClassObject;
import static org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils.resolveOverrides;
public final class JavaPropertyResolver {
private JavaTypeTransformer typeTransformer;
private JavaResolverCache cache;
private JavaAnnotationResolver annotationResolver;
private ExternalSignatureResolver externalSignatureResolver;
private ErrorReporter errorReporter;
@Inject
public void setTypeTransformer(@NotNull JavaTypeTransformer javaTypeTransformer) {
this.typeTransformer = javaTypeTransformer;
}
@Inject
public void setCache(JavaResolverCache cache) {
this.cache = cache;
}
@Inject
public void setAnnotationResolver(JavaAnnotationResolver annotationResolver) {
this.annotationResolver = annotationResolver;
}
@Inject
public void setExternalSignatureResolver(ExternalSignatureResolver externalSignatureResolver) {
this.externalSignatureResolver = externalSignatureResolver;
}
@Inject
public void setErrorReporter(ErrorReporter errorReporter) {
this.errorReporter = errorReporter;
}
@NotNull
public Set<VariableDescriptor> resolveFieldGroup(@NotNull NamedMembers members, @NotNull ClassOrPackageFragmentDescriptor owner) {
if (isEnumClassObject(owner)) {
return Collections.emptySet();
}
Name propertyName = members.getName();
List<JavaField> fields = members.getFields();
Set<PropertyDescriptor> propertiesFromCurrent = new HashSet<PropertyDescriptor>(1);
assert fields.size() <= 1;
if (fields.size() == 1) {
JavaField field = fields.iterator().next();
if (!field.isEnumEntry()) {
propertiesFromCurrent.add(resolveProperty(owner, propertyName, field));
}
}
Set<PropertyDescriptor> properties = new HashSet<PropertyDescriptor>();
if (owner instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) owner;
Collection<PropertyDescriptor> propertiesFromSupertypes = getPropertiesFromSupertypes(propertyName, classDescriptor);
properties.addAll(resolveOverrides(propertyName, propertiesFromSupertypes, propertiesFromCurrent, classDescriptor,
errorReporter));
}
properties.addAll(propertiesFromCurrent);
return new HashSet<VariableDescriptor>(properties);
}
@NotNull
private PropertyDescriptor resolveProperty(@NotNull ClassOrPackageFragmentDescriptor owner, @NotNull Name name, @NotNull JavaField field) {
assert !field.isEnumEntry() : "Enum entries are resolved into classes, not into properties: " + name;
boolean isVar = !field.isFinal();
PropertyDescriptorImpl propertyDescriptor =
new JavaPropertyDescriptor(owner, annotationResolver.resolveAnnotations(field), field.getVisibility(), isVar, name);
propertyDescriptor.initialize(null, null);
TypeVariableResolver typeVariableResolver =
new TypeVariableResolverImpl(Collections.<TypeParameterDescriptor>emptyList(), propertyDescriptor);
JetType propertyType = getPropertyType(field, typeVariableResolver);
ExternalSignatureResolver.AlternativeFieldSignature effectiveSignature =
externalSignatureResolver.resolveAlternativeFieldSignature(field, propertyType, isVar);
List<String> signatureErrors = effectiveSignature.getErrors();
if (!signatureErrors.isEmpty()) {
externalSignatureResolver.reportSignatureErrors(propertyDescriptor, signatureErrors);
}
propertyDescriptor.setType(
effectiveSignature.getReturnType(),
Collections.<TypeParameterDescriptor>emptyList(),
DescriptorUtils.getExpectedThisObjectIfNeeded(owner),
(JetType) null
);
cache.recordField(field, propertyDescriptor);
return propertyDescriptor;
}
@NotNull
private JetType getPropertyType(@NotNull JavaField field, @NotNull TypeVariableResolver typeVariableResolver) {
JetType propertyType = typeTransformer.transformToType(field.getType(), typeVariableResolver);
if (annotationResolver.hasNotNullAnnotation(field) || isStaticFinalField(field) /* TODO: WTF? */) {
return TypeUtils.makeNotNullable(propertyType);
}
return propertyType;
}
}
@@ -1,100 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.resolver;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
import org.jetbrains.jet.lang.resolve.java.structure.JavaClassifierType;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.IGNORE_KOTLIN_SOURCES;
public final class JavaSupertypeResolver {
private JavaTypeTransformer typeTransformer;
private JavaClassResolver classResolver;
@Inject
public void setTypeTransformer(JavaTypeTransformer typeTransformer) {
this.typeTransformer = typeTransformer;
}
@Inject
public void setClassResolver(JavaClassResolver classResolver) {
this.classResolver = classResolver;
}
@NotNull
public Collection<JetType> getSupertypes(
@NotNull ClassDescriptor classDescriptor,
@NotNull JavaClass javaClass,
@NotNull List<TypeParameterDescriptor> typeParameters
) {
TypeVariableResolver typeVariableResolver = new TypeVariableResolverImpl(typeParameters, classDescriptor);
List<JetType> result = transformSupertypeList(javaClass.getSupertypes(), typeVariableResolver);
return result.isEmpty() ? Collections.singletonList(getDefaultSupertype(javaClass)) : result;
}
@NotNull
private JetType getDefaultSupertype(@NotNull JavaClass javaClass) {
if (OBJECT_FQ_NAME.equals(javaClass.getFqName()) || javaClass.isAnnotationType()) {
return KotlinBuiltIns.getInstance().getAnyType();
}
else {
ClassDescriptor object = classResolver.resolveClass(OBJECT_FQ_NAME, IGNORE_KOTLIN_SOURCES);
if (object != null) {
return object.getDefaultType();
}
else {
//TODO: hack here
return KotlinBuiltIns.getInstance().getAnyType();
// throw new IllegalStateException("Could not resolve java.lang.Object");
}
}
}
@NotNull
private List<JetType> transformSupertypeList(
@NotNull Collection<JavaClassifierType> supertypes,
@NotNull TypeVariableResolver typeVariableResolver
) {
List<JetType> result = new ArrayList<JetType>(supertypes.size());
for (JavaClassifierType type : supertypes) {
JetType transformed = typeTransformer.transformToType(type, TypeUsage.SUPERTYPE, typeVariableResolver);
if (transformed.isError()) {
// TODO: report INCOMPLETE_HIERARCHY
}
else {
result.add(TypeUtils.makeNotNullable(transformed));
}
}
return result;
}
}
@@ -1,107 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.resolver;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl;
import org.jetbrains.jet.lang.resolve.java.structure.JavaClassifierType;
import org.jetbrains.jet.lang.resolve.java.structure.JavaTypeParameter;
import org.jetbrains.jet.lang.resolve.java.structure.JavaTypeParameterListOwner;
import org.jetbrains.jet.lang.types.Variance;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
public final class JavaTypeParameterResolver {
@NotNull
private JavaTypeTransformer typeTransformer;
@Inject
public void setTypeTransformer(@NotNull JavaTypeTransformer javaTypeTransformer) {
this.typeTransformer = javaTypeTransformer;
}
@NotNull
public Initializer resolveTypeParameters(
@NotNull DeclarationDescriptor ownerDescriptor,
@NotNull JavaTypeParameterListOwner typeParameterListOwner
) {
Initializer result = new Initializer(ownerDescriptor);
for (JavaTypeParameter typeParameter : typeParameterListOwner.getTypeParameters()) {
result.addTypeParameter(typeParameter);
}
return result;
}
public class Initializer {
private final DeclarationDescriptor owner;
private final List<TypeParameterDescriptor> descriptors = new ArrayList<TypeParameterDescriptor>();
private final List<JavaTypeParameter> javaTypeParameters = new ArrayList<JavaTypeParameter>();
private Initializer(@NotNull DeclarationDescriptor owner) {
this.owner = owner;
}
private void addTypeParameter(@NotNull JavaTypeParameter typeParameter) {
TypeParameterDescriptorImpl descriptor = TypeParameterDescriptorImpl.createForFurtherModification(
owner,
Annotations.EMPTY, // TODO
false,
Variance.INVARIANT,
typeParameter.getName(),
typeParameter.getIndex()
);
descriptors.add(descriptor);
javaTypeParameters.add(typeParameter);
}
@NotNull
public List<TypeParameterDescriptor> getDescriptors() {
return descriptors;
}
public void initialize() {
TypeVariableResolver typeVariableResolver = new TypeVariableResolverImpl(getDescriptors(), owner);
Iterator<TypeParameterDescriptor> descriptorIterator = descriptors.iterator();
Iterator<JavaTypeParameter> typeParameterIterator = javaTypeParameters.iterator();
while (descriptorIterator.hasNext()) {
TypeParameterDescriptorImpl descriptor = (TypeParameterDescriptorImpl) descriptorIterator.next();
Collection<JavaClassifierType> upperBounds = typeParameterIterator.next().getUpperBounds();
if (upperBounds.isEmpty()) {
descriptor.addUpperBound(KotlinBuiltIns.getInstance().getDefaultBound());
}
else {
for (JavaClassifierType upperBound : upperBounds) {
descriptor.addUpperBound(typeTransformer.transformToType(upperBound, TypeUsage.UPPER_BOUND, typeVariableResolver));
}
}
descriptor.setInitialized();
}
}
}
}
@@ -1,278 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.resolver;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap;
import org.jetbrains.jet.lang.resolve.java.structure.*;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import javax.inject.Inject;
import java.util.*;
import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.INCLUDE_KOTLIN_SOURCES;
import static org.jetbrains.jet.lang.resolve.java.resolver.TypeUsage.*;
import static org.jetbrains.jet.lang.types.Variance.*;
public class JavaTypeTransformer {
private JavaClassResolver classResolver;
@Inject
public void setClassResolver(JavaClassResolver classResolver) {
this.classResolver = classResolver;
}
@NotNull
private TypeProjection transformToTypeProjection(
@NotNull JavaType type,
@NotNull TypeParameterDescriptor typeParameterDescriptor,
@NotNull TypeVariableResolver typeVariableResolver,
@NotNull TypeUsage howThisTypeIsUsed
) {
if (!(type instanceof JavaWildcardType)) {
return new TypeProjectionImpl(transformToType(type, howThisTypeIsUsed, typeVariableResolver));
}
JavaWildcardType wildcardType = (JavaWildcardType) type;
JavaType bound = wildcardType.getBound();
if (bound == null) {
return SubstitutionUtils.makeStarProjection(typeParameterDescriptor);
}
Variance variance = wildcardType.isExtends() ? OUT_VARIANCE : IN_VARIANCE;
return new TypeProjectionImpl(variance, transformToType(bound, UPPER_BOUND, typeVariableResolver));
}
@NotNull
public JetType transformToType(@NotNull JavaType type, @NotNull TypeVariableResolver typeVariableResolver) {
return transformToType(type, TypeUsage.MEMBER_SIGNATURE_INVARIANT, typeVariableResolver);
}
@NotNull
public JetType transformToType(
@NotNull JavaType type,
@NotNull TypeUsage howThisTypeIsUsed,
@NotNull TypeVariableResolver typeVariableResolver
) {
if (type instanceof JavaClassifierType) {
JavaClassifierType classifierType = (JavaClassifierType) type;
return transformClassifierType(classifierType, howThisTypeIsUsed, typeVariableResolver);
}
else if (type instanceof JavaPrimitiveType) {
String canonicalText = ((JavaPrimitiveType) type).getCanonicalText();
JetType jetType = JavaToKotlinClassMap.getInstance().mapPrimitiveKotlinClass(canonicalText);
assert jetType != null : "Primitive type is not found: " + canonicalText;
return jetType;
}
else if (type instanceof JavaArrayType) {
return transformArrayType((JavaArrayType) type, howThisTypeIsUsed, typeVariableResolver, false);
}
else {
throw new UnsupportedOperationException("Unsupported type: " + type); // TODO
}
}
@NotNull
private JetType transformClassifierType(
@NotNull JavaClassifierType classifierType,
@NotNull TypeUsage howThisTypeIsUsed,
@NotNull TypeVariableResolver typeVariableResolver
) {
JavaClassifier javaClassifier = classifierType.getClassifier();
if (javaClassifier instanceof JavaTypeParameter) {
return transformTypeParameter((JavaTypeParameter) javaClassifier, classifierType, howThisTypeIsUsed, typeVariableResolver);
}
else {
return transformClassType(javaClassifier, classifierType, howThisTypeIsUsed, typeVariableResolver);
}
}
@NotNull
private JetType transformTypeParameter(
@NotNull JavaTypeParameter typeParameter,
@NotNull JavaClassifierType classifierType,
@NotNull TypeUsage howThisTypeIsUsed,
@NotNull TypeVariableResolver typeVariableResolver
) {
// In Java: ArrayList<T>
// In Kotlin: ArrayList<T>, not ArrayList<T?>
// nullability will be taken care of in individual member signatures
boolean nullable = !EnumSet.of(TYPE_ARGUMENT, UPPER_BOUND, SUPERTYPE_ARGUMENT).contains(howThisTypeIsUsed);
JavaTypeParameterListOwner owner = typeParameter.getOwner();
if (owner instanceof JavaMethod && ((JavaMethod) owner).isConstructor()) {
Set<JetType> supertypesJet = new HashSet<JetType>();
for (JavaClassifierType supertype : typeParameter.getUpperBounds()) {
supertypesJet.add(transformToType(supertype, UPPER_BOUND, typeVariableResolver));
}
JetType intersection = TypeUtils.intersect(JetTypeChecker.INSTANCE, supertypesJet);
if (intersection == null) {
return createErrorClassifierType(classifierType, nullable);
}
return intersection;
}
TypeParameterDescriptor descriptor = typeVariableResolver.getTypeVariable(typeParameter.getName());
if (descriptor == null) return createErrorClassifierType(classifierType, nullable);
return TypeUtils.makeNullableIfNeeded(descriptor.getDefaultType(), nullable);
}
@NotNull
private JetType transformClassType(
@Nullable JavaClassifier javaClassifier,
@NotNull JavaClassifierType classifierType,
@NotNull TypeUsage howThisTypeIsUsed,
@NotNull TypeVariableResolver typeVariableResolver
) {
// 'L extends List<T>' in Java is a List<T> in Kotlin, not a List<T?>
boolean nullable = !EnumSet.of(TYPE_ARGUMENT, SUPERTYPE_ARGUMENT, SUPERTYPE).contains(howThisTypeIsUsed);
if (javaClassifier == null) return createErrorClassifierType(classifierType, nullable);
FqName fqName = ((JavaClass) javaClassifier).getFqName();
assert fqName != null : "Class type should have a FQ name: " + javaClassifier;
ClassDescriptor classData = JavaToKotlinClassMap.getInstance().mapKotlinClass(fqName, howThisTypeIsUsed);
if (classData == null) {
classData = classResolver.resolveClass(fqName, INCLUDE_KOTLIN_SOURCES);
}
if (classData == null) {
return createErrorClassifierType(classifierType, nullable);
}
List<TypeProjection> arguments = new ArrayList<TypeProjection>();
List<TypeParameterDescriptor> parameters = classData.getTypeConstructor().getParameters();
if (isRaw(classifierType, !parameters.isEmpty())) {
for (TypeParameterDescriptor parameter : parameters) {
// not making a star projection because of this case:
// Java:
// class C<T extends C> {}
// The upper bound is raw here, and we can't compute the projection: it would be infinite:
// C<*> = C<out C<out C<...>>>
// this way we loose some type information, even when the case is not so bad, but it doesn't seem to matter
// projections are not allowed in immediate arguments of supertypes
Variance projectionKind = parameter.getVariance() == OUT_VARIANCE || howThisTypeIsUsed == SUPERTYPE
? INVARIANT
: OUT_VARIANCE;
arguments.add(new TypeProjectionImpl(projectionKind, KotlinBuiltIns.getInstance().getNullableAnyType()));
}
}
else {
List<JavaType> javaTypeArguments = classifierType.getTypeArguments();
if (parameters.size() != javaTypeArguments.size()) {
// Most of the time this means there is an error in the Java code
for (TypeParameterDescriptor parameter : parameters) {
arguments.add(new TypeProjectionImpl(ErrorUtils.createErrorType(parameter.getName().asString())));
}
}
else {
for (int i = 0, size = javaTypeArguments.size(); i < size; i++) {
JavaType typeArgument = javaTypeArguments.get(i);
TypeParameterDescriptor typeParameterDescriptor = parameters.get(i);
TypeUsage howTheProjectionIsUsed = howThisTypeIsUsed == SUPERTYPE ? SUPERTYPE_ARGUMENT : TYPE_ARGUMENT;
TypeProjection typeProjection =
transformToTypeProjection(typeArgument, typeParameterDescriptor, typeVariableResolver, howTheProjectionIsUsed);
if (typeProjection.getProjectionKind() == typeParameterDescriptor.getVariance()) {
// remove redundant 'out' and 'in'
arguments.add(new TypeProjectionImpl(INVARIANT, typeProjection.getType()));
}
else {
arguments.add(typeProjection);
}
}
}
}
return new JetTypeImpl(
Annotations.EMPTY,
classData.getTypeConstructor(),
nullable,
arguments,
classData.getMemberScope(arguments));
}
@NotNull
private static JetType createErrorClassifierType(JavaClassifierType classifierType, boolean nullable) {
return TypeUtils.makeNullableAsSpecified(
ErrorUtils.createErrorType("Unresolved java classifier: " + classifierType.getPresentableText()),
nullable
);
}
@NotNull
private JetType transformArrayType(
@NotNull JavaArrayType arrayType,
@NotNull TypeUsage howThisTypeIsUsed,
@NotNull TypeVariableResolver typeVariableResolver,
boolean vararg
) {
JavaType componentType = arrayType.getComponentType();
if (componentType instanceof JavaPrimitiveType) {
JetType jetType = JavaToKotlinClassMap.getInstance().mapPrimitiveKotlinClass(
"[" + ((JavaPrimitiveType) componentType).getCanonicalText());
if (jetType != null) {
return TypeUtils.makeNullable(jetType);
}
}
Variance projectionKind = arrayElementTypeProjectionKind(howThisTypeIsUsed, vararg);
TypeUsage howArgumentTypeIsUsed = vararg ? MEMBER_SIGNATURE_CONTRAVARIANT : TYPE_ARGUMENT;
JetType type = transformToType(componentType, howArgumentTypeIsUsed, typeVariableResolver);
return TypeUtils.makeNullable(KotlinBuiltIns.getInstance().getArrayType(projectionKind, type));
}
@NotNull
private static Variance arrayElementTypeProjectionKind(@NotNull TypeUsage howThisTypeIsUsed, boolean vararg) {
if (howThisTypeIsUsed == MEMBER_SIGNATURE_CONTRAVARIANT && !vararg) {
return OUT_VARIANCE;
}
else {
return INVARIANT;
}
}
@NotNull
public JetType transformVarargType(
@NotNull JavaArrayType type,
@NotNull TypeUsage howThisTypeIsUsed,
@NotNull TypeVariableResolver typeVariableResolver
) {
return transformArrayType(type, howThisTypeIsUsed, typeVariableResolver, true);
}
private static boolean isRaw(@NotNull JavaClassifierType classifierType, boolean argumentsExpected) {
// The second option is needed because sometimes we get weird versions of JDK classes in the class path,
// such as collections with no generics, so the Java types are not raw, formally, but they don't match with
// their Kotlin analogs, so we treat them as raw to avoid exceptions
return classifierType.isRaw() || argumentsExpected && classifierType.getTypeArguments().isEmpty();
}
}
@@ -1,113 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.resolver;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl;
import org.jetbrains.jet.lang.resolve.java.structure.JavaArrayType;
import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod;
import org.jetbrains.jet.lang.resolve.java.structure.JavaType;
import org.jetbrains.jet.lang.resolve.java.structure.JavaValueParameter;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.TypeUtils;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.List;
public final class JavaValueParameterResolver {
private JavaAnnotationResolver annotationResolver;
private JavaTypeTransformer typeTransformer;
@Inject
public void setAnnotationResolver(JavaAnnotationResolver annotationResolver) {
this.annotationResolver = annotationResolver;
}
@Inject
public void setTypeTransformer(JavaTypeTransformer typeTransformer) {
this.typeTransformer = typeTransformer;
}
@NotNull
private ValueParameterDescriptor resolveValueParameter(
@NotNull DeclarationDescriptor containingDeclaration,
int i,
@NotNull JavaValueParameter parameter,
@NotNull TypeVariableResolver typeVariableResolver
) {
TypeUsage typeUsage = annotationResolver.hasMutableAnnotation(parameter)
? TypeUsage.MEMBER_SIGNATURE_COVARIANT
: TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT;
JavaType parameterType = parameter.getType();
JetType varargElementType;
JetType outType;
if (parameter.isVararg()) {
// TODO: test this code
assert parameterType instanceof JavaArrayType : "Vararg parameter should be an array: " + parameterType;
JetType arrayType = typeTransformer.transformVarargType(((JavaArrayType) parameterType), typeUsage, typeVariableResolver);
outType = TypeUtils.makeNotNullable(arrayType);
varargElementType = KotlinBuiltIns.getInstance().getArrayElementType(outType);
}
else {
JetType transformedType = typeTransformer.transformToType(parameterType, typeUsage, typeVariableResolver);
if (transformedType.isNullable() && annotationResolver.hasNotNullAnnotation(parameter)) {
transformedType = TypeUtils.makeNotNullable(transformedType);
}
outType = transformedType;
varargElementType = null;
}
return new ValueParameterDescriptorImpl(
containingDeclaration,
i,
annotationResolver.resolveAnnotations(parameter),
getParameterName(i, parameter), // TODO: must be very slow, make it lazy?
outType,
false,
varargElementType
);
}
@NotNull
private static Name getParameterName(int number, @NotNull JavaValueParameter parameter) {
Name psiParameterName = parameter.getName();
return psiParameterName != null ? psiParameterName : Name.identifier("p" + number);
}
@NotNull
public List<ValueParameterDescriptor> resolveValueParameters(
@NotNull DeclarationDescriptor container,
@NotNull JavaMethod method,
@NotNull TypeVariableResolver typeVariableResolver
) {
List<JavaValueParameter> parameters = method.getValueParameters();
List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(parameters.size());
for (int i = 0, size = parameters.size(); i < size; i++) {
result.add(resolveValueParameter(container, i, parameters.get(i), typeVariableResolver));
}
return result;
}
}
@@ -1,38 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.resolver;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public final class PostponedTasks {
@NotNull
private final List<Runnable> tasks = new ArrayList<Runnable>();
public void addTask(@NotNull Runnable runnable) {
tasks.add(runnable);
}
public void performTasks() {
for (Runnable task : tasks) {
task.run();
}
}
}
@@ -1,39 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.resolver;
import org.jetbrains.annotations.NotNull;
import java.util.Iterator;
import java.util.ServiceLoader;
public abstract class ProgressChecker {
private static ProgressChecker instance;
@NotNull
public static ProgressChecker getInstance() {
if (instance == null) {
Iterator<ProgressChecker> iterator =
ServiceLoader.load(ProgressChecker.class, ProgressChecker.class.getClassLoader()).iterator();
assert iterator.hasNext() : "No service found: " + ProgressChecker.class.getName();
instance = iterator.next();
}
return instance;
}
public abstract void checkCanceled();
}
@@ -1,35 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.resolver;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.resolve.name.Name;
public interface TypeVariableResolver {
TypeVariableResolver EMPTY = new TypeVariableResolver() {
@Nullable
@Override
public TypeParameterDescriptor getTypeVariable(@NotNull Name name) {
return null;
}
};
@Nullable
TypeParameterDescriptor getTypeVariable(@NotNull Name name);
}
@@ -1,75 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.resolver;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.resolve.name.Name;
import java.util.List;
/* package */ class TypeVariableResolverImpl implements TypeVariableResolver {
@NotNull
private final List<TypeParameterDescriptor> typeParameters;
@NotNull
private final DeclarationDescriptor owner;
public TypeVariableResolverImpl(@NotNull List<TypeParameterDescriptor> typeParameters, @NotNull DeclarationDescriptor owner) {
this.typeParameters = typeParameters;
this.owner = owner;
assert parametersBelongToOwner() : "Type parameters should belong to owner: " + owner + "; " + typeParameters;
}
private boolean parametersBelongToOwner() {
for (TypeParameterDescriptor typeParameter : typeParameters) {
if (typeParameter.getContainingDeclaration() != owner) {
return false;
}
}
return true;
}
@Nullable
@Override
public TypeParameterDescriptor getTypeVariable(@NotNull Name name) {
return getTypeVariable(name, typeParameters, owner);
}
@Nullable
private static TypeParameterDescriptor getTypeVariable(
@NotNull Name name,
@NotNull List<TypeParameterDescriptor> typeParameters,
@NotNull DeclarationDescriptor owner
) {
for (TypeParameterDescriptor typeParameter : typeParameters) {
if (typeParameter.getName().equals(name)) {
return typeParameter;
}
}
DeclarationDescriptor container = owner.getContainingDeclaration();
if (container instanceof ClassDescriptor) {
return getTypeVariable(name, ((ClassDescriptor) container).getTypeConstructor().getParameters(), container);
}
return null;
}
}
@@ -1,165 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.scope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaMemberResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.ProgressChecker;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScopeImpl;
import org.jetbrains.jet.utils.Printer;
import java.util.*;
public abstract class JavaBaseScope extends JetScopeImpl {
@NotNull
protected final JavaMemberResolver memberResolver;
@NotNull
protected final MembersProvider membersProvider;
@NotNull
private final Map<Name, Set<FunctionDescriptor>> functionDescriptors = new HashMap<Name, Set<FunctionDescriptor>>();
@NotNull
private final Map<Name, Set<VariableDescriptor>> propertyDescriptors = new HashMap<Name, Set<VariableDescriptor>>();
@Nullable
private Collection<DeclarationDescriptor> allDescriptors = null;
@NotNull
protected final ClassOrPackageFragmentDescriptor descriptor;
private Collection<ClassDescriptor> innerClasses = null;
protected JavaBaseScope(
@NotNull ClassOrPackageFragmentDescriptor descriptor,
@NotNull JavaMemberResolver memberResolver,
@NotNull MembersProvider membersProvider
) {
this.memberResolver = memberResolver;
this.membersProvider = membersProvider;
this.descriptor = descriptor;
}
@NotNull
@Override
public DeclarationDescriptor getContainingDeclaration() {
return descriptor;
}
@NotNull
@Override
public Collection<VariableDescriptor> getProperties(@NotNull Name name) {
Set<VariableDescriptor> cached = propertyDescriptors.get(name);
if (cached != null) return cached;
if (allDescriptorsComputed()) {
return Collections.emptySet();
}
Set<VariableDescriptor> computedDescriptors = computePropertyDescriptors(name);
propertyDescriptors.put(name, computedDescriptors);
return computedDescriptors;
}
@NotNull
private Set<VariableDescriptor> computePropertyDescriptors(@NotNull Name name) {
NamedMembers members = membersProvider.get(name);
if (members == null) {
return Collections.emptySet();
}
return memberResolver.resolveFieldGroup(members, descriptor);
}
@NotNull
@Override
public Collection<FunctionDescriptor> getFunctions(@NotNull Name name) {
Set<FunctionDescriptor> cached = functionDescriptors.get(name);
if (cached != null) return cached;
if (allDescriptorsComputed()) {
return Collections.emptySet();
}
Set<FunctionDescriptor> computedDescriptors = computeFunctionDescriptor(name);
functionDescriptors.put(name, computedDescriptors);
return computedDescriptors;
}
@NotNull
protected abstract Set<FunctionDescriptor> computeFunctionDescriptor(@NotNull Name name);
@NotNull
@Override
public Collection<DeclarationDescriptor> getAllDescriptors() {
if (allDescriptorsComputed()) {
return allDescriptors;
}
allDescriptors = computeAllDescriptors();
return allDescriptors;
}
private boolean allDescriptorsComputed() {
return allDescriptors != null;
}
@NotNull
protected Collection<DeclarationDescriptor> computeAllDescriptors() {
Collection<DeclarationDescriptor> result = new HashSet<DeclarationDescriptor>();
result.addAll(computeFieldAndFunctionDescriptors());
result.addAll(getInnerClasses());
return result;
}
@NotNull
protected abstract Collection<ClassDescriptor> computeInnerClasses();
@NotNull
private Collection<DeclarationDescriptor> computeFieldAndFunctionDescriptors() {
Collection<DeclarationDescriptor> result = new ArrayList<DeclarationDescriptor>();
for (NamedMembers members : membersProvider.allMembers()) {
Name name = members.getName();
ProgressChecker.getInstance().checkCanceled();
result.addAll(getFunctions(name));
ProgressChecker.getInstance().checkCanceled();
result.addAll(getProperties(name));
}
return result;
}
@NotNull
protected Collection<ClassDescriptor> getInnerClasses() {
if (innerClasses == null) {
innerClasses = computeInnerClasses();
}
return innerClasses;
}
@TestOnly
@Override
public void printScopeStructure(@NotNull Printer p) {
p.println(getClass().getSimpleName(), " {");
p.pushIndent();
p.println("descriptor = ", descriptor);
p.popIndent();
p.println("}");
}
}
@@ -1,66 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.scope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaMemberResolver;
import org.jetbrains.jet.lang.resolve.name.LabelName;
import org.jetbrains.jet.lang.resolve.name.Name;
import java.util.*;
public abstract class JavaClassMembersScope extends JavaBaseScope {
private Map<Name, ClassDescriptor> innerClassesMap = null;
protected JavaClassMembersScope(
@NotNull ClassOrPackageFragmentDescriptor descriptor,
@NotNull MembersProvider membersProvider,
@NotNull JavaMemberResolver memberResolver
) {
super(descriptor, memberResolver, membersProvider);
}
@NotNull
@Override
public Collection<DeclarationDescriptor> getDeclarationsByLabel(@NotNull LabelName labelName) {
throw new UnsupportedOperationException(); // TODO
}
@NotNull
@Override
protected Set<FunctionDescriptor> computeFunctionDescriptor(@NotNull Name name) {
NamedMembers members = membersProvider.get(name);
if (members == null) {
return Collections.emptySet();
}
return memberResolver.resolveFunctionGroupForClass(members, descriptor);
}
@Override
public ClassifierDescriptor getClassifier(@NotNull Name name) {
if (innerClassesMap == null) {
Collection<ClassDescriptor> innerClasses = getInnerClasses();
innerClassesMap = new HashMap<Name, ClassDescriptor>();
for (ClassDescriptor innerClass : innerClasses) {
innerClassesMap.put(innerClass.getName(), innerClass);
}
}
return innerClassesMap.get(name);
}
}
@@ -1,118 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.scope;
import jet.Function0;
import jet.Function1;
import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.EnumEntrySyntheticClassDescriptor;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaMemberResolver;
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
import org.jetbrains.jet.lang.resolve.java.structure.JavaField;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.storage.LockBasedStorageManager;
import org.jetbrains.jet.storage.NotNullLazyValue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isEnumClass;
import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.IGNORE_KOTLIN_SOURCES;
public final class JavaClassNonStaticMembersScope extends JavaClassMembersScope {
@NotNull
private final ClassDescriptor descriptor;
@NotNull
private final JavaClass javaClass;
public JavaClassNonStaticMembersScope(
@NotNull ClassDescriptor descriptor,
@NotNull JavaClass javaClass,
@NotNull JavaMemberResolver memberResolver
) {
super(descriptor, MembersProvider.forClass(javaClass, false), memberResolver);
this.descriptor = descriptor;
this.javaClass = javaClass;
}
@NotNull
public Collection<ConstructorDescriptor> getConstructors() {
return memberResolver.resolveConstructors(javaClass, descriptor);
}
@NotNull
@Override
protected Collection<ClassDescriptor> computeInnerClasses() {
Collection<JavaClass> innerClasses = javaClass.getInnerClasses();
List<ClassDescriptor> result = new ArrayList<ClassDescriptor>(innerClasses.size());
for (JavaClass innerClass : innerClasses) {
result.add(resolveInnerClass(innerClass));
}
if (isEnumClass(descriptor)) {
result.addAll(computeEnumEntries());
}
return result;
}
private Collection<ClassDescriptor> computeEnumEntries() {
List<ClassDescriptor> result = new ArrayList<ClassDescriptor>();
final Collection<NamedMembers> enumNonStaticMembers = MembersProvider.forClass(javaClass, true).allMembers();
NotNullLazyValue<Collection<Name>> enumMemberNames =
LockBasedStorageManager.NO_LOCKS.createLazyValue(new Function0<Collection<Name>>() {
@Override
public Collection<Name> invoke() {
return KotlinPackage.map(enumNonStaticMembers, new Function1<NamedMembers, Name>() {
@Override
public Name invoke(@NotNull NamedMembers members) {
return members.getName();
}
});
}
});
for (NamedMembers members : enumNonStaticMembers) {
for (JavaField field : members.getFields()) {
if (field.isEnumEntry()) {
EnumEntrySyntheticClassDescriptor enumEntry = EnumEntrySyntheticClassDescriptor
.create(LockBasedStorageManager.NO_LOCKS, descriptor, members.getName(), enumMemberNames);
result.add(enumEntry);
break;
}
}
}
return result;
}
@NotNull
private ClassDescriptor resolveInnerClass(@NotNull JavaClass innerClass) {
FqName fqName = innerClass.getFqName();
assert fqName != null : "Inner class has no qualified name: " + innerClass;
ClassDescriptor classDescriptor = memberResolver.resolveClass(fqName, IGNORE_KOTLIN_SOURCES);
assert classDescriptor != null : "Couldn't resolve inner class " + fqName;
return classDescriptor;
}
}
@@ -1,64 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.scope;
import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor;
import org.jetbrains.jet.lang.descriptors.Visibility;
import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaMemberResolver;
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
import org.jetbrains.jet.lang.resolve.name.FqName;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public final class JavaClassStaticMembersScope extends JavaClassMembersScope implements JavaPackageFragmentScope {
@NotNull
private final JavaClass javaClass;
public JavaClassStaticMembersScope(
@NotNull PackageFragmentDescriptor descriptor,
@NotNull JavaClass javaClass,
@NotNull JavaMemberResolver memberResolver
) {
super(descriptor, MembersProvider.forClass(javaClass, true), memberResolver);
this.javaClass = javaClass;
}
@NotNull
@Override
protected Collection<ClassDescriptor> computeInnerClasses() {
return Collections.emptyList();
}
@Override
@NotNull
public Collection<FqName> getSubPackages() {
List<FqName> result = Lists.newArrayList();
for (JavaClass nested : javaClass.getInnerClasses()) {
if (DescriptorResolverUtils.isJavaClassVisibleAsPackage(nested)) {
result.add(nested.getFqName());
}
}
return result;
}
}
@@ -1,42 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.scope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassOrPackageFragmentDescriptor;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaMemberResolver;
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
import java.util.Collection;
import java.util.Collections;
public class JavaEnumClassObjectScope extends JavaClassMembersScope {
public JavaEnumClassObjectScope(
@NotNull ClassOrPackageFragmentDescriptor descriptor,
@NotNull JavaClass javaClass,
@NotNull JavaMemberResolver memberResolver
) {
super(descriptor, MembersProvider.forClass(javaClass, true), memberResolver);
}
@NotNull
@Override
protected Collection<ClassDescriptor> computeInnerClasses() {
return Collections.emptySet();
}
}
@@ -1,43 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.scope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.scopes.ChainedScope;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import java.util.Collection;
public class JavaFullPackageScope extends ChainedScope implements JavaPackageFragmentScope {
private final JavaPurePackageScope purePackageScope;
public JavaFullPackageScope(
@NotNull PackageFragmentDescriptor packageFragment,
@NotNull JetScope kotlinPackageScope,
@NotNull JavaPurePackageScope purePackageScope
) {
super(packageFragment, "JavaFullPackageScope", kotlinPackageScope, purePackageScope);
this.purePackageScope = purePackageScope;
}
@Override
public Collection<FqName> getSubPackages() {
return purePackageScope.getSubPackages();
}
}
@@ -1,26 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.scope;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import java.util.Collection;
public interface JavaPackageFragmentScope extends JetScope {
Collection<FqName> getSubPackages();
}
@@ -1,145 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.scope;
import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaPackageFragmentDescriptor;
import org.jetbrains.jet.lang.resolve.java.descriptor.SamConstructorDescriptor;
import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaFunctionResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.JavaMemberResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.ProgressChecker;
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
import org.jetbrains.jet.lang.resolve.java.structure.JavaPackage;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import java.util.*;
import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.IGNORE_KOTLIN_SOURCES;
public final class JavaPurePackageScope extends JavaBaseScope implements JavaPackageFragmentScope {
@NotNull
private final JavaPackage javaPackage;
@NotNull
private final FqName packageFQN;
private final boolean includeCompiledKotlinClasses;
private List<FqName> subPackages = null;
private final Object subPackagesLock = new Object();
public JavaPurePackageScope(
@NotNull PackageFragmentDescriptor descriptor,
@NotNull JavaPackage javaPackage,
@NotNull FqName packageFQN,
@NotNull JavaMemberResolver memberResolver,
boolean includeCompiledKotlinClasses
) {
super(descriptor, memberResolver, MembersProvider.forPackage(javaPackage));
this.javaPackage = javaPackage;
this.packageFQN = packageFQN;
this.includeCompiledKotlinClasses = includeCompiledKotlinClasses;
}
@Override
public ClassifierDescriptor getClassifier(@NotNull Name name) {
return memberResolver.resolveClass(packageFQN.child(name), IGNORE_KOTLIN_SOURCES);
}
@NotNull
@Override
protected Collection<DeclarationDescriptor> computeAllDescriptors() {
Collection<DeclarationDescriptor> result = super.computeAllDescriptors();
result.addAll(computeAllPackageDeclarations());
return result;
}
@NotNull
private Collection<DeclarationDescriptor> computeAllPackageDeclarations() {
Collection<DeclarationDescriptor> result = new HashSet<DeclarationDescriptor>();
for (JavaClass javaClass : DescriptorResolverUtils.getClassesInPackage(javaPackage)) {
if (DescriptorResolverUtils.isCompiledKotlinPackageClass(javaClass)) continue;
if (!includeCompiledKotlinClasses && DescriptorResolverUtils.isCompiledKotlinClass(javaClass)) continue;
if (javaClass.getOriginKind() == JavaClass.OriginKind.KOTLIN_LIGHT_CLASS) continue;
if (javaClass.getVisibility() == Visibilities.PRIVATE) continue;
ProgressChecker.getInstance().checkCanceled();
FqName fqName = javaClass.getFqName();
if (fqName == null) continue;
ClassDescriptor classDescriptor = memberResolver.resolveClass(fqName, IGNORE_KOTLIN_SOURCES);
if (classDescriptor != null) {
result.add(classDescriptor);
}
}
return result;
}
@Override
@NotNull
protected Set<FunctionDescriptor> computeFunctionDescriptor(@NotNull Name name) {
NamedMembers members = membersProvider.get(name);
if (members == null) {
return Collections.emptySet();
}
SamConstructorDescriptor samConstructor = JavaFunctionResolver.resolveSamConstructor((JavaPackageFragmentDescriptor) descriptor, members);
if (samConstructor == null) {
return Collections.emptySet();
}
return Collections.<FunctionDescriptor>singleton(samConstructor);
}
@NotNull
@Override
protected Collection<ClassDescriptor> computeInnerClasses() {
return Collections.emptyList();
}
@Override
@NotNull
public Collection<FqName> getSubPackages() {
synchronized (subPackagesLock) {
if (subPackages == null) {
subPackages = Lists.newArrayList(); // Initializing with empty list to avoid infinite recursion
subPackages = computeSubPackages();
}
return subPackages;
}
}
@NotNull
private List<FqName> computeSubPackages() {
List<FqName> result = Lists.newArrayList();
for (JavaPackage subPackage : javaPackage.getSubPackages()) {
result.add(subPackage.getFqName());
}
for (JavaClass javaClass : DescriptorResolverUtils.getClassesInPackage(javaPackage)) {
if (DescriptorResolverUtils.isJavaClassVisibleAsPackage(javaClass)) {
result.add(javaClass.getFqName());
}
}
return result;
}
}
@@ -1,258 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.scope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.Visibilities;
import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils;
import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils;
import org.jetbrains.jet.lang.resolve.java.structure.*;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
/* package */ final class MembersCache {
private final Map<Name, Collection<Runnable>> memberProcessingTasks = new HashMap<Name, Collection<Runnable>>();
private final Map<Name, NamedMembers> namedMembersMap = new HashMap<Name, NamedMembers>();
@Nullable
public NamedMembers get(@NotNull Name name) {
runTasksByName(name);
return namedMembersMap.get(name);
}
@NotNull
public Collection<NamedMembers> allMembers() {
runAllTasks();
memberProcessingTasks.clear();
return namedMembersMap.values();
}
@NotNull
private NamedMembers getOrCreateEmpty(@NotNull JavaNamedElement element) {
Name name = element.getName();
NamedMembers r = namedMembersMap.get(name);
if (r == null) {
r = new NamedMembers(name);
namedMembersMap.put(name, r);
}
return r;
}
private void addTask(@NotNull JavaNamedElement member, @NotNull RunOnce task) {
Name name = member.getName();
Collection<Runnable> tasks = memberProcessingTasks.get(name);
if (tasks == null) {
tasks = new HashSet<Runnable>();
memberProcessingTasks.put(name, tasks);
}
tasks.add(task);
}
private void runTasksByName(Name name) {
if (!memberProcessingTasks.containsKey(name)) return;
Collection<Runnable> tasks = memberProcessingTasks.get(name);
for (Runnable task : tasks) {
task.run();
}
// Delete tasks
tasks.clear();
}
private void runAllTasks() {
for (Collection<Runnable> tasks : memberProcessingTasks.values()) {
for (Runnable task : tasks) {
task.run();
}
}
}
@NotNull
public static MembersCache buildForClass(@NotNull JavaClass javaClass, boolean staticMembers) {
MembersCache membersCache = new MembersCache();
membersCache.new ClassMemberProcessor(javaClass, staticMembers).process();
membersCache.new ExtraPackageMembersProcessor(javaClass.getInnerClasses()).process();
return membersCache;
}
@NotNull
public static MembersCache buildForPackage(@NotNull JavaPackage javaPackage) {
MembersCache membersCache = new MembersCache();
Collection<JavaClass> classes = DescriptorResolverUtils.getClassesInPackage(javaPackage);
membersCache.new ExtraPackageMembersProcessor(classes).process();
return membersCache;
}
private class ExtraPackageMembersProcessor { // 'extra' means that PSI elements for these members are not just top-level classes
@NotNull
private final Collection<JavaClass> javaClasses;
private ExtraPackageMembersProcessor(@NotNull Collection<JavaClass> javaClasses) {
this.javaClasses = javaClasses;
}
private void process() {
for (JavaClass javaClass : javaClasses) {
if (javaClass.getOriginKind() != JavaClass.OriginKind.KOTLIN_LIGHT_CLASS) {
if (SingleAbstractMethodUtils.isSamInterface(javaClass)) {
processSamInterface(javaClass);
}
}
}
}
private void processSamInterface(@NotNull JavaClass javaClass) {
getOrCreateEmpty(javaClass).setSamInterface(javaClass);
}
}
private class ClassMemberProcessor {
@NotNull
private final JavaClass javaClass;
private final boolean staticMembers;
private ClassMemberProcessor(@NotNull JavaClass javaClass, boolean staticMembers) {
this.javaClass = javaClass;
this.staticMembers = staticMembers;
}
private void process() {
processFields();
processMethods();
processNestedClasses();
}
private void processFields() {
for (final JavaField field : javaClass.getAllFields()) {
addTask(field, new RunOnce() {
@Override
public void doRun() {
processField(field);
}
});
}
}
private void processMethods() {
createEntriesForAllMethods();
processOwnMethods();
}
private void createEntriesForAllMethods() {
for (JavaMethod method : javaClass.getAllMethods()) {
getOrCreateEmpty(method);
}
}
private void processOwnMethods() {
for (final JavaMethod method : javaClass.getMethods()) {
addTask(method, new RunOnce() {
@Override
public void doRun() {
processOwnMethod(method);
}
});
}
}
private void processNestedClasses() {
if (!staticMembers) {
return;
}
for (final JavaClass nested : javaClass.getInnerClasses()) {
addTask(nested, new RunOnce() {
@Override
public void doRun() {
processNestedClass(nested);
}
});
}
}
private boolean includeMember(@NotNull JavaMember member) {
if (javaClass.isEnum() && staticMembers) {
return member.isStatic();
}
if (member.isStatic() != staticMembers) {
return false;
}
if (!isInCurrentClass(member)) {
return false;
}
if (member.getVisibility() == Visibilities.PRIVATE) {
return false;
}
if (DescriptorResolverUtils.isObjectMethodInInterface(member)) {
return false;
}
return true;
}
private boolean isInCurrentClass(@NotNull JavaMember member) {
FqName fqName = member.getContainingClass().getFqName();
return fqName != null && fqName.equals(javaClass.getFqName());
}
private void processField(@NotNull JavaField field) {
// group must be created even for excluded field
NamedMembers namedMembers = getOrCreateEmpty(field);
if (includeMember(field)) {
namedMembers.addField(field);
}
}
private void processOwnMethod(@NotNull JavaMethod ownMethod) {
if (includeMember(ownMethod)) {
getOrCreateEmpty(ownMethod).addMethod(ownMethod);
}
}
private void processNestedClass(@NotNull JavaClass nested) {
if (SingleAbstractMethodUtils.isSamInterface(nested)) {
getOrCreateEmpty(nested).setSamInterface(nested);
}
}
}
private static abstract class RunOnce implements Runnable {
private boolean hasRun = false;
@Override
public final void run() {
if (hasRun) return;
hasRun = true;
doRun();
}
protected abstract void doRun();
}
}
@@ -1,77 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.scope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
import org.jetbrains.jet.lang.resolve.java.structure.JavaPackage;
import org.jetbrains.jet.lang.resolve.name.Name;
import java.util.Collection;
/* package */ class MembersProvider {
@Nullable
private final JavaClass javaClass;
@Nullable
private final JavaPackage javaPackage;
private final boolean staticMembers;
private MembersCache membersCache;
private MembersProvider(@Nullable JavaClass javaClass, @Nullable JavaPackage javaPackage, boolean staticMembers) {
this.javaClass = javaClass;
this.javaPackage = javaPackage;
this.staticMembers = staticMembers;
}
@NotNull
public static MembersProvider forPackage(@NotNull JavaPackage javaPackage) {
return new MembersProvider(null, javaPackage, true);
}
@NotNull
public static MembersProvider forClass(@NotNull JavaClass javaClass, boolean staticMembers) {
return new MembersProvider(javaClass, null, staticMembers);
}
@Nullable
public NamedMembers get(@NotNull Name name) {
return getMembersCache().get(name);
}
@NotNull
public Collection<NamedMembers> allMembers() {
return getMembersCache().allMembers();
}
@NotNull
private MembersCache getMembersCache() {
if (membersCache == null) {
if (javaClass != null) {
membersCache = MembersCache.buildForClass(javaClass, staticMembers);
}
else if (javaPackage != null) {
membersCache = MembersCache.buildForPackage(javaPackage);
}
else {
throw new IllegalStateException("MembersProvider should be created either for a class or for a package");
}
}
return membersCache;
}
}
@@ -1,83 +0,0 @@
/*
* Copyright 2010-2013 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.jet.lang.resolve.java.scope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
import org.jetbrains.jet.lang.resolve.java.structure.JavaField;
import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod;
import org.jetbrains.jet.lang.resolve.name.Name;
import java.util.ArrayList;
import java.util.List;
public final class NamedMembers {
public NamedMembers(@NotNull Name name) {
this.name = name;
}
@NotNull
private final Name name;
@NotNull
private final List<JavaMethod> methods = new ArrayList<JavaMethod>();
@NotNull
private final List<JavaField> fields = new ArrayList<JavaField>();
@Nullable
private JavaClass samInterface;
void addMethod(@NotNull JavaMethod method) {
methods.add(method);
}
void addField(@NotNull JavaField field) {
fields.add(field);
}
void setSamInterface(@NotNull JavaClass samInterface) {
this.samInterface = samInterface;
}
@NotNull
public Name getName() {
return name;
}
@NotNull
public List<JavaMethod> getMethods() {
return methods;
}
@NotNull
public List<JavaField> getFields() {
return fields;
}
@Nullable
public JavaClass getSamInterface() {
return samInterface;
}
@Override
public String toString() {
return name + ": " + methods.size() + " methods, " + fields.size() + " fields";
}
}