Introduce JavaClassifier
JavaClassifier is a common type for JavaClass and JavaTypeParameter. In almost all of the places JavaClass remains to be JavaClass, except for the resolution result of JavaClassType, which can be a type parameter. Add an assertion that JavaClass is created only for a class and not for a type parameter. Delete different creations of JavaClass in 'idea' (where there can be a type parameter) by changing the interface of util functions. Delete JavaModifierListOwnerImpl, extract its methods into JavaElementUtil and use these implementations for every JavaModifierListOwner Continue refactoring JavaTypeTransformer to work with JavaType, not PsiType
This commit is contained in:
+8
-7
@@ -43,8 +43,9 @@ public final class DescriptorResolverUtils {
|
||||
private DescriptorResolverUtils() {
|
||||
}
|
||||
|
||||
public static boolean isCompiledKotlinPackageClass(@NotNull JavaClass javaClass) {
|
||||
if (javaClass.getPsi() instanceof ClsClassImpl) {
|
||||
public static boolean isCompiledKotlinPackageClass(@NotNull PsiClass psiClass) {
|
||||
if (psiClass instanceof ClsClassImpl) {
|
||||
JavaClass javaClass = new JavaClass(psiClass);
|
||||
FqName fqName = javaClass.getFqName();
|
||||
if (fqName != null && PackageClassUtils.isPackageClassFqName(fqName)) {
|
||||
return hasAnnotation(javaClass, JvmAnnotationNames.KOTLIN_PACKAGE.getFqName());
|
||||
@@ -53,9 +54,9 @@ public final class DescriptorResolverUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isCompiledKotlinClass(@NotNull JavaClass javaClass) {
|
||||
if (javaClass.getPsi() instanceof ClsClassImpl) {
|
||||
return hasAnnotation(javaClass, JvmAnnotationNames.KOTLIN_CLASS.getFqName());
|
||||
public static boolean isCompiledKotlinClass(@NotNull PsiClass psiClass) {
|
||||
if (psiClass instanceof ClsClassImpl) {
|
||||
return hasAnnotation(new JavaClass(psiClass), JvmAnnotationNames.KOTLIN_CLASS.getFqName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -64,8 +65,8 @@ public final class DescriptorResolverUtils {
|
||||
return javaClass.findAnnotation(annotationFqName.asString()) != null;
|
||||
}
|
||||
|
||||
public static boolean isCompiledKotlinClassOrPackageClass(@NotNull JavaClass javaClass) {
|
||||
return isCompiledKotlinClass(javaClass) || isCompiledKotlinPackageClass(javaClass);
|
||||
public static boolean isCompiledKotlinClassOrPackageClass(@NotNull PsiClass psiClass) {
|
||||
return isCompiledKotlinClass(psiClass) || isCompiledKotlinPackageClass(psiClass);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+3
-3
@@ -187,10 +187,10 @@ public final class JavaNamespaceResolver {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (DescriptorResolverUtils.isCompiledKotlinClassOrPackageClass(javaClass)) {
|
||||
PsiClass psiClass = javaClass.getPsi();
|
||||
if (DescriptorResolverUtils.isCompiledKotlinClassOrPackageClass(psiClass)) {
|
||||
return null;
|
||||
}
|
||||
PsiClass psiClass = javaClass.getPsi();
|
||||
if (!hasStaticMembers(psiClass)) {
|
||||
return null;
|
||||
}
|
||||
@@ -257,7 +257,7 @@ public final class JavaNamespaceResolver {
|
||||
Collection<JavaClass> classes = DescriptorResolverUtils.filterDuplicateClasses(javaPackage.getClasses());
|
||||
List<Name> result = new ArrayList<Name>(classes.size());
|
||||
for (JavaClass javaClass : classes) {
|
||||
if (DescriptorResolverUtils.isCompiledKotlinClass(javaClass)) {
|
||||
if (DescriptorResolverUtils.isCompiledKotlinClass(javaClass.getPsi())) {
|
||||
result.add(javaClass.getName());
|
||||
}
|
||||
}
|
||||
|
||||
+4
-2
@@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.resolve.java.TypeUsage;
|
||||
import org.jetbrains.jet.lang.resolve.java.TypeVariableResolver;
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaClassType;
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaClassifier;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.types.ErrorUtils;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
@@ -116,9 +117,10 @@ public final class JavaSupertypeResolver {
|
||||
) {
|
||||
List<JetType> result = new ArrayList<JetType>(supertypes.size());
|
||||
for (JavaClassType type : supertypes) {
|
||||
JavaClass resolved = type.resolve();
|
||||
JavaClassifier resolved = type.resolve();
|
||||
if (resolved != null) {
|
||||
FqName fqName = resolved.getFqName();
|
||||
assert resolved instanceof JavaClass : "Supertype should be a class: " + resolved;
|
||||
FqName fqName = ((JavaClass) resolved).getFqName();
|
||||
assert fqName != null : "Unresolved supertype: " + resolved;
|
||||
if (JvmAbi.JET_OBJECT.getFqName().equals(fqName)) {
|
||||
continue;
|
||||
|
||||
+106
-94
@@ -19,8 +19,10 @@ package org.jetbrains.jet.lang.resolve.java.resolver;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.PsiModifierListOwner;
|
||||
import com.intellij.psi.PsiType;
|
||||
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.AnnotationDescriptor;
|
||||
@@ -89,7 +91,12 @@ public class JavaTypeTransformer {
|
||||
@NotNull TypeVariableResolver typeVariableResolver
|
||||
) {
|
||||
if (type instanceof JavaClassType) {
|
||||
return transformClassType((JavaClassType) type, howThisTypeIsUsed, typeVariableResolver);
|
||||
JavaClassType classType = (JavaClassType) type;
|
||||
JetType jetType = transformClassType(classType, howThisTypeIsUsed, typeVariableResolver);
|
||||
if (jetType == null) {
|
||||
return ErrorUtils.createErrorType("Unresolved java class: " + classType.getPresentableText());
|
||||
}
|
||||
return jetType;
|
||||
}
|
||||
else if (type instanceof JavaPrimitiveType) {
|
||||
String canonicalText = ((JavaPrimitiveType) type).getCanonicalText();
|
||||
@@ -105,125 +112,130 @@ public class JavaTypeTransformer {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Nullable
|
||||
private JetType transformClassType(
|
||||
@NotNull JavaClassType classType,
|
||||
@NotNull TypeUsage howThisTypeIsUsed,
|
||||
@NotNull TypeVariableResolver typeVariableResolver
|
||||
) {
|
||||
JavaClass javaClass = classType.resolve();
|
||||
if (javaClass == null) {
|
||||
return ErrorUtils.createErrorType("Unresolved java class: " + classType.getPresentableText());
|
||||
JavaClassifier javaClassifier = classType.resolve();
|
||||
if (javaClassifier == null) {
|
||||
return null;
|
||||
}
|
||||
if (javaClassifier instanceof JavaTypeParameter) {
|
||||
return transformTypeParameter((JavaTypeParameter) javaClassifier, howThisTypeIsUsed, typeVariableResolver);
|
||||
}
|
||||
else if (javaClassifier instanceof JavaClass) {
|
||||
FqName fqName = ((JavaClass) javaClassifier).getFqName();
|
||||
assert fqName != null : "Class type should have a FQ name: " + javaClassifier;
|
||||
return transformClassType(fqName, classType, howThisTypeIsUsed, typeVariableResolver);
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("Unsupported classifier: " + javaClassifier);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private JetType transformTypeParameter(
|
||||
@NotNull JavaTypeParameter typeParameter,
|
||||
@NotNull TypeUsage howThisTypeIsUsed,
|
||||
@NotNull TypeVariableResolver typeVariableResolver
|
||||
) {
|
||||
JavaTypeParameterListOwner owner = typeParameter.getOwner();
|
||||
if (owner instanceof JavaMethod && ((JavaMethod) owner).isConstructor()) {
|
||||
Set<JetType> supertypesJet = Sets.newHashSet();
|
||||
for (JavaClassType supertype : typeParameter.getUpperBounds()) {
|
||||
supertypesJet.add(transformToType(supertype, UPPER_BOUND, typeVariableResolver));
|
||||
}
|
||||
return TypeUtils.intersect(JetTypeChecker.INSTANCE, supertypesJet);
|
||||
}
|
||||
|
||||
PsiClass psiClass = javaClass.getPsi();
|
||||
TypeParameterDescriptor typeParameterDescriptor = typeVariableResolver.getTypeVariable(typeParameter.getName().asString());
|
||||
|
||||
if (psiClass instanceof PsiTypeParameter) {
|
||||
PsiTypeParameter typeParameter = (PsiTypeParameter) psiClass;
|
||||
// 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);
|
||||
|
||||
PsiTypeParameterListOwner typeParameterListOwner = typeParameter.getOwner();
|
||||
if (typeParameterListOwner instanceof PsiMethod) {
|
||||
PsiMethod psiMethod = (PsiMethod) typeParameterListOwner;
|
||||
if (psiMethod.isConstructor()) {
|
||||
Set<JetType> supertypesJet = Sets.newHashSet();
|
||||
for (PsiClassType supertype : typeParameter.getExtendsListTypes()) {
|
||||
supertypesJet.add(transformToType(JavaType.create(supertype), UPPER_BOUND, typeVariableResolver));
|
||||
}
|
||||
JetType type = TypeUtils.intersect(JetTypeChecker.INSTANCE, supertypesJet);
|
||||
if (type == null) {
|
||||
return ErrorUtils.createErrorType("Unresolved java class: " + classType.getPresentableText());
|
||||
}
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return TypeUtils.makeNullableIfNeeded(typeParameterDescriptor.getDefaultType(), nullable);
|
||||
}
|
||||
|
||||
TypeParameterDescriptor typeParameterDescriptor = typeVariableResolver.getTypeVariable(typeParameter.getName());
|
||||
@Nullable
|
||||
private JetType transformClassType(
|
||||
@NotNull FqName fqName,
|
||||
@NotNull JavaClassType classType,
|
||||
@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);
|
||||
|
||||
// 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);
|
||||
if (nullable) {
|
||||
return TypeUtils.makeNullable(typeParameterDescriptor.getDefaultType());
|
||||
}
|
||||
else {
|
||||
return typeParameterDescriptor.getDefaultType();
|
||||
ClassDescriptor classData = JavaToKotlinClassMap.getInstance().mapKotlinClass(fqName, howThisTypeIsUsed);
|
||||
|
||||
if (classData == null) {
|
||||
classData = classResolver.resolveClass(fqName, INCLUDE_KOTLIN_SOURCES);
|
||||
}
|
||||
if (classData == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<TypeProjection> arguments = Lists.newArrayList();
|
||||
List<TypeParameterDescriptor> parameters = classData.getTypeConstructor().getParameters();
|
||||
if (isRaw(classType, !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 TypeProjection(projectionKind, KotlinBuiltIns.getInstance().getNullableAnyType()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// '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);
|
||||
PsiType[] psiArguments = classType.getPsi().getParameters();
|
||||
|
||||
FqName fqName = javaClass.getFqName();
|
||||
assert fqName != null : "Class type should have a FQ name: " + javaClass;
|
||||
if (parameters.size() != psiArguments.length) {
|
||||
// Most of the time this means there is an error in the Java code
|
||||
LOG.warn("parameters = " + parameters.size() + ", actual arguments = " + psiArguments.length +
|
||||
" in " + classType.getPresentableText() + "\n fqName: \n" + fqName);
|
||||
|
||||
ClassDescriptor classData = JavaToKotlinClassMap.getInstance().mapKotlinClass(fqName, howThisTypeIsUsed);
|
||||
|
||||
if (classData == null) {
|
||||
classData = classResolver.resolveClass(fqName, INCLUDE_KOTLIN_SOURCES);
|
||||
}
|
||||
if (classData == null) {
|
||||
return ErrorUtils.createErrorType("Unresolved java class: " + classType.getPresentableText());
|
||||
}
|
||||
|
||||
List<TypeProjection> arguments = Lists.newArrayList();
|
||||
List<TypeParameterDescriptor> parameters = classData.getTypeConstructor().getParameters();
|
||||
if (isRaw(classType, !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 TypeProjection(projectionKind, KotlinBuiltIns.getInstance().getNullableAnyType()));
|
||||
arguments.add(new TypeProjection(ErrorUtils.createErrorType(parameter.getName().asString())));
|
||||
}
|
||||
}
|
||||
else {
|
||||
PsiType[] psiArguments = classType.getPsi().getParameters();
|
||||
for (int i = 0; i < parameters.size(); i++) {
|
||||
PsiType psiArgument = psiArguments[i];
|
||||
TypeParameterDescriptor typeParameterDescriptor = parameters.get(i);
|
||||
|
||||
if (parameters.size() != psiArguments.length) {
|
||||
// Most of the time this means there is an error in the Java code
|
||||
LOG.warn("parameters = " + parameters.size() + ", actual arguments = " + psiArguments.length +
|
||||
" in " + classType.getPresentableText() + "\n PsiClass: \n" + psiClass.getText());
|
||||
TypeUsage howTheProjectionIsUsed = howThisTypeIsUsed == SUPERTYPE ? SUPERTYPE_ARGUMENT : TYPE_ARGUMENT;
|
||||
TypeProjection typeProjection = transformToTypeProjection(
|
||||
JavaType.create(psiArgument), typeParameterDescriptor, typeVariableResolver,
|
||||
howTheProjectionIsUsed);
|
||||
|
||||
for (TypeParameterDescriptor parameter : parameters) {
|
||||
arguments.add(new TypeProjection(ErrorUtils.createErrorType(parameter.getName().asString())));
|
||||
if (typeProjection.getProjectionKind() == typeParameterDescriptor.getVariance()) {
|
||||
// remove redundant 'out' and 'in'
|
||||
arguments.add(new TypeProjection(INVARIANT, typeProjection.getType()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < parameters.size(); i++) {
|
||||
PsiType psiArgument = psiArguments[i];
|
||||
TypeParameterDescriptor typeParameterDescriptor = parameters.get(i);
|
||||
|
||||
TypeUsage howTheProjectionIsUsed = howThisTypeIsUsed == SUPERTYPE ? SUPERTYPE_ARGUMENT : TYPE_ARGUMENT;
|
||||
TypeProjection typeProjection = transformToTypeProjection(
|
||||
JavaType.create(psiArgument), typeParameterDescriptor, typeVariableResolver,
|
||||
howTheProjectionIsUsed);
|
||||
|
||||
if (typeProjection.getProjectionKind() == typeParameterDescriptor.getVariance()) {
|
||||
// remove redundant 'out' and 'in'
|
||||
arguments.add(new TypeProjection(INVARIANT, typeProjection.getType()));
|
||||
}
|
||||
else {
|
||||
arguments.add(typeProjection);
|
||||
}
|
||||
else {
|
||||
arguments.add(typeProjection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new JetTypeImpl(
|
||||
Collections.<AnnotationDescriptor>emptyList(),
|
||||
classData.getTypeConstructor(),
|
||||
nullable,
|
||||
arguments,
|
||||
classData.getMemberScope(arguments));
|
||||
}
|
||||
|
||||
return new JetTypeImpl(
|
||||
Collections.<AnnotationDescriptor>emptyList(),
|
||||
classData.getTypeConstructor(),
|
||||
nullable,
|
||||
arguments,
|
||||
classData.getMemberScope(arguments));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+5
-2
@@ -34,6 +34,7 @@ import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmByte
|
||||
import org.jetbrains.jet.lang.resolve.java.kotlinSignature.SignaturesUtil;
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaClassType;
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaClassifier;
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
@@ -378,10 +379,12 @@ public class SingleAbstractMethodUtils {
|
||||
private boolean find(@NotNull JavaClassType classType) {
|
||||
PsiClassType.ClassResolveResult classResolveResult = classType.getPsi().resolveGenerics();
|
||||
PsiSubstitutor classSubstitutor = classResolveResult.getSubstitutor();
|
||||
JavaClass javaClass = classType.resolve();
|
||||
if (javaClass == null) {
|
||||
JavaClassifier javaClassifier = classType.resolve();
|
||||
if (javaClassifier == null) {
|
||||
return false; // can't resolve class -> not a SAM interface
|
||||
}
|
||||
assert javaClassifier instanceof JavaClass : "Classifier should be a class here: " + javaClassifier;
|
||||
JavaClass javaClass = (JavaClass) javaClassifier;
|
||||
if (new FqName(CommonClassNames.JAVA_LANG_OBJECT).equals(javaClass.getFqName())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+1
-1
@@ -97,7 +97,7 @@ public final class JavaPackageScope extends JavaBaseScope {
|
||||
}
|
||||
|
||||
for (JavaClass javaClass : DescriptorResolverUtils.filterDuplicateClasses(javaPackage.getClasses())) {
|
||||
if (DescriptorResolverUtils.isCompiledKotlinPackageClass(javaClass)) continue;
|
||||
if (DescriptorResolverUtils.isCompiledKotlinPackageClass(javaClass.getPsi())) continue;
|
||||
|
||||
if (isKotlinLightClass(javaClass)) continue;
|
||||
|
||||
|
||||
+32
-7
@@ -19,11 +19,13 @@ package org.jetbrains.jet.lang.resolve.java.structure;
|
||||
import com.intellij.psi.PsiAnnotation;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiModifierList;
|
||||
import com.intellij.psi.PsiTypeParameter;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassKind;
|
||||
import org.jetbrains.jet.lang.descriptors.Modality;
|
||||
import org.jetbrains.jet.lang.descriptors.Visibility;
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
|
||||
@@ -31,15 +33,11 @@ import java.util.Collection;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.java.structure.JavaElementCollectionFromPsiArrayUtil.*;
|
||||
|
||||
public class JavaClass extends JavaModifierListOwnerImpl implements JavaNamedElement, JavaTypeParameterListOwner {
|
||||
public class JavaClass extends JavaClassifier implements JavaNamedElement, JavaTypeParameterListOwner, JavaModifierListOwner {
|
||||
public JavaClass(@NotNull PsiClass psiClass) {
|
||||
super(psiClass);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClass getPsi() {
|
||||
return (PsiClass) super.getPsi();
|
||||
assert !(psiClass instanceof PsiTypeParameter)
|
||||
: "PsiTypeParameter should be wrapped in JavaTypeParameter, not JavaClass: use JavaClassifier.create()";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -136,4 +134,31 @@ public class JavaClass extends JavaModifierListOwnerImpl implements JavaNamedEle
|
||||
public Collection<JavaMethod> getConstructors() {
|
||||
return methods(getPsi().getConstructors());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAbstract() {
|
||||
return JavaElementUtil.isAbstract(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStatic() {
|
||||
return JavaElementUtil.isStatic(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinal() {
|
||||
return JavaElementUtil.isFinal(this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Visibility getVisibility() {
|
||||
return JavaElementUtil.getVisibility(this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<JavaAnnotation> getAnnotations() {
|
||||
return JavaElementUtil.getAnnotations(this);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -39,9 +39,9 @@ public class JavaClassType extends JavaType {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JavaClass resolve() {
|
||||
public JavaClassifier resolve() {
|
||||
PsiClass psiClass = getPsi().resolve();
|
||||
return psiClass == null ? null : new JavaClass(psiClass);
|
||||
return psiClass == null ? null : JavaClassifier.create(psiClass);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.structure;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiTypeParameter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class JavaClassifier extends JavaElementImpl {
|
||||
protected JavaClassifier(@NotNull PsiClass psiClass) {
|
||||
super(psiClass);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClass getPsi() {
|
||||
return (PsiClass) super.getPsi();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JavaClassifier create(@NotNull PsiClass psiClass) {
|
||||
if (psiClass instanceof PsiTypeParameter) {
|
||||
return new JavaTypeParameter((PsiTypeParameter) psiClass);
|
||||
}
|
||||
else {
|
||||
return new JavaClass(psiClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
+21
-34
@@ -18,7 +18,6 @@ package org.jetbrains.jet.lang.resolve.java.structure;
|
||||
|
||||
import com.intellij.psi.PsiModifier;
|
||||
import com.intellij.psi.PsiModifierList;
|
||||
import com.intellij.psi.PsiModifierListOwner;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.Visibilities;
|
||||
import org.jetbrains.jet.lang.descriptors.Visibility;
|
||||
@@ -29,51 +28,39 @@ import java.util.Collections;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.java.structure.JavaElementCollectionFromPsiArrayUtil.annotations;
|
||||
|
||||
public abstract class JavaModifierListOwnerImpl extends JavaElementImpl implements JavaModifierListOwner {
|
||||
protected JavaModifierListOwnerImpl(@NotNull PsiModifierListOwner psiModifierListOwner) {
|
||||
super(psiModifierListOwner);
|
||||
/* package */ class JavaElementUtil {
|
||||
private JavaElementUtil() {
|
||||
}
|
||||
|
||||
public static boolean isAbstract(@NotNull JavaModifierListOwner owner) {
|
||||
return owner.getPsi().hasModifierProperty(PsiModifier.ABSTRACT);
|
||||
}
|
||||
|
||||
public static boolean isStatic(@NotNull JavaModifierListOwner owner) {
|
||||
return owner.getPsi().hasModifierProperty(PsiModifier.STATIC);
|
||||
}
|
||||
|
||||
public static boolean isFinal(@NotNull JavaModifierListOwner owner) {
|
||||
return owner.getPsi().hasModifierProperty(PsiModifier.FINAL);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiModifierListOwner getPsi() {
|
||||
return (PsiModifierListOwner) super.getPsi();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAbstract() {
|
||||
return getPsi().hasModifierProperty(PsiModifier.ABSTRACT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStatic() {
|
||||
return getPsi().hasModifierProperty(PsiModifier.STATIC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinal() {
|
||||
return getPsi().hasModifierProperty(PsiModifier.FINAL);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Visibility getVisibility() {
|
||||
if (getPsi().hasModifierProperty(PsiModifier.PUBLIC)) {
|
||||
public static Visibility getVisibility(@NotNull JavaModifierListOwner owner) {
|
||||
if (owner.getPsi().hasModifierProperty(PsiModifier.PUBLIC)) {
|
||||
return Visibilities.PUBLIC;
|
||||
}
|
||||
if (getPsi().hasModifierProperty(PsiModifier.PRIVATE)) {
|
||||
if (owner.getPsi().hasModifierProperty(PsiModifier.PRIVATE)) {
|
||||
return Visibilities.PRIVATE;
|
||||
}
|
||||
if (getPsi().hasModifierProperty(PsiModifier.PROTECTED)) {
|
||||
return isStatic() ? JavaVisibilities.PROTECTED_STATIC_VISIBILITY : JavaVisibilities.PROTECTED_AND_PACKAGE;
|
||||
if (owner.getPsi().hasModifierProperty(PsiModifier.PROTECTED)) {
|
||||
return owner.isStatic() ? JavaVisibilities.PROTECTED_STATIC_VISIBILITY : JavaVisibilities.PROTECTED_AND_PACKAGE;
|
||||
}
|
||||
return JavaVisibilities.PACKAGE_VISIBILITY;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<JavaAnnotation> getAnnotations() {
|
||||
PsiModifierList modifierList = getPsi().getModifierList();
|
||||
public static Collection<JavaAnnotation> getAnnotations(@NotNull JavaModifierListOwner owner) {
|
||||
PsiModifierList modifierList = owner.getPsi().getModifierList();
|
||||
if (modifierList != null) {
|
||||
return annotations(modifierList.getAnnotations());
|
||||
}
|
||||
-9
@@ -16,11 +16,9 @@
|
||||
|
||||
package org.jetbrains.jet.lang.resolve.java.structure;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiEnumConstant;
|
||||
import com.intellij.psi.PsiField;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class JavaField extends JavaMemberImpl {
|
||||
public JavaField(@NotNull PsiField psiField) {
|
||||
@@ -33,13 +31,6 @@ public class JavaField extends JavaMemberImpl {
|
||||
return (PsiField) super.getPsi();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public JavaClass getContainingClass() {
|
||||
PsiClass psiClass = getPsi().getContainingClass();
|
||||
return psiClass == null ? null : new JavaClass(psiClass);
|
||||
}
|
||||
|
||||
public boolean isEnumEntry() {
|
||||
return getPsi() instanceof PsiEnumConstant;
|
||||
}
|
||||
|
||||
+41
-1
@@ -16,11 +16,16 @@
|
||||
|
||||
package org.jetbrains.jet.lang.resolve.java.structure;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiMember;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.Visibility;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
|
||||
public abstract class JavaMemberImpl extends JavaModifierListOwnerImpl implements JavaMember {
|
||||
import java.util.Collection;
|
||||
|
||||
public abstract class JavaMemberImpl extends JavaElementImpl implements JavaMember, JavaModifierListOwner {
|
||||
protected JavaMemberImpl(@NotNull PsiMember psiMember) {
|
||||
super(psiMember);
|
||||
}
|
||||
@@ -38,4 +43,39 @@ public abstract class JavaMemberImpl extends JavaModifierListOwnerImpl implement
|
||||
assert name != null : "Member must have a name: " + getPsi();
|
||||
return Name.identifier(name);
|
||||
}
|
||||
|
||||
// TODO: NotNull?
|
||||
@Nullable
|
||||
@Override
|
||||
public JavaClass getContainingClass() {
|
||||
PsiClass psiClass = getPsi().getContainingClass();
|
||||
return psiClass == null ? null : new JavaClass(psiClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAbstract() {
|
||||
return JavaElementUtil.isAbstract(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStatic() {
|
||||
return JavaElementUtil.isStatic(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinal() {
|
||||
return JavaElementUtil.isFinal(this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Visibility getVisibility() {
|
||||
return JavaElementUtil.getVisibility(this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<JavaAnnotation> getAnnotations() {
|
||||
return JavaElementUtil.getAnnotations(this);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-9
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.jet.lang.resolve.java.structure;
|
||||
|
||||
import com.intellij.psi.PsiAnnotationMethod;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -46,14 +45,6 @@ public class JavaMethod extends JavaMemberImpl implements JavaTypeParameterListO
|
||||
return Name.identifier(getPsi().getName());
|
||||
}
|
||||
|
||||
// TODO: NotNull?
|
||||
@Nullable
|
||||
@Override
|
||||
public JavaClass getContainingClass() {
|
||||
PsiClass psiClass = getPsi().getContainingClass();
|
||||
return psiClass == null ? null : new JavaClass(psiClass);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<JavaTypeParameter> getTypeParameters() {
|
||||
@@ -83,4 +74,9 @@ public class JavaMethod extends JavaMemberImpl implements JavaTypeParameterListO
|
||||
public boolean isVararg() {
|
||||
return getPsi().isVarArgs();
|
||||
}
|
||||
|
||||
public boolean isConstructor() {
|
||||
// TODO: class JavaConstructor extends JavaMethod
|
||||
return getPsi().isConstructor();
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -16,12 +16,17 @@
|
||||
|
||||
package org.jetbrains.jet.lang.resolve.java.structure;
|
||||
|
||||
import com.intellij.psi.PsiModifierListOwner;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.Visibility;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface JavaModifierListOwner extends JavaElement {
|
||||
@NotNull
|
||||
@Override
|
||||
PsiModifierListOwner getPsi();
|
||||
|
||||
boolean isAbstract();
|
||||
|
||||
boolean isStatic();
|
||||
|
||||
+22
-1
@@ -16,15 +16,19 @@
|
||||
|
||||
package org.jetbrains.jet.lang.resolve.java.structure;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiTypeParameter;
|
||||
import com.intellij.psi.PsiTypeParameterListOwner;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.java.structure.JavaElementCollectionFromPsiArrayUtil.classTypes;
|
||||
|
||||
public class JavaTypeParameter extends JavaElementImpl implements JavaNamedElement {
|
||||
public class JavaTypeParameter extends JavaClassifier implements JavaNamedElement {
|
||||
public JavaTypeParameter(@NotNull PsiTypeParameter psiTypeParameter) {
|
||||
super(psiTypeParameter);
|
||||
}
|
||||
@@ -49,4 +53,21 @@ public class JavaTypeParameter extends JavaElementImpl implements JavaNamedEleme
|
||||
public Collection<JavaClassType> getUpperBounds() {
|
||||
return classTypes(getPsi().getExtendsList().getReferencedTypes());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JavaTypeParameterListOwner getOwner() {
|
||||
PsiTypeParameterListOwner owner = getPsi().getOwner();
|
||||
// TODO: a separate factory for such things
|
||||
if (owner instanceof PsiMethod) {
|
||||
return new JavaMethod((PsiMethod) owner);
|
||||
}
|
||||
else if (owner instanceof PsiClass) {
|
||||
return new JavaClass((PsiClass) owner);
|
||||
}
|
||||
else if (owner != null) {
|
||||
throw new UnsupportedOperationException("Unsupported type parameter list owner: " + owner);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user