package blue.stack.serializableParcelablegenerator.util;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiType;
import com.intellij.psi.util.PsiTypesUtil;
import java.util.ArrayList;
import java.util.List;
final public class PsiUtils {
private PsiUtils() {
}
/**
* Checks that the given type is an implementer of the given canonicalName with the given typed parameters
*
* @param type what we're checking against
* @param canonicalName the type must extend/implement this generic
* @param canonicalParamNames the type that the generic(s) must be (in this order)
* @return
*/
public static boolean isTypedClass(PsiType type, String canonicalName, String... canonicalParamNames) {
PsiClass parameterClass = PsiTypesUtil.getPsiClass(type);
if (parameterClass == null) {
return false;
}
// This is a safe cast, for if parameterClass != null, the type was checked in PsiTypesUtil#getPsiClass(...)
PsiClassType pct = (PsiClassType) type;
// Main class name doesn't match; exit early
if (!canonicalName.equals(parameterClass.getQualifiedName())) {
return false;
}
List<PsiType> psiTypes = new ArrayList<PsiType>(pct.resolveGenerics().getSubstitutor().getSubstitutionMap().values());
for (int i = 0; i < canonicalParamNames.length; i++) {
if (!isOfType(psiTypes.get(i), canonicalParamNames[i])) {
return false;
}
}
// Passed all screenings; must be a match!
return true;
}
/**
* Resolves generics on the given type and returns them (if any) or null if there are none
*
* @param type
* @return
*/
public static List<PsiType> getResolvedGenerics(PsiType type) {
List<PsiType> psiTypes = null;
if (type instanceof PsiClassType) {
PsiClassType pct = (PsiClassType) type;
psiTypes = new ArrayList<PsiType>(pct.resolveGenerics().getSubstitutor().getSubstitutionMap().values());
}
return psiTypes;
}
public static boolean isOfType(PsiType type, String canonicalName) {
if (type.getCanonicalText().equals(canonicalName)) {
return true;
}
if (getNonGenericType(type).equals(canonicalName)) {
return true;
}
for (PsiType iterType : type.getSuperTypes()) {
if (iterType.getCanonicalText().equals(canonicalName) || getNonGenericType(iterType).equals(canonicalName)) {
return true;
}
}
return false;
}
public static String getNonGenericType(PsiType type) {
if (type instanceof PsiClassType) {
PsiClassType pct = (PsiClassType) type;
return pct.resolve().getQualifiedName();
}
return type.getCanonicalText();
}
}