diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index 2988a05c518..7bcd70358be 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -30,8 +30,7 @@ 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.*; -import org.jetbrains.jet.lang.resolve.constants.StringValue; +import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; 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; @@ -42,6 +41,7 @@ import org.jetbrains.jet.lang.resolve.java.kotlinSignature.AlternativeMethodSign 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.scope.JavaClassMembersScope; @@ -54,11 +54,13 @@ import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqNameBase; 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.*; +import org.jetbrains.jet.lang.types.DependencyClassByQualifiedNameResolver; +import org.jetbrains.jet.lang.types.ErrorUtils; +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.JetStandardClasses; import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; @@ -128,6 +130,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes private PropertiesResolver propertiesResolver = new PropertiesResolver(this); private final ClassResolver classResolver = new ClassResolver(this); private final ConstructorResolver constructorResolver = new ConstructorResolver(this); + private final CompileTimeConstResolver compileTimeConstResolver = new CompileTimeConstResolver(this); @Inject public void setProject(Project project) { @@ -203,12 +206,8 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes return constructorResolver.resolveConstructors(classData); } - @Nullable - private ConstructorDescriptor resolveConstructor(PsiClass psiClass, ResolverClassData classData, boolean aStatic, PsiMethod psiConstructor) { - - //noinspection deprecation - - return constructorResolver.resolveConstructor(psiClass, classData, aStatic, psiConstructor); + public ClassResolver getClassResolver() { + return classResolver; } public static void checkPsiClassIsNotJet(PsiClass psiClass) { @@ -968,7 +967,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes } @Nullable - private AnnotationDescriptor resolveAnnotation(PsiAnnotation psiAnnotation, @NotNull List taskList) { + public AnnotationDescriptor resolveAnnotation(PsiAnnotation psiAnnotation, @NotNull List taskList) { final AnnotationDescriptor annotation = new AnnotationDescriptor(); String qname = psiAnnotation.getQualifiedName(); if (qname == null) { @@ -1001,7 +1000,8 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes if (name == null) name = "value"; Name identifier = Name.identifier(name); - CompileTimeConstant compileTimeConst = getCompileTimeConstFromExpression(annotationFqName, identifier, value, taskList); + CompileTimeConstant compileTimeConst = + compileTimeConstResolver.getCompileTimeConstFromExpression(annotationFqName, identifier, value, taskList); if (compileTimeConst != null) { ValueParameterDescriptor valueParameterDescriptor = getValueParameterDescriptorForAnnotationParameter(identifier, clazz); if (valueParameterDescriptor != null) { @@ -1031,145 +1031,6 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes return null; } - @Nullable - private CompileTimeConstant getCompileTimeConstFromExpression( - FqName annotationFqName, Name parameterName, - PsiAnnotationMemberValue value, List taskList - ) { - if (value instanceof PsiLiteralExpression) { - return getCompileTimeConstFromLiteralExpression((PsiLiteralExpression) value); - } - // Enum - else if (value instanceof PsiReferenceExpression) { - return getCompileTimeConstFromReferenceExpression((PsiReferenceExpression) value, taskList); - } - // Array - else if (value instanceof PsiArrayInitializerMemberValue) { - return getCompileTimeConstFromArrayExpression(annotationFqName, parameterName, (PsiArrayInitializerMemberValue) value, taskList); - } - // Annotation - else if (value instanceof PsiAnnotation) { - return getCompileTimeConstFromAnnotation((PsiAnnotation) value, taskList); - } - return null; - } - - @Nullable - private CompileTimeConstant getCompileTimeConstFromAnnotation(PsiAnnotation value, List taskList) { - AnnotationDescriptor annotationDescriptor = resolveAnnotation(value, taskList); - if (annotationDescriptor != null) { - return new AnnotationValue(annotationDescriptor); - } - return null; - } - - @Nullable - private CompileTimeConstant getCompileTimeConstFromArrayExpression( - FqName annotationFqName, - Name valueName, PsiArrayInitializerMemberValue value, - List taskList - ) { - PsiAnnotationMemberValue[] initializers = value.getInitializers(); - List> values = getCompileTimeConstantForArrayValues(annotationFqName, valueName, taskList, initializers); - - ClassDescriptor classDescriptor = classResolver.resolveClass(annotationFqName, DescriptorSearchRule.INCLUDE_KOTLIN, taskList); - - ValueParameterDescriptor valueParameterDescriptor = getValueParameterDescriptorForAnnotationParameter(valueName, classDescriptor); - if (valueParameterDescriptor == null) { - return null; - } - JetType expectedArrayType = valueParameterDescriptor.getType(); - return new ArrayValue(values, expectedArrayType); - } - - private List> getCompileTimeConstantForArrayValues( - FqName annotationQualifiedName, - Name valueName, - List taskList, - PsiAnnotationMemberValue[] initializers - ) { - List> values = new ArrayList>(); - for (PsiAnnotationMemberValue initializer : initializers) { - CompileTimeConstant compileTimeConstant = - getCompileTimeConstFromExpression(annotationQualifiedName, valueName, initializer, taskList); - if (compileTimeConstant == null) { - compileTimeConstant = NullValue.NULL; - } - values.add(compileTimeConstant); - } - return values; - } - - @Nullable - private CompileTimeConstant getCompileTimeConstFromReferenceExpression(PsiReferenceExpression value, List taskList) { - PsiElement resolveElement = value.resolve(); - if (resolveElement instanceof PsiEnumConstant) { - PsiElement psiElement = resolveElement.getParent(); - if (psiElement instanceof PsiClass) { - PsiClass psiClass = (PsiClass) psiElement; - String fqName = psiClass.getQualifiedName(); - if (fqName == null) { - return null; - } - - JetScope scope; - ClassDescriptor classDescriptor = - classResolver.resolveClass(new FqName(fqName), DescriptorSearchRule.INCLUDE_KOTLIN, taskList); - if (classDescriptor == null) { - return null; - } - ClassDescriptor classObjectDescriptor = classDescriptor.getClassObjectDescriptor(); - if (classObjectDescriptor == null) { - return null; - } - scope = classObjectDescriptor.getMemberScope(Lists.newArrayList()); - - Name identifier = Name.identifier(((PsiEnumConstant) resolveElement).getName()); - Collection properties = scope.getProperties(identifier); - for (VariableDescriptor variableDescriptor : properties) { - if (!variableDescriptor.getReceiverParameter().exists()) { - return new EnumValue((PropertyDescriptor) variableDescriptor); - } - } - return null; - } - } - return null; - } - - @Nullable - private static CompileTimeConstant getCompileTimeConstFromLiteralExpression(PsiLiteralExpression value) { - Object literalValue = value.getValue(); - if (literalValue instanceof String) { - return new StringValue((String) literalValue); - } - else if (literalValue instanceof Byte) { - return new ByteValue((Byte) literalValue); - } - else if (literalValue instanceof Short) { - return new ShortValue((Short) literalValue); - } - else if (literalValue instanceof Character) { - return new CharValue((Character) literalValue); - } - else if (literalValue instanceof Integer) { - return new IntValue((Integer) literalValue); - } - else if (literalValue instanceof Long) { - return new LongValue((Long) literalValue); - } - else if (literalValue instanceof Float) { - return new FloatValue((Float) literalValue); - } - else if (literalValue instanceof Double) { - return new DoubleValue((Double) literalValue); - } - else if (literalValue == null) { - return NullValue.NULL; - } - return null; - } - public List resolveMethods(@NotNull ResolverScopeData scopeData) { getResolverScopeData(scopeData); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/CompileTimeConstResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/CompileTimeConstResolver.java new file mode 100644 index 00000000000..ca20f0f803f --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/CompileTimeConstResolver.java @@ -0,0 +1,190 @@ +/* + * 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.psi.*; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; +import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; +import org.jetbrains.jet.lang.descriptors.VariableDescriptor; +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.resolve.constants.*; +import org.jetbrains.jet.lang.resolve.constants.StringValue; +import org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule; +import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; +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 org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.TypeProjection; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class CompileTimeConstResolver { + private final JavaDescriptorResolver javaDescriptorResolver; + + public CompileTimeConstResolver(JavaDescriptorResolver javaDescriptorResolver) { + this.javaDescriptorResolver = javaDescriptorResolver; + } + + @Nullable + public CompileTimeConstant getCompileTimeConstFromExpression( + FqName annotationFqName, Name parameterName, + PsiAnnotationMemberValue value, List taskList + ) { + if (value instanceof PsiLiteralExpression) { + return getCompileTimeConstFromLiteralExpression((PsiLiteralExpression) value); + } + // Enum + else if (value instanceof PsiReferenceExpression) { + return getCompileTimeConstFromReferenceExpression((PsiReferenceExpression) value, taskList); + } + // Array + else if (value instanceof PsiArrayInitializerMemberValue) { + return getCompileTimeConstFromArrayExpression(annotationFqName, parameterName, (PsiArrayInitializerMemberValue) value, + taskList); + } + // Annotation + else if (value instanceof PsiAnnotation) { + return getCompileTimeConstFromAnnotation((PsiAnnotation) value, taskList); + } + return null; + } + + @Nullable + public CompileTimeConstant getCompileTimeConstFromAnnotation(PsiAnnotation value, List taskList) { + AnnotationDescriptor annotationDescriptor = javaDescriptorResolver.resolveAnnotation(value, taskList); + if (annotationDescriptor != null) { + return new AnnotationValue(annotationDescriptor); + } + return null; + } + + @Nullable + public CompileTimeConstant getCompileTimeConstFromArrayExpression( + FqName annotationFqName, + Name valueName, PsiArrayInitializerMemberValue value, + List taskList + ) { + PsiAnnotationMemberValue[] initializers = value.getInitializers(); + List> values = getCompileTimeConstantForArrayValues(annotationFqName, valueName, taskList, initializers); + + ClassDescriptor classDescriptor = + javaDescriptorResolver.getClassResolver().resolveClass(annotationFqName, DescriptorSearchRule.INCLUDE_KOTLIN, taskList); + + ValueParameterDescriptor valueParameterDescriptor = + JavaDescriptorResolver.getValueParameterDescriptorForAnnotationParameter(valueName, classDescriptor); + if (valueParameterDescriptor == null) { + return null; + } + JetType expectedArrayType = valueParameterDescriptor.getType(); + return new ArrayValue(values, expectedArrayType); + } + + public List> getCompileTimeConstantForArrayValues( + FqName annotationQualifiedName, + Name valueName, + List taskList, + PsiAnnotationMemberValue[] initializers + ) { + List> values = new ArrayList>(); + for (PsiAnnotationMemberValue initializer : initializers) { + CompileTimeConstant compileTimeConstant = + getCompileTimeConstFromExpression(annotationQualifiedName, valueName, initializer, taskList); + if (compileTimeConstant == null) { + compileTimeConstant = NullValue.NULL; + } + values.add(compileTimeConstant); + } + return values; + } + + @Nullable + public CompileTimeConstant getCompileTimeConstFromReferenceExpression(PsiReferenceExpression value, List taskList) { + PsiElement resolveElement = value.resolve(); + if (resolveElement instanceof PsiEnumConstant) { + PsiElement psiElement = resolveElement.getParent(); + if (psiElement instanceof PsiClass) { + PsiClass psiClass = (PsiClass) psiElement; + String fqName = psiClass.getQualifiedName(); + if (fqName == null) { + return null; + } + + JetScope scope; + ClassDescriptor classDescriptor = + javaDescriptorResolver.getClassResolver() + .resolveClass(new FqName(fqName), DescriptorSearchRule.INCLUDE_KOTLIN, taskList); + if (classDescriptor == null) { + return null; + } + ClassDescriptor classObjectDescriptor = classDescriptor.getClassObjectDescriptor(); + if (classObjectDescriptor == null) { + return null; + } + scope = classObjectDescriptor.getMemberScope(Lists.newArrayList()); + + Name identifier = Name.identifier(((PsiEnumConstant) resolveElement).getName()); + Collection properties = scope.getProperties(identifier); + for (VariableDescriptor variableDescriptor : properties) { + if (!variableDescriptor.getReceiverParameter().exists()) { + return new EnumValue((PropertyDescriptor) variableDescriptor); + } + } + return null; + } + } + return null; + } + + @Nullable + public static CompileTimeConstant getCompileTimeConstFromLiteralExpression(PsiLiteralExpression value) { + Object literalValue = value.getValue(); + if (literalValue instanceof String) { + return new StringValue((String) literalValue); + } + else if (literalValue instanceof Byte) { + return new ByteValue((Byte) literalValue); + } + else if (literalValue instanceof Short) { + return new ShortValue((Short) literalValue); + } + else if (literalValue instanceof Character) { + return new CharValue((Character) literalValue); + } + else if (literalValue instanceof Integer) { + return new IntValue((Integer) literalValue); + } + else if (literalValue instanceof Long) { + return new LongValue((Long) literalValue); + } + else if (literalValue instanceof Float) { + return new FloatValue((Float) literalValue); + } + else if (literalValue instanceof Double) { + return new DoubleValue((Double) literalValue); + } + else if (literalValue == null) { + return NullValue.NULL; + } + return null; + } +} \ No newline at end of file