Copy and adapt TypeConversionUtil#erasure

This helps to separate SAM resolution from PSI
This commit is contained in:
Alexander Udalov
2013-08-09 19:15:15 +04:00
parent 2b1a2c9988
commit a5ad63c8b6
7 changed files with 134 additions and 14 deletions
@@ -151,4 +151,78 @@ public final class DescriptorResolverUtils {
return result;
}
/**
* @see com.intellij.psi.util.TypeConversionUtil#erasure(com.intellij.psi.PsiType)
*/
@Nullable
public static JavaType erasure(@NotNull JavaType type) {
return erasure(type, JavaTypeSubstitutor.EMPTY);
}
/**
* @see com.intellij.psi.util.TypeConversionUtil#erasure(com.intellij.psi.PsiType, com.intellij.psi.PsiSubstitutor)
*/
@Nullable
public static JavaType erasure(@NotNull JavaType type, @NotNull JavaTypeSubstitutor substitutor) {
if (type instanceof JavaClassifierType) {
JavaClassifier classifier = ((JavaClassifierType) type).getClassifier();
if (classifier instanceof JavaClass) {
return ((JavaClass) classifier).getDefaultType();
}
else if (classifier instanceof JavaTypeParameter) {
JavaTypeParameter typeParameter = (JavaTypeParameter) classifier;
return typeParameterErasure(typeParameter, new HashSet<JavaTypeParameter>(), substitutor);
}
else {
return null;
}
}
else if (type instanceof JavaPrimitiveType) {
return type;
}
else if (type instanceof JavaArrayType) {
JavaType erasure = erasure(((JavaArrayType) type).getComponentType(), substitutor);
return erasure == null ? null : JavaArrayType.create(erasure);
}
else if (type instanceof JavaWildcardType) {
JavaWildcardType wildcardType = (JavaWildcardType) type;
JavaType bound = wildcardType.getBound();
if (bound != null && wildcardType.isExtends()) {
return erasure(bound, substitutor);
}
return wildcardType.getTypeProvider().createJavaLangObjectType();
}
else {
throw new IllegalStateException("Unsupported type: " + type);
}
}
/**
* @see com.intellij.psi.util.TypeConversionUtil#typeParameterErasure(com.intellij.psi.PsiTypeParameter)
*/
@Nullable
private static JavaType typeParameterErasure(
@NotNull JavaTypeParameter typeParameter,
@NotNull HashSet<JavaTypeParameter> visited,
@NotNull JavaTypeSubstitutor substitutor
) {
Collection<JavaClassifierType> upperBounds = typeParameter.getUpperBounds();
if (!upperBounds.isEmpty()) {
JavaClassifier classifier = upperBounds.iterator().next().getClassifier();
if (classifier instanceof JavaTypeParameter && !visited.contains(classifier)) {
JavaTypeParameter typeParameterBound = (JavaTypeParameter) classifier;
visited.add(typeParameterBound);
JavaType substitutedType = substitutor.substitute(typeParameterBound);
if (substitutedType != null) {
return erasure(substitutedType);
}
return typeParameterErasure(typeParameterBound, visited, substitutor);
}
else if (classifier instanceof JavaClass) {
return ((JavaClass) classifier).getDefaultType();
}
}
return typeParameter.getTypeProvider().createJavaLangObjectType();
}
}
@@ -19,8 +19,8 @@ package org.jetbrains.jet.lang.resolve.java.kotlinSignature;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -41,6 +41,8 @@ import org.jetbrains.jet.renderer.DescriptorRenderer;
import java.util.*;
import static org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils.erasure;
// This class contains heuristics for processing corner cases in propagation
class PropagationHeuristics {
// Checks for case when method returning Super[] is overridden with method returning Sub[]
@@ -201,7 +203,7 @@ class PropagationHeuristics {
parameterFromSuper.isVararg()
));
if (!originalType.equals(typeFromSuper)) {
if (!Comparing.equal(originalType, typeFromSuper)) {
return false;
}
}
@@ -214,11 +216,6 @@ class PropagationHeuristics {
return isVararg ? JavaArrayType.create(((JavaArrayType) type).getComponentType()) : type;
}
@NotNull
private static JavaType erasure(@NotNull JavaType type) {
return JavaType.create(TypeConversionUtil.erasure(type.getPsi()));
}
@NotNull
private static JavaTypeSubstitutor getErasedSubstitutor(@NotNull JavaClassifierType type) {
Map<JavaTypeParameter, JavaType> unerasedMap = type.getSubstitutor().getSubstitutionMap();
@@ -17,7 +17,6 @@
package org.jetbrains.jet.lang.resolve.java.sam;
import com.google.common.collect.Lists;
import com.intellij.psi.util.TypeConversionUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
@@ -38,6 +37,7 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import java.util.*;
import static org.jetbrains.jet.lang.resolve.java.DescriptorResolverUtils.erasure;
import static org.jetbrains.jet.lang.types.Variance.INVARIANT;
public class SingleAbstractMethodUtils {
@@ -407,17 +407,12 @@ public class SingleAbstractMethodUtils {
for (Iterator<JavaValueParameter> it1 = parameters1.iterator(), it2 = parameters2.iterator(); it1.hasNext(); ) {
JavaType type1 = erasure(substitutor1.substitute(it1.next().getType()), substitutor1);
JavaType type2 = erasure(substitutor2.substitute(it2.next().getType()), substitutor2);
if (!type1.equals(type2)) return false;
if (!(type1 == null ? type2 == null : type1.equals(type2))) return false;
}
return true;
}
@NotNull
private static JavaType erasure(@NotNull JavaType type, @NotNull JavaTypeSubstitutor substitutor) {
return JavaType.create(TypeConversionUtil.erasure(type.getPsi(), substitutor.getPsi()));
}
@Nullable
private JavaMethod getFoundMethod() {
return foundMethod;
@@ -70,4 +70,9 @@ public class JavaTypeParameter extends JavaClassifier implements JavaNamedElemen
return null;
}
@NotNull
public JavaTypeProvider getTypeProvider() {
return new JavaTypeProvider(getPsi().getManager());
}
}
@@ -0,0 +1,35 @@
/*
* 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.PsiManager;
import com.intellij.psi.PsiType;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
public class JavaTypeProvider {
private final PsiManager manager;
public JavaTypeProvider(@NotNull PsiManager manager) {
this.manager = manager;
}
@NotNull
public JavaType createJavaLangObjectType() {
return JavaType.create(PsiType.getJavaLangObject(manager, GlobalSearchScope.allScope(manager.getProject())));
}
}
@@ -21,11 +21,14 @@ import com.intellij.psi.PsiType;
import com.intellij.psi.PsiTypeParameter;
import com.intellij.psi.impl.PsiSubstitutorImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
public class JavaTypeSubstitutor {
public static final JavaTypeSubstitutor EMPTY = new JavaTypeSubstitutor(PsiSubstitutor.EMPTY);
private final PsiSubstitutor psiSubstitutor;
private Map<JavaTypeParameter, JavaType> substitutionMap;
@@ -59,6 +62,12 @@ public class JavaTypeSubstitutor {
return JavaType.create(getPsi().substitute(type.getPsi()));
}
@Nullable
public JavaType substitute(@NotNull JavaTypeParameter typeParameter) {
PsiType psiType = getPsi().substitute(typeParameter.getPsi());
return psiType == null ? null : JavaType.create(psiType);
}
@NotNull
public Map<JavaTypeParameter, JavaType> getSubstitutionMap() {
if (substitutionMap == null) {
@@ -41,4 +41,9 @@ public class JavaWildcardType extends JavaType {
public boolean isExtends() {
return getPsi().isExtends();
}
@NotNull
public JavaTypeProvider getTypeProvider() {
return new JavaTypeProvider(getPsi().getManager());
}
}