Cleanup JavaElement model from methods used only in substitutor

Downcast everything used in JavaTypeSubstitutorImpl to *Impl, remove methods
from interfaces, inline/move some of them
This commit is contained in:
Alexander Udalov
2016-03-17 17:29:43 +03:00
parent 26bf0dca13
commit 291c713d8b
21 changed files with 106 additions and 297 deletions
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.load.java.structure.impl;
import com.intellij.psi.PsiArrayType; import com.intellij.psi.PsiArrayType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.load.java.structure.JavaArrayType; import org.jetbrains.kotlin.load.java.structure.JavaArrayType;
import org.jetbrains.kotlin.load.java.structure.JavaType;
public class JavaArrayTypeImpl extends JavaTypeImpl<PsiArrayType> implements JavaArrayType { public class JavaArrayTypeImpl extends JavaTypeImpl<PsiArrayType> implements JavaArrayType {
public JavaArrayTypeImpl(@NotNull PsiArrayType psiArrayType) { public JavaArrayTypeImpl(@NotNull PsiArrayType psiArrayType) {
@@ -28,7 +27,7 @@ public class JavaArrayTypeImpl extends JavaTypeImpl<PsiArrayType> implements Jav
@Override @Override
@NotNull @NotNull
public JavaType getComponentType() { public JavaTypeImpl<?> getComponentType() {
return JavaTypeImpl.create(getPsi().getComponentType()); return JavaTypeImpl.create(getPsi().getComponentType());
} }
} }
@@ -78,7 +78,7 @@ public class JavaClassImpl extends JavaClassifierImpl<PsiClass> implements JavaC
@Override @Override
@Nullable @Nullable
public JavaClass getOuterClass() { public JavaClassImpl getOuterClass() {
PsiClass outer = getPsi().getContainingClass(); PsiClass outer = getPsi().getContainingClass();
return outer == null ? null : new JavaClassImpl(outer); return outer == null ? null : new JavaClassImpl(outer);
} }
@@ -154,12 +154,6 @@ public class JavaClassImpl extends JavaClassifierImpl<PsiClass> implements JavaC
return JavaElementUtil.getVisibility(this); return JavaElementUtil.getVisibility(this);
} }
@Override
@NotNull
public JavaClassifierType getDefaultType() {
return new JavaClassifierTypeImpl(JavaPsiFacade.getElementFactory(getPsi().getProject()).createType(getPsi()));
}
@Override @Override
@NotNull @NotNull
public OriginKind getOriginKind() { public OriginKind getOriginKind() {
@@ -176,25 +170,24 @@ public class JavaClassImpl extends JavaClassifierImpl<PsiClass> implements JavaC
} }
@NotNull @NotNull
public JavaType createImmediateType(@NotNull JavaTypeSubstitutorImpl substitutor) { /* package */ JavaTypeImpl<?> createImmediateType(@NotNull Map<JavaTypeParameterImpl, JavaTypeImpl<?>> substitutionMap) {
return new JavaClassifierTypeImpl( return new JavaClassifierTypeImpl(
JavaPsiFacade.getElementFactory(getPsi().getProject()).createType(getPsi(), createPsiSubstitutor(substitutor))); JavaPsiFacade.getElementFactory(getPsi().getProject()).createType(getPsi(), createPsiSubstitutor(substitutionMap))
);
} }
@NotNull @NotNull
private static PsiSubstitutor createPsiSubstitutor(@NotNull JavaTypeSubstitutorImpl substitutor) { private static PsiSubstitutor createPsiSubstitutor(@NotNull Map<JavaTypeParameterImpl, JavaTypeImpl<?>> substitutionMap) {
Map<PsiTypeParameter, PsiType> substMap = new HashMap<PsiTypeParameter, PsiType>(); if (substitutionMap.isEmpty()) return PsiSubstitutor.EMPTY;
for (Map.Entry<JavaTypeParameter, JavaType> entry : substitutor.getSubstitutionMap().entrySet()) {
PsiTypeParameter key = ((JavaTypeParameterImpl) entry.getKey()).getPsi(); Map<PsiTypeParameter, PsiType> result = new HashMap<PsiTypeParameter, PsiType>();
if (entry.getValue() == null) { for (Map.Entry<JavaTypeParameterImpl, JavaTypeImpl<?>> entry : substitutionMap.entrySet()) {
substMap.put(key, null); PsiTypeParameter key = entry.getKey().getPsi();
} JavaTypeImpl<?> value = entry.getValue();
else { result.put(key, value == null ? null : value.getPsi());
substMap.put(key, ((JavaTypeImpl) entry.getValue()).getPsi());
}
} }
return PsiSubstitutorImpl.createSubstitutor(substMap); return PsiSubstitutorImpl.createSubstitutor(result);
} }
@Nullable @Nullable
@@ -32,7 +32,7 @@ public abstract class JavaClassifierImpl<Psi extends PsiClass> extends JavaEleme
} }
@NotNull @NotNull
/* package */ static JavaClassifier create(@NotNull PsiClass psiClass) { /* package */ static JavaClassifierImpl<?> create(@NotNull PsiClass psiClass) {
if (psiClass instanceof PsiTypeParameter) { if (psiClass instanceof PsiTypeParameter) {
return new JavaTypeParameterImpl((PsiTypeParameter) psiClass); return new JavaTypeParameterImpl((PsiTypeParameter) psiClass);
} }
@@ -19,20 +19,18 @@ package org.jetbrains.kotlin.load.java.structure.impl;
import com.intellij.psi.*; import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.load.java.structure.JavaClassifier;
import org.jetbrains.kotlin.load.java.structure.JavaClassifierType; import org.jetbrains.kotlin.load.java.structure.JavaClassifierType;
import org.jetbrains.kotlin.load.java.structure.JavaType; import org.jetbrains.kotlin.load.java.structure.JavaType;
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter;
import java.util.*; import java.util.*;
public class JavaClassifierTypeImpl extends JavaTypeImpl<PsiClassType> implements JavaClassifierType { public class JavaClassifierTypeImpl extends JavaTypeImpl<PsiClassType> implements JavaClassifierType {
private static class ResolutionResult { private static class ResolutionResult {
private final JavaClassifier classifier; private final JavaClassifierImpl<?> classifier;
private final JavaTypeSubstitutorImpl substitutor; private final JavaTypeSubstitutorImpl substitutor;
private final boolean isRaw; private final boolean isRaw;
private ResolutionResult(@Nullable JavaClassifier classifier, @NotNull JavaTypeSubstitutorImpl substitutor, boolean isRaw) { private ResolutionResult(@Nullable JavaClassifierImpl<?> classifier, @NotNull JavaTypeSubstitutorImpl substitutor, boolean isRaw) {
this.classifier = classifier; this.classifier = classifier;
this.substitutor = substitutor; this.substitutor = substitutor;
this.isRaw = isRaw; this.isRaw = isRaw;
@@ -47,7 +45,7 @@ public class JavaClassifierTypeImpl extends JavaTypeImpl<PsiClassType> implement
@Override @Override
@Nullable @Nullable
public JavaClassifier getClassifier() { public JavaClassifierImpl<?> getClassifier() {
resolve(); resolve();
return resolutionResult.classifier; return resolutionResult.classifier;
} }
@@ -66,35 +64,21 @@ public class JavaClassifierTypeImpl extends JavaTypeImpl<PsiClassType> implement
resolutionResult = new ResolutionResult( resolutionResult = new ResolutionResult(
psiClass == null ? null : JavaClassifierImpl.create(psiClass), psiClass == null ? null : JavaClassifierImpl.create(psiClass),
new JavaTypeSubstitutorImpl(convertSubstitutionMap(substitutor.getSubstitutionMap())), new JavaTypeSubstitutorImpl(convertSubstitutionMap(substitutor.getSubstitutionMap())),
PsiClassType.isRaw(result)); PsiClassType.isRaw(result)
);
} }
} }
@NotNull @NotNull
private static Map<JavaTypeParameter, JavaType> convertSubstitutionMap(@NotNull Map<PsiTypeParameter, PsiType> psiMap) { private static Map<JavaTypeParameterImpl, JavaTypeImpl<?>> convertSubstitutionMap(@NotNull Map<PsiTypeParameter, PsiType> psiMap) {
if (psiMap.isEmpty()) return Collections.emptyMap(); if (psiMap.isEmpty()) return Collections.emptyMap();
Map<JavaTypeParameter, JavaType> substitutionMap = new HashMap<JavaTypeParameter, JavaType>(); Map<JavaTypeParameterImpl, JavaTypeImpl<?>> result = new HashMap<JavaTypeParameterImpl, JavaTypeImpl<?>>();
for (Map.Entry<PsiTypeParameter, PsiType> entry : psiMap.entrySet()) { for (Map.Entry<PsiTypeParameter, PsiType> entry : psiMap.entrySet()) {
PsiType value = entry.getValue(); PsiType value = entry.getValue();
substitutionMap.put(new JavaTypeParameterImpl(entry.getKey()), value == null ? null : JavaTypeImpl.create(value)); result.put(new JavaTypeParameterImpl(entry.getKey()), value == null ? null : JavaTypeImpl.create(value));
} }
return substitutionMap;
}
@Override
@NotNull
public Collection<JavaClassifierType> getSupertypes() {
PsiType[] psiTypes = getPsi().getSuperTypes();
if (psiTypes.length == 0) return Collections.emptyList();
List<JavaClassifierType> result = new ArrayList<JavaClassifierType>(psiTypes.length);
for (PsiType psiType : psiTypes) {
if (!(psiType instanceof PsiClassType)) {
throw new IllegalStateException("Supertype should be a class: " + psiType + ", type: " + getPsi());
}
result.add(new JavaClassifierTypeImpl((PsiClassType) psiType));
}
return result; return result;
} }
@@ -113,11 +97,11 @@ public class JavaClassifierTypeImpl extends JavaTypeImpl<PsiClassType> implement
@Override @Override
@NotNull @NotNull
public List<JavaType> getTypeArguments() { public List<JavaType> getTypeArguments() {
JavaClassifier classifier = getClassifier(); JavaClassifierImpl<?> classifier = getClassifier();
// parameters including ones from outer class // parameters including ones from outer class
Iterable<PsiTypeParameter> parameters = classifier instanceof JavaClassImpl Iterable<PsiTypeParameter> parameters = classifier instanceof JavaClassImpl
? getTypeParameters(((JavaClassImpl) classifier).getPsi()) ? getTypeParameters(classifier.getPsi())
: Collections.<PsiTypeParameter>emptyList(); : Collections.<PsiTypeParameter>emptyList();
JavaTypeSubstitutorImpl substitutor = getSubstitutor(); JavaTypeSubstitutorImpl substitutor = getSubstitutor();
@@ -20,7 +20,6 @@ import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation; import org.jetbrains.kotlin.load.java.structure.JavaAnnotation;
import org.jetbrains.kotlin.load.java.structure.JavaArrayType;
import org.jetbrains.kotlin.load.java.structure.JavaType; import org.jetbrains.kotlin.load.java.structure.JavaType;
import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.FqName;
@@ -79,12 +78,6 @@ public abstract class JavaTypeImpl<Psi extends PsiType> implements JavaType, Jav
}); });
} }
@NotNull
@Override
public JavaArrayType createArrayType() {
return new JavaArrayTypeImpl(getPsi().createArrayType());
}
@NotNull @NotNull
@Override @Override
public Collection<JavaAnnotation> getAnnotations() { public Collection<JavaAnnotation> getAnnotations() {
@@ -16,10 +16,12 @@
package org.jetbrains.kotlin.load.java.structure.impl; package org.jetbrains.kotlin.load.java.structure.impl;
import com.intellij.psi.*; import com.intellij.psi.PsiAnnotationOwner;
import com.intellij.psi.PsiTypeParameter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.load.java.structure.*; import org.jetbrains.kotlin.load.java.structure.JavaClassifierType;
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
import java.util.Collection; import java.util.Collection;
@@ -43,37 +45,6 @@ public class JavaTypeParameterImpl extends JavaClassifierImpl<PsiTypeParameter>
return classifierTypes(getPsi().getExtendsList().getReferencedTypes()); return classifierTypes(getPsi().getExtendsList().getReferencedTypes());
} }
@Override
@Nullable
public JavaTypeParameterListOwner getOwner() {
PsiTypeParameterListOwner owner = getPsi().getOwner();
// TODO: a separate factory for such things
if (owner instanceof PsiMethod) {
PsiMethod psiMethod = (PsiMethod) owner;
return psiMethod.isConstructor() ? new JavaConstructorImpl(psiMethod) : new JavaMethodImpl(psiMethod);
}
else if (owner instanceof PsiClass) {
return new JavaClassImpl((PsiClass) owner);
}
else if (owner != null) {
throw new UnsupportedOperationException("Unsupported type parameter list owner: " + owner);
}
return null;
}
@NotNull
@Override
public JavaType getType() {
return JavaTypeImpl.create(JavaPsiFacade.getInstance(getPsi().getProject()).getElementFactory().createType(getPsi()));
}
@Override
@NotNull
public JavaTypeProvider getTypeProvider() {
return new JavaTypeProviderImpl(getPsi().getManager());
}
@Nullable @Nullable
@Override @Override
public PsiAnnotationOwner getAnnotationOwnerPsi() { public PsiAnnotationOwner getAnnotationOwnerPsi() {
@@ -1,58 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.load.java.structure.impl;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiType;
import com.intellij.psi.PsiWildcardType;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.load.java.structure.JavaType;
import org.jetbrains.kotlin.load.java.structure.JavaTypeProvider;
import org.jetbrains.kotlin.load.java.structure.JavaWildcardType;
public class JavaTypeProviderImpl implements JavaTypeProvider {
private final PsiManager manager;
public JavaTypeProviderImpl(@NotNull PsiManager manager) {
this.manager = manager;
}
@Override
@NotNull
public JavaType createJavaLangObjectType() {
return JavaTypeImpl.create(PsiType.getJavaLangObject(manager, GlobalSearchScope.allScope(manager.getProject())));
}
@NotNull
@Override
public JavaWildcardType createUpperBoundWildcard(@NotNull JavaType bound) {
return new JavaWildcardTypeImpl(PsiWildcardType.createExtends(manager, ((JavaTypeImpl) bound).getPsi()));
}
@NotNull
@Override
public JavaWildcardType createLowerBoundWildcard(@NotNull JavaType bound) {
return new JavaWildcardTypeImpl(PsiWildcardType.createSuper(manager, ((JavaTypeImpl) bound).getPsi()));
}
@NotNull
@Override
public JavaWildcardType createUnboundedWildcard() {
return new JavaWildcardTypeImpl(PsiWildcardType.createUnbounded(manager));
}
}
@@ -16,9 +16,13 @@
package org.jetbrains.kotlin.load.java.structure.impl; package org.jetbrains.kotlin.load.java.structure.impl;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.load.java.structure.*; import org.jetbrains.kotlin.load.java.structure.JavaClassifier;
import org.jetbrains.kotlin.load.java.structure.JavaClassifierType;
import org.jetbrains.kotlin.load.java.structure.JavaPrimitiveType;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
@@ -26,15 +30,15 @@ import java.util.List;
import java.util.Map; import java.util.Map;
public class JavaTypeSubstitutorImpl { public class JavaTypeSubstitutorImpl {
private final Map<JavaTypeParameter, JavaType> substitutionMap; private final Map<JavaTypeParameterImpl, JavaTypeImpl<?>> substitutionMap;
public JavaTypeSubstitutorImpl(@NotNull Map<JavaTypeParameter, JavaType> substitutionMap) { public JavaTypeSubstitutorImpl(@NotNull Map<JavaTypeParameterImpl, JavaTypeImpl<?>> substitutionMap) {
this.substitutionMap = substitutionMap; this.substitutionMap = substitutionMap;
} }
@NotNull @NotNull
public JavaType substitute(@NotNull JavaType type) { public JavaTypeImpl<?> substitute(@NotNull JavaTypeImpl<?> type) {
JavaType substitutedType = substituteInternal(type); JavaTypeImpl<?> substitutedType = substituteInternal(type);
return substitutedType != null ? substitutedType : correctSubstitutionForRawType(type); return substitutedType != null ? substitutedType : correctSubstitutionForRawType(type);
} }
@@ -42,11 +46,11 @@ public class JavaTypeSubstitutorImpl {
// In case of raw type we get substitution map like T -> null, // In case of raw type we get substitution map like T -> null,
// in this case we should substitute upper bound of T or, // in this case we should substitute upper bound of T or,
// if it does not exist, return java.lang.Object // if it does not exist, return java.lang.Object
private JavaType correctSubstitutionForRawType(@NotNull JavaType original) { private JavaTypeImpl<?> correctSubstitutionForRawType(@NotNull JavaTypeImpl<?> original) {
if (original instanceof JavaClassifierType) { if (original instanceof JavaClassifierType) {
JavaClassifier classifier = ((JavaClassifierType) original).getClassifier(); JavaClassifier classifier = ((JavaClassifierType) original).getClassifier();
if (classifier instanceof JavaTypeParameter) { if (classifier instanceof JavaTypeParameterImpl) {
return rawTypeForTypeParameter((JavaTypeParameter) classifier); return rawTypeForTypeParameter((JavaTypeParameterImpl) classifier);
} }
} }
@@ -54,20 +58,20 @@ public class JavaTypeSubstitutorImpl {
} }
@Nullable @Nullable
private JavaType substituteInternal(@NotNull JavaType type) { private JavaTypeImpl<?> substituteInternal(@NotNull JavaTypeImpl<?> type) {
if (type instanceof JavaClassifierType) { if (type instanceof JavaClassifierTypeImpl) {
JavaClassifierType classifierType = (JavaClassifierType) type; JavaClassifierTypeImpl classifierType = (JavaClassifierTypeImpl) type;
JavaClassifier classifier = classifierType.getClassifier(); JavaClassifierImpl<?> classifier = classifierType.getClassifier();
if (classifier instanceof JavaTypeParameter) { if (classifier instanceof JavaTypeParameterImpl) {
return substitute((JavaTypeParameter) classifier); return substitute((JavaTypeParameterImpl) classifier);
} }
else if (classifier instanceof JavaClassImpl) { else if (classifier instanceof JavaClassImpl) {
JavaClassImpl javaClass = (JavaClassImpl) classifier; JavaClassImpl javaClass = (JavaClassImpl) classifier;
Map<JavaTypeParameter, JavaType> substMap = new HashMap<JavaTypeParameter, JavaType>(); Map<JavaTypeParameterImpl, JavaTypeImpl<?>> substMap = new HashMap<JavaTypeParameterImpl, JavaTypeImpl<?>>();
processClass(javaClass, ((JavaClassifierTypeImpl) classifierType).getSubstitutor(), substMap); processClass(javaClass, classifierType.getSubstitutor(), substMap);
return javaClass.createImmediateType(new JavaTypeSubstitutorImpl(substMap)); return javaClass.createImmediateType(substMap);
} }
return type; return type;
@@ -75,52 +79,50 @@ public class JavaTypeSubstitutorImpl {
else if (type instanceof JavaPrimitiveType) { else if (type instanceof JavaPrimitiveType) {
return type; return type;
} }
else if (type instanceof JavaArrayType) { else if (type instanceof JavaArrayTypeImpl) {
JavaType componentType = ((JavaArrayType) type).getComponentType(); JavaTypeImpl<?> componentType = ((JavaArrayTypeImpl) type).getComponentType();
JavaType substitutedComponentType = substitute(componentType); JavaTypeImpl<?> substitutedComponentType = substitute(componentType);
if (substitutedComponentType == componentType) return type; if (substitutedComponentType == componentType) return type;
return substitutedComponentType.createArrayType(); return new JavaArrayTypeImpl(substitutedComponentType.getPsi().createArrayType());
} }
else if (type instanceof JavaWildcardType) { else if (type instanceof JavaWildcardTypeImpl) {
return substituteWildcardType((JavaWildcardType) type); return substituteWildcardType((JavaWildcardTypeImpl) type);
} }
return type; return type;
} }
private void processClass( private void processClass(
@NotNull JavaClass javaClass, @NotNull JavaTypeSubstitutorImpl substitutor, @NotNull Map<JavaTypeParameter, JavaType> substMap @NotNull JavaClassImpl javaClass,
@NotNull JavaTypeSubstitutorImpl substitutor,
@NotNull Map<JavaTypeParameterImpl, JavaTypeImpl<?>> substMap
) { ) {
List<JavaTypeParameter> typeParameters = javaClass.getTypeParameters(); @SuppressWarnings("unchecked")
for (JavaTypeParameter typeParameter : typeParameters) { List<JavaTypeParameterImpl> typeParameters = (List) javaClass.getTypeParameters();
JavaType substitutedParam = substitutor.substitute(typeParameter); for (JavaTypeParameterImpl typeParameter : typeParameters) {
if (substitutedParam == null) { JavaTypeImpl<?> substitutedParam = substitutor.substitute(typeParameter);
substMap.put(typeParameter, null); substMap.put(typeParameter, substitutedParam == null ? null : substituteInternal(substitutedParam));
}
else {
substMap.put(typeParameter, substituteInternal(substitutedParam));
}
} }
if (javaClass.isStatic()) { if (javaClass.isStatic()) {
return; return;
} }
JavaClass outerClass = javaClass.getOuterClass(); JavaClassImpl outerClass = javaClass.getOuterClass();
if (outerClass != null) { if (outerClass != null) {
processClass(outerClass, substitutor, substMap); processClass(outerClass, substitutor, substMap);
} }
} }
@Nullable @Nullable
private JavaType substituteWildcardType(@NotNull JavaWildcardType wildcardType) { private JavaTypeImpl<?> substituteWildcardType(@NotNull JavaWildcardTypeImpl wildcardType) {
JavaType bound = wildcardType.getBound(); JavaTypeImpl<?> bound = wildcardType.getBound();
if (bound == null) { if (bound == null) {
return wildcardType; return wildcardType;
} }
JavaType newBound = substituteInternal(bound); JavaTypeImpl<?> newBound = substituteInternal(bound);
if (newBound == null) { if (newBound == null) {
// This can be in case of substitution wildcard to raw type // This can be in case of substitution wildcard to raw type
return null; return null;
@@ -130,41 +132,40 @@ public class JavaTypeSubstitutorImpl {
} }
@NotNull @NotNull
private static JavaWildcardType rebound(@NotNull JavaWildcardType type, @NotNull JavaType newBound) { private static JavaWildcardTypeImpl rebound(@NotNull JavaWildcardTypeImpl type, @NotNull JavaTypeImpl<?> newBound) {
if (type.getTypeProvider().createJavaLangObjectType().equals(newBound)) { PsiManager manager = type.getPsi().getManager();
return type.getTypeProvider().createUnboundedWildcard(); if (createJavaLangObjectType(manager).equals(newBound)) {
return createUnboundedWildcard(manager);
} }
if (type.isExtends()) { if (type.isExtends()) {
return type.getTypeProvider().createUpperBoundWildcard(newBound); return createUpperBoundWildcard(manager, newBound);
} }
else { else {
return type.getTypeProvider().createLowerBoundWildcard(newBound); return createLowerBoundWildcard(manager, newBound);
} }
} }
@NotNull @NotNull
private JavaType rawTypeForTypeParameter(@NotNull JavaTypeParameter typeParameter) { private JavaTypeImpl<?> rawTypeForTypeParameter(@NotNull JavaTypeParameterImpl typeParameter) {
Collection<JavaClassifierType> bounds = typeParameter.getUpperBounds(); Collection<JavaClassifierType> bounds = typeParameter.getUpperBounds();
if (!bounds.isEmpty()) { if (!bounds.isEmpty()) {
return substitute(bounds.iterator().next()); return substitute(((JavaClassifierTypeImpl) bounds.iterator().next()));
} }
return typeParameter.getTypeProvider().createJavaLangObjectType(); return createJavaLangObjectType(typeParameter.getPsi().getManager());
} }
@Nullable @Nullable
public JavaType substitute(@NotNull JavaTypeParameter typeParameter) { public JavaTypeImpl<?> substitute(@NotNull JavaTypeParameterImpl typeParameter) {
if (substitutionMap.containsKey(typeParameter)) { if (substitutionMap.containsKey(typeParameter)) {
return substitutionMap.get(typeParameter); return substitutionMap.get(typeParameter);
} }
return typeParameter.getType(); PsiTypeParameter psiTypeParameter = typeParameter.getPsi();
} return JavaTypeImpl.create(
JavaPsiFacade.getInstance(psiTypeParameter.getProject()).getElementFactory().createType(psiTypeParameter)
@NotNull );
public Map<JavaTypeParameter, JavaType> getSubstitutionMap() {
return substitutionMap;
} }
@Override @Override
@@ -181,4 +182,24 @@ public class JavaTypeSubstitutorImpl {
public String toString() { public String toString() {
return getClass().getSimpleName() + ": " + substitutionMap; return getClass().getSimpleName() + ": " + substitutionMap;
} }
@NotNull
private static JavaTypeImpl<?> createJavaLangObjectType(@NotNull PsiManager manager) {
return JavaTypeImpl.create(PsiType.getJavaLangObject(manager, GlobalSearchScope.allScope(manager.getProject())));
}
@NotNull
private static JavaWildcardTypeImpl createUpperBoundWildcard(@NotNull PsiManager manager, @NotNull JavaTypeImpl<?> bound) {
return new JavaWildcardTypeImpl(PsiWildcardType.createExtends(manager, bound.getPsi()));
}
@NotNull
private static JavaWildcardTypeImpl createLowerBoundWildcard(@NotNull PsiManager manager, @NotNull JavaTypeImpl<?> bound) {
return new JavaWildcardTypeImpl(PsiWildcardType.createSuper(manager, bound.getPsi()));
}
@NotNull
private static JavaWildcardTypeImpl createUnboundedWildcard(@NotNull PsiManager manager) {
return new JavaWildcardTypeImpl(PsiWildcardType.createUnbounded(manager));
}
} }
@@ -20,8 +20,6 @@ import com.intellij.psi.PsiType;
import com.intellij.psi.PsiWildcardType; import com.intellij.psi.PsiWildcardType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.load.java.structure.JavaType;
import org.jetbrains.kotlin.load.java.structure.JavaTypeProvider;
import org.jetbrains.kotlin.load.java.structure.JavaWildcardType; import org.jetbrains.kotlin.load.java.structure.JavaWildcardType;
public class JavaWildcardTypeImpl extends JavaTypeImpl<PsiWildcardType> implements JavaWildcardType { public class JavaWildcardTypeImpl extends JavaTypeImpl<PsiWildcardType> implements JavaWildcardType {
@@ -31,7 +29,7 @@ public class JavaWildcardTypeImpl extends JavaTypeImpl<PsiWildcardType> implemen
@Override @Override
@Nullable @Nullable
public JavaType getBound() { public JavaTypeImpl<?> getBound() {
PsiType bound = getPsi().getBound(); PsiType bound = getPsi().getBound();
return bound == null ? null : create(bound); return bound == null ? null : create(bound);
} }
@@ -40,10 +38,4 @@ public class JavaWildcardTypeImpl extends JavaTypeImpl<PsiWildcardType> implemen
public boolean isExtends() { public boolean isExtends() {
return getPsi().isExtends(); return getPsi().isExtends();
} }
@Override
@NotNull
public JavaTypeProvider getTypeProvider() {
return new JavaTypeProviderImpl(getPsi().getManager());
}
} }
@@ -50,9 +50,6 @@ public interface JavaClass extends JavaClassifier, JavaTypeParameterListOwner, J
@NotNull @NotNull
Collection<JavaConstructor> getConstructors(); Collection<JavaConstructor> getConstructors();
@NotNull
JavaClassifierType getDefaultType();
@NotNull @NotNull
OriginKind getOriginKind(); OriginKind getOriginKind();
@@ -20,17 +20,12 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.ReadOnly; import org.jetbrains.annotations.ReadOnly;
import java.util.Collection;
import java.util.List; import java.util.List;
public interface JavaClassifierType extends JavaType, JavaAnnotationOwner { public interface JavaClassifierType extends JavaType, JavaAnnotationOwner {
@Nullable @Nullable
JavaClassifier getClassifier(); JavaClassifier getClassifier();
@NotNull
@ReadOnly
Collection<JavaClassifierType> getSupertypes();
@NotNull @NotNull
String getPresentableText(); String getPresentableText();
@@ -16,9 +16,5 @@
package org.jetbrains.kotlin.load.java.structure; package org.jetbrains.kotlin.load.java.structure;
import org.jetbrains.annotations.NotNull;
public interface JavaType { public interface JavaType {
@NotNull
JavaArrayType createArrayType();
} }
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.load.java.structure; package org.jetbrains.kotlin.load.java.structure;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.ReadOnly; import org.jetbrains.annotations.ReadOnly;
import java.util.Collection; import java.util.Collection;
@@ -26,13 +25,4 @@ public interface JavaTypeParameter extends JavaClassifier {
@NotNull @NotNull
@ReadOnly @ReadOnly
Collection<JavaClassifierType> getUpperBounds(); Collection<JavaClassifierType> getUpperBounds();
@Nullable
JavaTypeParameterListOwner getOwner();
@NotNull
JavaType getType();
@NotNull
JavaTypeProvider getTypeProvider();
} }
@@ -1,33 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.load.java.structure;
import org.jetbrains.annotations.NotNull;
public interface JavaTypeProvider {
@NotNull
JavaType createJavaLangObjectType();
@NotNull
JavaWildcardType createUpperBoundWildcard(@NotNull JavaType bound);
@NotNull
JavaWildcardType createLowerBoundWildcard(@NotNull JavaType bound);
@NotNull
JavaWildcardType createUnboundedWildcard();
}
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.load.java.structure; package org.jetbrains.kotlin.load.java.structure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public interface JavaWildcardType extends JavaType { public interface JavaWildcardType extends JavaType {
@@ -24,7 +23,4 @@ public interface JavaWildcardType extends JavaType {
JavaType getBound(); JavaType getBound();
boolean isExtends(); boolean isExtends();
@NotNull
JavaTypeProvider getTypeProvider();
} }
@@ -81,8 +81,6 @@ class ReflectJavaClass(
.map(::ReflectJavaConstructor) .map(::ReflectJavaConstructor)
.toList() .toList()
override fun getDefaultType(): ReflectJavaClassifierType = throw UnsupportedOperationException()
// TODO: drop OriginKind // TODO: drop OriginKind
override fun getOriginKind() = JavaClass.OriginKind.COMPILED override fun getOriginKind() = JavaClass.OriginKind.COMPILED
@@ -39,8 +39,6 @@ class ReflectJavaClassifierType(public override val type: Type) : ReflectJavaTyp
override fun getClassifier(): JavaClassifier = classifier override fun getClassifier(): JavaClassifier = classifier
override fun getSupertypes(): Collection<JavaClassifierType> = throw UnsupportedOperationException()
override fun getPresentableText(): String = type.toString() override fun getPresentableText(): String = type.toString()
override fun isRaw(): Boolean = with(type) { this is Class<*> && getTypeParameters().isNotEmpty() } override fun isRaw(): Boolean = with(type) { this is Class<*> && getTypeParameters().isNotEmpty() }
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.load.java.structure.reflect package org.jetbrains.kotlin.load.java.structure.reflect
import org.jetbrains.kotlin.load.java.structure.JavaArrayType
import org.jetbrains.kotlin.load.java.structure.JavaType import org.jetbrains.kotlin.load.java.structure.JavaType
import java.lang.reflect.GenericArrayType import java.lang.reflect.GenericArrayType
import java.lang.reflect.Type import java.lang.reflect.Type
@@ -25,8 +24,6 @@ import java.lang.reflect.WildcardType
abstract class ReflectJavaType : JavaType { abstract class ReflectJavaType : JavaType {
protected abstract val type: Type protected abstract val type: Type
override fun createArrayType(): JavaArrayType = throw UnsupportedOperationException()
companion object Factory { companion object Factory {
fun create(type: Type): ReflectJavaType { fun create(type: Type): ReflectJavaType {
return when { return when {
@@ -16,11 +16,9 @@
package org.jetbrains.kotlin.load.java.structure.reflect package org.jetbrains.kotlin.load.java.structure.reflect
import org.jetbrains.kotlin.load.java.structure.* import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import java.lang.reflect.AnnotatedElement import java.lang.reflect.AnnotatedElement
import java.lang.reflect.Constructor
import java.lang.reflect.Method
import java.lang.reflect.TypeVariable import java.lang.reflect.TypeVariable
class ReflectJavaTypeParameter( class ReflectJavaTypeParameter(
@@ -36,20 +34,6 @@ class ReflectJavaTypeParameter(
// TypeVariable is AnnotatedElement only in JDK8 // TypeVariable is AnnotatedElement only in JDK8
get() = typeVariable as? AnnotatedElement get() = typeVariable as? AnnotatedElement
override fun getOwner(): JavaTypeParameterListOwner? {
val owner = typeVariable.genericDeclaration
return when (owner) {
is Class<*> -> ReflectJavaClass(owner)
is Method -> ReflectJavaMethod(owner)
is Constructor<*> -> ReflectJavaConstructor(owner)
else -> throw UnsupportedOperationException("Unsupported type parameter list owner (${owner.javaClass}): $owner")
}
}
override fun getType(): JavaType = throw UnsupportedOperationException()
override fun getTypeProvider(): JavaTypeProvider = throw UnsupportedOperationException()
override fun getName() = Name.identifier(typeVariable.name) override fun getName() = Name.identifier(typeVariable.name)
override fun equals(other: Any?) = other is ReflectJavaTypeParameter && typeVariable == other.typeVariable override fun equals(other: Any?) = other is ReflectJavaTypeParameter && typeVariable == other.typeVariable
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.load.java.structure.reflect package org.jetbrains.kotlin.load.java.structure.reflect
import org.jetbrains.kotlin.load.java.structure.JavaTypeProvider
import org.jetbrains.kotlin.load.java.structure.JavaWildcardType import org.jetbrains.kotlin.load.java.structure.JavaWildcardType
import java.lang.reflect.WildcardType import java.lang.reflect.WildcardType
@@ -35,6 +34,4 @@ class ReflectJavaWildcardType(override val type: WildcardType): ReflectJavaType(
} }
override fun isExtends() = type.upperBounds.firstOrNull() != Any::class.java override fun isExtends() = type.upperBounds.firstOrNull() != Any::class.java
override fun getTypeProvider(): JavaTypeProvider = throw UnsupportedOperationException()
} }
@@ -24,7 +24,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase; import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase;
import org.jetbrains.kotlin.idea.test.KotlinLightProjectDescriptor; import org.jetbrains.kotlin.idea.test.KotlinLightProjectDescriptor;
import org.jetbrains.kotlin.load.java.structure.JavaType; import org.jetbrains.kotlin.load.java.structure.JavaType;
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter;
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassifierTypeImpl; import org.jetbrains.kotlin.load.java.structure.impl.JavaClassifierTypeImpl;
import org.jetbrains.kotlin.load.java.structure.impl.JavaTypeImpl; import org.jetbrains.kotlin.load.java.structure.impl.JavaTypeImpl;
import org.jetbrains.kotlin.load.java.structure.impl.JavaTypeParameterImpl; import org.jetbrains.kotlin.load.java.structure.impl.JavaTypeParameterImpl;
@@ -69,7 +68,7 @@ public abstract class AbstractJavaTypeSubstitutorTest extends KotlinLightCodeIns
PsiType expectedType = type.resolveGenerics().getSubstitutor().substitute(typeParameter); PsiType expectedType = type.resolveGenerics().getSubstitutor().substitute(typeParameter);
JavaClassifierTypeImpl javaClassifierType = (JavaClassifierTypeImpl) JavaTypeImpl.create(type); JavaClassifierTypeImpl javaClassifierType = (JavaClassifierTypeImpl) JavaTypeImpl.create(type);
JavaTypeParameter javaTypeToSubstitute = new JavaTypeParameterImpl(typeParameter); JavaTypeParameterImpl javaTypeToSubstitute = new JavaTypeParameterImpl(typeParameter);
JavaType actualType = javaClassifierType.getSubstitutor().substitute(javaTypeToSubstitute); JavaType actualType = javaClassifierType.getSubstitutor().substitute(javaTypeToSubstitute);
if (actualType == null) { if (actualType == null) {
@@ -84,7 +83,7 @@ public abstract class AbstractJavaTypeSubstitutorTest extends KotlinLightCodeIns
PsiType expectedType = type.resolveGenerics().getSubstitutor().substitute(psiTypeToSubstitute); PsiType expectedType = type.resolveGenerics().getSubstitutor().substitute(psiTypeToSubstitute);
JavaClassifierTypeImpl javaClassifierType = (JavaClassifierTypeImpl) JavaTypeImpl.create(type); JavaClassifierTypeImpl javaClassifierType = (JavaClassifierTypeImpl) JavaTypeImpl.create(type);
JavaType javaTypeToSubstitute = JavaTypeImpl.create(psiTypeToSubstitute); JavaTypeImpl<?> javaTypeToSubstitute = JavaTypeImpl.create(psiTypeToSubstitute);
JavaType actualType = javaClassifierType.getSubstitutor().substitute(javaTypeToSubstitute); JavaType actualType = javaClassifierType.getSubstitutor().substitute(javaTypeToSubstitute);
if (expectedType instanceof PsiEllipsisType) { if (expectedType instanceof PsiEllipsisType) {