Extract FunctionResolver and AnnotationResolver classes from JavaDescriptorResolver

This commit is contained in:
Pavel V. Talanov
2012-10-06 19:08:57 +04:00
parent 6ce1f8c111
commit 88bd991729
12 changed files with 329 additions and 202 deletions
@@ -19,7 +19,6 @@ package org.jetbrains.jet.lang.resolve.java;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.intellij.codeInsight.ExternalAnnotationsManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import gnu.trove.THashMap;
@@ -29,21 +28,18 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.OverrideResolver;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverClassData;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverNamespaceData;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverScopeData;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData.ResolverSyntheticClassObjectClassData;
import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode;
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaNamespaceDescriptor;
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.AlternativeMethodSignatureData;
import org.jetbrains.jet.lang.resolve.java.kt.DescriptorKindUtils;
import org.jetbrains.jet.lang.resolve.java.kt.PsiAnnotationWithFlags;
import org.jetbrains.jet.lang.resolve.java.resolver.ClassResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.CompileTimeConstResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.ConstructorResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.PropertiesResolver;
import org.jetbrains.jet.lang.resolve.java.resolver.*;
import org.jetbrains.jet.lang.resolve.java.scope.JavaClassMembersScope;
import org.jetbrains.jet.lang.resolve.java.scope.JavaPackageScope;
import org.jetbrains.jet.lang.resolve.java.wrapper.PsiClassWrapper;
@@ -81,7 +77,7 @@ import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getClassObjectName;
*/
public class JavaDescriptorResolver implements DependencyClassByQualifiedNameResolver {
private static final FqName OBJECT_FQ_NAME = new FqName("java.lang.Object");
public static final FqName OBJECT_FQ_NAME = new FqName("java.lang.Object");
public static final Name JAVA_ROOT = Name.special("<java_root>");
@@ -131,6 +127,8 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
private final ClassResolver classResolver = new ClassResolver(this);
private final ConstructorResolver constructorResolver = new ConstructorResolver(this);
private final CompileTimeConstResolver compileTimeConstResolver = new CompileTimeConstResolver(this);
private final AnnotationResolver annotationResolver = new AnnotationResolver(this);
private final FunctionResolver functionResolver = new FunctionResolver(this);
@Inject
public void setProject(Project project) {
@@ -210,6 +208,14 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
return classResolver;
}
public CompileTimeConstResolver getCompileTimeConstResolver() {
return compileTimeConstResolver;
}
public AnnotationResolver getAnnotationResolver() {
return annotationResolver;
}
public static void checkPsiClassIsNotJet(PsiClass psiClass) {
if (psiClass instanceof JetJavaMirrorMarker) {
throw new IllegalStateException("trying to resolve fake jet PsiClass as regular PsiClass: " + psiClass.getQualifiedName());
@@ -676,7 +682,8 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
else {
JetType transformedType;
if (findAnnotation(parameter.getPsiParameter(), JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName()) != null) {
if (AnnotationResolver
.findAnnotation(parameter.getPsiParameter(), JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName()) != null) {
transformedType = TypeUtils.makeNullableAsSpecified(outType, false);
}
else {
@@ -747,7 +754,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
Set<SimpleFunctionDescriptor> functionsFromCurrent = Sets.newHashSet();
for (PsiMethodWrapper method : namedMembers.getMethods()) {
SimpleFunctionDescriptor function = resolveMethodToFunctionDescriptor(psiClass, method, scopeData);
SimpleFunctionDescriptor function = functionResolver.resolveMethodToFunctionDescriptor(psiClass, method, scopeData);
if (function != null) {
functionsFromCurrent.add(function);
}
@@ -849,91 +856,6 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
return new ValueParameterDescriptors(receiverType, result);
}
@Nullable
private SimpleFunctionDescriptor resolveMethodToFunctionDescriptor(
@NotNull final PsiClass psiClass, final PsiMethodWrapper method,
@NotNull ResolverScopeData scopeData) {
getResolverScopeData(scopeData);
PsiType returnPsiType = method.getReturnType();
if (returnPsiType == null) {
return null;
}
// TODO: ugly
if (method.getJetMethod().hasPropertyFlag()) {
return null;
}
final PsiMethod psiMethod = method.getPsiMethod();
final PsiClass containingClass = psiMethod.getContainingClass();
if (scopeData.isKotlin()) {
// TODO: unless maybe class explicitly extends Object
assert containingClass != null;
String ownerClassName = containingClass.getQualifiedName();
if (OBJECT_FQ_NAME.getFqName().equals(ownerClassName)) {
return null;
}
}
if (trace.get(BindingContext.FUNCTION, psiMethod) != null) {
return trace.get(BindingContext.FUNCTION, psiMethod);
}
SimpleFunctionDescriptorImpl functionDescriptorImpl = new SimpleFunctionDescriptorImpl(
scopeData.getClassOrNamespaceDescriptor(),
resolveAnnotations(psiMethod),
Name.identifier(method.getName()),
DescriptorKindUtils.flagsToKind(method.getJetMethod().kind())
);
String context = "method " + method.getName() + " in class " + psiClass.getQualifiedName();
List<TypeParameterDescriptor> methodTypeParameters = javaDescriptorSignatureResolver.resolveMethodTypeParameters(method,
functionDescriptorImpl);
TypeVariableResolver methodTypeVariableResolver = TypeVariableResolvers.typeVariableResolverFromTypeParameters(methodTypeParameters,
functionDescriptorImpl,
context);
ValueParameterDescriptors valueParameterDescriptors = resolveParameterDescriptors(functionDescriptorImpl, method.getParameters(), methodTypeVariableResolver);
JetType returnType = makeReturnType(returnPsiType, method, methodTypeVariableResolver);
// TODO consider better place for this check
AlternativeMethodSignatureData alternativeMethodSignatureData =
new AlternativeMethodSignatureData(method, valueParameterDescriptors, returnType, methodTypeParameters);
if (alternativeMethodSignatureData.isAnnotated() && !alternativeMethodSignatureData.hasErrors()) {
valueParameterDescriptors = alternativeMethodSignatureData.getValueParameters();
returnType = alternativeMethodSignatureData.getReturnType();
methodTypeParameters = alternativeMethodSignatureData.getTypeParameters();
}
else if (alternativeMethodSignatureData.hasErrors()) {
trace.record(BindingContext.ALTERNATIVE_SIGNATURE_DATA_ERROR, functionDescriptorImpl, alternativeMethodSignatureData.getError());
}
functionDescriptorImpl.initialize(
valueParameterDescriptors.receiverType,
DescriptorUtils.getExpectedThisObjectIfNeeded(scopeData.getClassOrNamespaceDescriptor()),
methodTypeParameters,
valueParameterDescriptors.descriptors,
returnType,
resolveModality(method, method.isFinal()),
resolveVisibility(psiMethod, method.getJetMethod()),
/*isInline = */ false
);
if (functionDescriptorImpl.getKind() == CallableMemberDescriptor.Kind.DECLARATION) {
BindingContextUtils.recordFunctionDeclarationToDescriptor(trace, psiMethod, functionDescriptorImpl);
}
if (containingClass != psiClass && !method.isStatic()) {
throw new IllegalStateException("non-static method in subclass");
}
return functionDescriptorImpl;
}
private static boolean isEnumSpecialMethod(@NotNull FunctionDescriptor functionDescriptor) {
List<ValueParameterDescriptor> methodTypeParameters = functionDescriptor.getValueParameters();
String methodName = functionDescriptor.getName().getName();
@@ -946,71 +868,20 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
}
public List<AnnotationDescriptor> resolveAnnotations(PsiModifierListOwner owner, @NotNull List<Runnable> tasks) {
PsiAnnotation[] psiAnnotations = getAllAnnotations(owner);
List<AnnotationDescriptor> r = Lists.newArrayListWithCapacity(psiAnnotations.length);
for (PsiAnnotation psiAnnotation : psiAnnotations) {
AnnotationDescriptor annotation = resolveAnnotation(psiAnnotation, tasks);
if (annotation != null) {
r.add(annotation);
}
}
return r;
return annotationResolver.resolveAnnotations(owner, tasks);
}
public List<AnnotationDescriptor> resolveAnnotations(PsiModifierListOwner owner) {
List<Runnable> tasks = Lists.newArrayList();
List<AnnotationDescriptor> annotations = resolveAnnotations(owner, tasks);
for (Runnable task : tasks) {
task.run();
}
return annotations;
return annotationResolver.resolveAnnotations(owner);
}
@Nullable
public AnnotationDescriptor resolveAnnotation(PsiAnnotation psiAnnotation, @NotNull List<Runnable> taskList) {
final AnnotationDescriptor annotation = new AnnotationDescriptor();
String qname = psiAnnotation.getQualifiedName();
if (qname == null) {
return null;
}
// Don't process internal jet annotations and jetbrains NotNull annotations
if (qname.startsWith("jet.runtime.typeinfo.") || qname.equals(JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName())) {
return null;
}
FqName annotationFqName = new FqName(qname);
final ClassDescriptor clazz = classResolver.resolveClass(annotationFqName, DescriptorSearchRule.INCLUDE_KOTLIN, taskList);
if (clazz == null) {
return null;
}
taskList.add(new Runnable() {
@Override
public void run() {
annotation.setAnnotationType(clazz.getDefaultType());
}
});
PsiAnnotationParameterList parameterList = psiAnnotation.getParameterList();
for (PsiNameValuePair psiNameValuePair : parameterList.getAttributes()) {
PsiAnnotationMemberValue value = psiNameValuePair.getValue();
String name = psiNameValuePair.getName();
if (name == null) name = "value";
Name identifier = Name.identifier(name);
CompileTimeConstant compileTimeConst =
compileTimeConstResolver.getCompileTimeConstFromExpression(annotationFqName, identifier, value, taskList);
if (compileTimeConst != null) {
ValueParameterDescriptor valueParameterDescriptor = getValueParameterDescriptorForAnnotationParameter(identifier, clazz);
if (valueParameterDescriptor != null) {
annotation.setValueArgument(valueParameterDescriptor, compileTimeConst);
}
}
}
return annotation;
return annotationResolver.resolveAnnotation(psiAnnotation, taskList);
}
@Nullable
@@ -1060,8 +931,10 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
}
}
private JetType makeReturnType(PsiType returnType, PsiMethodWrapper method,
@NotNull TypeVariableResolver typeVariableResolver) {
public JetType makeReturnType(
PsiType returnType, PsiMethodWrapper method,
@NotNull TypeVariableResolver typeVariableResolver
) {
String returnTypeFromAnnotation = method.getJetMethod().returnType();
@@ -1074,7 +947,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
returnType, JavaTypeTransformer.TypeUsage.MEMBER_SIGNATURE_COVARIANT, typeVariableResolver);
}
if (findAnnotation(method.getPsiMethod(), JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName()) != null) {
if (AnnotationResolver.findAnnotation(method.getPsiMethod(), JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName()) != null) {
return TypeUtils.makeNullableAsSpecified(transformedType, false);
}
else {
@@ -1164,34 +1037,4 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
assert classDescriptor != null : "Couldn't resolve class " + name;
return classDescriptor;
}
@NotNull
public static PsiAnnotation[] getAllAnnotations(@NotNull PsiModifierListOwner owner) {
List<PsiAnnotation> result = new ArrayList<PsiAnnotation>();
PsiModifierList list = owner.getModifierList();
if (list != null) {
result.addAll(Arrays.asList(list.getAnnotations()));
}
PsiAnnotation[] externalAnnotations = ExternalAnnotationsManager.getInstance(owner.getProject()).findExternalAnnotations(owner);
if (externalAnnotations != null) {
result.addAll(Arrays.asList(externalAnnotations));
}
return result.toArray(new PsiAnnotation[result.size()]);
}
@Nullable
public static PsiAnnotation findAnnotation(@NotNull PsiModifierListOwner owner, @NotNull String fqName) {
PsiModifierList list = owner.getModifierList();
if (list != null) {
PsiAnnotation found = list.findAnnotation(fqName);
if (found != null) {
return found;
}
}
return ExternalAnnotationsManager.getInstance(owner.getProject()).findExternalAnnotation(owner, fqName);
}
}
@@ -25,6 +25,7 @@ import com.intellij.psi.search.DelegatingGlobalSearchScope;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.resolver.AnnotationResolver;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.plugin.JetFileType;
@@ -80,8 +81,8 @@ public class PsiClassFinderImpl implements PsiClassFinder {
}
if ("jet".equals(qualifiedName.parent().getFqName())) {
PsiAnnotation assertInvisibleAnnotation = JavaDescriptorResolver
.findAnnotation(original, JvmStdlibNames.ASSERT_INVISIBLE_IN_RESOLVER.getFqName().getFqName());
PsiAnnotation assertInvisibleAnnotation =
AnnotationResolver.findAnnotation(original, JvmStdlibNames.ASSERT_INVISIBLE_IN_RESOLVER.getFqName().getFqName());
if (assertInvisibleAnnotation != null) {
if (runtimeClassesHandleMode == RuntimeClassesHandleMode.IGNORE) {
return null;
@@ -20,8 +20,8 @@ import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiClass;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
import org.jetbrains.jet.lang.resolve.java.resolver.AnnotationResolver;
/**
* @author Stepan Koltsov
@@ -56,7 +56,7 @@ public class JetClassAnnotation extends PsiAnnotationWithFlags {
@NotNull
public static JetClassAnnotation get(PsiClass psiClass) {
final PsiAnnotation annotation = JavaDescriptorResolver.findAnnotation(psiClass, JvmStdlibNames.JET_CLASS.getFqName().getFqName());
final PsiAnnotation annotation = AnnotationResolver.findAnnotation(psiClass, JvmStdlibNames.JET_CLASS.getFqName().getFqName());
return annotation != null ? new JetClassAnnotation(annotation) : NULL_ANNOTATION;
}
}
@@ -19,8 +19,8 @@ package org.jetbrains.jet.lang.resolve.java.kt;
import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiMethod;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
import org.jetbrains.jet.lang.resolve.java.resolver.AnnotationResolver;
/**
* @author Stepan Koltsov
@@ -51,7 +51,7 @@ public class JetConstructorAnnotation extends PsiAnnotationWithFlags {
public static JetConstructorAnnotation get(PsiMethod constructor) {
final PsiAnnotation annotation =
JavaDescriptorResolver.findAnnotation(constructor, JvmStdlibNames.JET_CONSTRUCTOR.getFqName().getFqName());
AnnotationResolver.findAnnotation(constructor, JvmStdlibNames.JET_CONSTRUCTOR.getFqName().getFqName());
return annotation != null ? new JetConstructorAnnotation(annotation) : NULL_ANNOTATION;
}
}
@@ -20,8 +20,8 @@ import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiMethod;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
import org.jetbrains.jet.lang.resolve.java.resolver.AnnotationResolver;
/**
* @author Stepan Koltsov
@@ -73,7 +73,7 @@ public class JetMethodAnnotation extends PsiAnnotationWithFlags {
public static JetMethodAnnotation get(PsiMethod psiMethod) {
final PsiAnnotation annotation =
JavaDescriptorResolver.findAnnotation(psiMethod, JvmStdlibNames.JET_METHOD.getFqName().getFqName());
AnnotationResolver.findAnnotation(psiMethod, JvmStdlibNames.JET_METHOD.getFqName().getFqName());
return annotation != null ? new JetMethodAnnotation(annotation) : NULL_ANNOTATION;
}
}
@@ -20,8 +20,8 @@ import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiParameter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
import org.jetbrains.jet.lang.resolve.java.resolver.AnnotationResolver;
/**
* @author Stepan Koltsov
@@ -43,7 +43,7 @@ public class JetTypeParameterAnnotation extends PsiAnnotationWrapper {
@NotNull
public static JetTypeParameterAnnotation get(@NotNull PsiParameter psiParameter) {
final PsiAnnotation annotation =
JavaDescriptorResolver.findAnnotation(psiParameter, JvmStdlibNames.JET_TYPE_PARAMETER.getFqName().getFqName());
AnnotationResolver.findAnnotation(psiParameter, JvmStdlibNames.JET_TYPE_PARAMETER.getFqName().getFqName());
return annotation != null ? new JetTypeParameterAnnotation(annotation) : NULL_ANNOTATION;
}
}
@@ -20,8 +20,8 @@ import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiParameter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
import org.jetbrains.jet.lang.resolve.java.resolver.AnnotationResolver;
/**
* @author Stepan Koltsov
@@ -74,7 +74,7 @@ public class JetValueParameterAnnotation extends PsiAnnotationWrapper {
public static JetValueParameterAnnotation get(PsiParameter psiParameter) {
final PsiAnnotation annotation =
JavaDescriptorResolver.findAnnotation(psiParameter, JvmStdlibNames.JET_VALUE_PARAMETER.getFqName().getFqName());
AnnotationResolver.findAnnotation(psiParameter, JvmStdlibNames.JET_VALUE_PARAMETER.getFqName().getFqName());
return annotation != null ? new JetValueParameterAnnotation(annotation) : NULL_ANNOTATION;
}
}
@@ -21,8 +21,8 @@ import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiModifierListOwner;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames;
import org.jetbrains.jet.lang.resolve.java.resolver.AnnotationResolver;
/**
* @author Evgeny Gerashchenko
@@ -54,7 +54,7 @@ public class KotlinSignatureAnnotation extends PsiAnnotationWrapper {
@NotNull
public static KotlinSignatureAnnotation get(PsiModifierListOwner psiModifierListOwner) {
final PsiAnnotation annotation =
JavaDescriptorResolver.findAnnotation(psiModifierListOwner, JvmStdlibNames.KOTLIN_SIGNATURE.getFqName().getFqName());
AnnotationResolver.findAnnotation(psiModifierListOwner, JvmStdlibNames.KOTLIN_SIGNATURE.getFqName().getFqName());
return annotation != null ? new KotlinSignatureAnnotation(annotation) : NULL_ANNOTATION;
}
}
@@ -0,0 +1,145 @@
/*
* Copyright 2010-2012 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.Lists;
import com.intellij.codeInsight.ExternalAnnotationsManager;
import com.intellij.psi.*;
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.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class AnnotationResolver {
private final JavaDescriptorResolver javaDescriptorResolver;
public AnnotationResolver(JavaDescriptorResolver javaDescriptorResolver) {
this.javaDescriptorResolver = javaDescriptorResolver;
}
public List<AnnotationDescriptor> resolveAnnotations(PsiModifierListOwner owner, @NotNull List<Runnable> tasks) {
PsiAnnotation[] psiAnnotations = getAllAnnotations(owner);
List<AnnotationDescriptor> r = Lists.newArrayListWithCapacity(psiAnnotations.length);
for (PsiAnnotation psiAnnotation : psiAnnotations) {
AnnotationDescriptor annotation = resolveAnnotation(psiAnnotation, tasks);
if (annotation != null) {
r.add(annotation);
}
}
return r;
}
public List<AnnotationDescriptor> resolveAnnotations(PsiModifierListOwner owner) {
List<Runnable> tasks = Lists.newArrayList();
List<AnnotationDescriptor> annotations = resolveAnnotations(owner, tasks);
for (Runnable task : tasks) {
task.run();
}
return annotations;
}
@Nullable
public AnnotationDescriptor resolveAnnotation(PsiAnnotation psiAnnotation, @NotNull List<Runnable> taskList) {
final AnnotationDescriptor annotation = new AnnotationDescriptor();
String qname = psiAnnotation.getQualifiedName();
if (qname == null) {
return null;
}
// Don't process internal jet annotations and jetbrains NotNull annotations
if (qname.startsWith("jet.runtime.typeinfo.") || qname.equals(JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName())) {
return null;
}
FqName annotationFqName = new FqName(qname);
final ClassDescriptor clazz =
javaDescriptorResolver.getClassResolver().resolveClass(annotationFqName, DescriptorSearchRule.INCLUDE_KOTLIN, taskList);
if (clazz == null) {
return null;
}
taskList.add(new Runnable() {
@Override
public void run() {
annotation.setAnnotationType(clazz.getDefaultType());
}
});
PsiAnnotationParameterList parameterList = psiAnnotation.getParameterList();
for (PsiNameValuePair psiNameValuePair : parameterList.getAttributes()) {
PsiAnnotationMemberValue value = psiNameValuePair.getValue();
String name = psiNameValuePair.getName();
if (name == null) name = "value";
Name identifier = Name.identifier(name);
CompileTimeConstant compileTimeConst =
javaDescriptorResolver.getCompileTimeConstResolver()
.getCompileTimeConstFromExpression(annotationFqName, identifier, value, taskList);
if (compileTimeConst != null) {
ValueParameterDescriptor valueParameterDescriptor =
JavaDescriptorResolver.getValueParameterDescriptorForAnnotationParameter(identifier, clazz);
if (valueParameterDescriptor != null) {
annotation.setValueArgument(valueParameterDescriptor, compileTimeConst);
}
}
}
return annotation;
}
@NotNull
public static PsiAnnotation[] getAllAnnotations(@NotNull PsiModifierListOwner owner) {
List<PsiAnnotation> result = new ArrayList<PsiAnnotation>();
PsiModifierList list = owner.getModifierList();
if (list != null) {
result.addAll(Arrays.asList(list.getAnnotations()));
}
PsiAnnotation[] externalAnnotations = ExternalAnnotationsManager.getInstance(owner.getProject()).findExternalAnnotations(owner);
if (externalAnnotations != null) {
result.addAll(Arrays.asList(externalAnnotations));
}
return result.toArray(new PsiAnnotation[result.size()]);
}
@Nullable
public static PsiAnnotation findAnnotation(@NotNull PsiModifierListOwner owner, @NotNull String fqName) {
PsiModifierList list = owner.getModifierList();
if (list != null) {
PsiAnnotation found = list.findAnnotation(fqName);
if (found != null) {
return found;
}
}
return ExternalAnnotationsManager.getInstance(owner.getProject()).findExternalAnnotation(owner, fqName);
}
}
@@ -0,0 +1,138 @@
/*
* Copyright 2010-2012 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.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptorImpl;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolveData;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.TypeVariableResolver;
import org.jetbrains.jet.lang.resolve.java.TypeVariableResolvers;
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.AlternativeMethodSignatureData;
import org.jetbrains.jet.lang.resolve.java.kt.DescriptorKindUtils;
import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.JetType;
import java.util.List;
public class FunctionResolver {
private final JavaDescriptorResolver javaDescriptorResolver;
public FunctionResolver(JavaDescriptorResolver javaDescriptorResolver) {
this.javaDescriptorResolver = javaDescriptorResolver;
}
@Nullable
public SimpleFunctionDescriptor resolveMethodToFunctionDescriptor(
@NotNull final PsiClass psiClass, final PsiMethodWrapper method,
@NotNull JavaDescriptorResolveData.ResolverScopeData scopeData
) {
JavaDescriptorResolver.getResolverScopeData(scopeData);
PsiType returnPsiType = method.getReturnType();
if (returnPsiType == null) {
return null;
}
// TODO: ugly
if (method.getJetMethod().hasPropertyFlag()) {
return null;
}
final PsiMethod psiMethod = method.getPsiMethod();
final PsiClass containingClass = psiMethod.getContainingClass();
if (scopeData.isKotlin()) {
// TODO: unless maybe class explicitly extends Object
assert containingClass != null;
String ownerClassName = containingClass.getQualifiedName();
if (JavaDescriptorResolver.OBJECT_FQ_NAME.getFqName().equals(ownerClassName)) {
return null;
}
}
if (javaDescriptorResolver.getTrace().get(BindingContext.FUNCTION, psiMethod) != null) {
return javaDescriptorResolver.getTrace().get(BindingContext.FUNCTION, psiMethod);
}
SimpleFunctionDescriptorImpl functionDescriptorImpl = new SimpleFunctionDescriptorImpl(
scopeData.getClassOrNamespaceDescriptor(),
javaDescriptorResolver.getAnnotationResolver().resolveAnnotations(psiMethod),
Name.identifier(method.getName()),
DescriptorKindUtils.flagsToKind(method.getJetMethod().kind())
);
String context = "method " + method.getName() + " in class " + psiClass.getQualifiedName();
List<TypeParameterDescriptor> methodTypeParameters =
javaDescriptorResolver.getJavaDescriptorSignatureResolver().resolveMethodTypeParameters(method,
functionDescriptorImpl);
TypeVariableResolver methodTypeVariableResolver = TypeVariableResolvers.typeVariableResolverFromTypeParameters(methodTypeParameters,
functionDescriptorImpl,
context);
JavaDescriptorResolver.ValueParameterDescriptors valueParameterDescriptors = javaDescriptorResolver
.resolveParameterDescriptors(functionDescriptorImpl, method.getParameters(), methodTypeVariableResolver);
JetType returnType = javaDescriptorResolver.makeReturnType(returnPsiType, method, methodTypeVariableResolver);
// TODO consider better place for this check
AlternativeMethodSignatureData alternativeMethodSignatureData =
new AlternativeMethodSignatureData(method, valueParameterDescriptors, returnType, methodTypeParameters);
if (alternativeMethodSignatureData.isAnnotated() && !alternativeMethodSignatureData.hasErrors()) {
valueParameterDescriptors = alternativeMethodSignatureData.getValueParameters();
returnType = alternativeMethodSignatureData.getReturnType();
methodTypeParameters = alternativeMethodSignatureData.getTypeParameters();
}
else if (alternativeMethodSignatureData.hasErrors()) {
javaDescriptorResolver.getTrace().record(BindingContext.ALTERNATIVE_SIGNATURE_DATA_ERROR, functionDescriptorImpl,
alternativeMethodSignatureData.getError());
}
functionDescriptorImpl.initialize(
valueParameterDescriptors.getReceiverType(),
DescriptorUtils.getExpectedThisObjectIfNeeded(scopeData.getClassOrNamespaceDescriptor()),
methodTypeParameters,
valueParameterDescriptors.getDescriptors(),
returnType,
JavaDescriptorResolver.resolveModality(method, method.isFinal()),
JavaDescriptorResolver.resolveVisibility(psiMethod, method.getJetMethod()),
/*isInline = */ false
);
if (functionDescriptorImpl.getKind() == CallableMemberDescriptor.Kind.DECLARATION) {
BindingContextUtils.recordFunctionDeclarationToDescriptor(javaDescriptorResolver.getTrace(), psiMethod, functionDescriptorImpl);
}
if (containingClass != psiClass && !method.isStatic()) {
throw new IllegalStateException("non-static method in subclass");
}
return functionDescriptorImpl;
}
}
@@ -292,8 +292,8 @@ public final class PropertiesResolver {
}
else {
propertyType = semanticServices.getTypeTransformer().transformToType(characteristicMember.getType().getPsiType(), typeVariableResolverForPropertyInternals);
if (JavaDescriptorResolver.findAnnotation(characteristicMember.getType().getPsiNotNullOwner(),
JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName()) != null) {
if (AnnotationResolver.findAnnotation(characteristicMember.getType().getPsiNotNullOwner(),
JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName()) != null) {
propertyType = TypeUtils.makeNullableAsSpecified(propertyType, false);
}
else if (members.getter == null && members.setter == null && members.field.getMember().isFinal() && members.field.getMember().isStatic()) {