下面列出了怎么用com.intellij.psi.PsiClassType的API类实例代码及写法,或者点击链接到github查看源代码。
static TypeName getTypeName(PsiType type) {
if (type instanceof PsiPrimitiveType) {
// float
return getPrimitiveTypeName((PsiPrimitiveType) type);
} else if (type instanceof PsiClassType && ((PsiClassType) type).getParameterCount() > 0) {
// Set<Integer>
PsiClassType classType = (PsiClassType) type;
return ParameterizedTypeName.get(
guessClassName(classType.rawType().getCanonicalText()),
getTypeNameArray(classType.getParameters()));
} else if (type instanceof PsiArrayType) {
// int[]
PsiType componentType = ((PsiArrayType) type).getComponentType();
return ArrayTypeName.of(getTypeName(componentType));
} else if (type.getCanonicalText().contains("?")) {
// ? extends Type
return getWildcardTypeName(type.getCanonicalText());
} else {
return guessClassName(type.getCanonicalText());
}
}
public static ImmutableList<TypeVariableName> getTypeVariables(PsiClass psiClass) {
PsiTypeParameter[] psiTypeParameters = psiClass.getTypeParameters();
final List<TypeVariableName> typeVariables = new ArrayList<>(psiTypeParameters.length);
for (PsiTypeParameter psiTypeParameter : psiTypeParameters) {
final PsiReferenceList extendsList = psiTypeParameter.getExtendsList();
final PsiClassType[] psiClassTypes = extendsList.getReferencedTypes();
final TypeName[] boundsTypeNames = new TypeName[psiClassTypes.length];
for (int i = 0, size = psiClassTypes.length; i < size; i++) {
boundsTypeNames[i] = PsiTypeUtils.getTypeName(psiClassTypes[i]);
}
final TypeVariableName typeVariable =
TypeVariableName.get(psiTypeParameter.getName(), boundsTypeNames);
typeVariables.add(typeVariable);
}
return ImmutableList.copyOf(typeVariables);
}
@Nullable
public static PsiType safeGetValidType(@NotNull Module module, @NotNull String fqn) {
try {
// Intellij expects inner classes to be referred via `.` instead of `$`
PsiType type = JavaPsiFacade.getInstance(module.getProject()).getParserFacade()
.createTypeFromText(fqn.replaceAll("\\$", "."), null);
boolean typeValid = isValidType(type);
if (typeValid) {
if (type instanceof PsiClassType) {
return PsiClassType.class.cast(type);
} else if (type instanceof PsiArrayType) {
return PsiArrayType.class.cast(type);
}
}
return null;
} catch (IncorrectOperationException e) {
debug(() -> log.debug("Unable to find class fqn " + fqn));
return null;
}
}
public static boolean isValidType(@NotNull PsiType type) {
if (!type.isValid()) {
TimeoutUtil.sleep(
1); // to see if processing in another thread suddenly makes the type valid again (which is a bug)
if (!type.isValid()) {
return false;
}
}
if (type instanceof PsiArrayType) {
return isValidType(PsiArrayType.class.cast(type).getComponentType());
} else if (type instanceof PsiWildcardType) {
PsiType bound = ((PsiWildcardType) type).getBound();
return bound != null && isValidType(bound);
} else if (type instanceof PsiCapturedWildcardType) {
PsiType lowerBound = ((PsiCapturedWildcardType) type).getLowerBound();
type = (lowerBound != NULL ? lowerBound : ((PsiCapturedWildcardType) type).getUpperBound());
return type != NULL && isValidType(type);
} else if (type instanceof PsiClassType) {
PsiClassType.ClassResolveResult classResolveResult = ((PsiClassType) type).resolveGenerics();
return classResolveResult.isValidResult() && isValidElement(
requireNonNull(classResolveResult.getElement())) && !hasUnresolvedComponents(type);
}
return true;
}
private void init(@NotNull PsiClassType type) {
if (isValidType(type)) {
PsiField[] fields = requireNonNull(toValidPsiClass(type)).getFields();
List<PsiField> acceptableFields = new ArrayList<>();
for (PsiField field : fields) {
if (field != null && field.getType().equals(type)) {
acceptableFields.add(field);
}
}
if (acceptableFields.size() != 0) {
childLookup = new THashMap<>();
childrenTrie = new PatriciaTrie<>();
acceptableFields.forEach(field -> {
childLookup.put(sanitise(requireNonNull(field.getName())), field);
childrenTrie.put(sanitise(field.getName()), field);
});
}
} else {
childLookup = null;
childrenTrie = null;
}
}
@NotNull
public static MetadataProxy newMetadataProxy(Module module, @NotNull PsiType type) {
if (type instanceof PsiArrayType) {
return new ArrayMetadataProxy(module, (PsiArrayType) type);
} else if (type instanceof PsiPrimitiveType) {
PsiPrimitiveType primitiveType = (PsiPrimitiveType) type;
type = getBoxedTypeFromPrimitiveType(module, primitiveType);
}
if (type instanceof PsiClassType) {
SuggestionNodeType suggestionNodeType = getSuggestionNodeType(type);
if (suggestionNodeType == SuggestionNodeType.MAP) {
return new MapClassMetadataProxy((PsiClassType) type);
} else {
return new ClassMetadataProxy((PsiClassType) type);
}
}
throw new IllegalAccessError(
"Supports only PsiArrayType, PsiPrimitiveType & PsiClassType types");
}
private void init(Module module, PsiClassType type) {
if (isValidType(type)) {
Map<PsiTypeParameter, PsiType> typeParameterToResolvedType = getTypeParameters(type);
assert typeParameterToResolvedType != null;
Set<PsiTypeParameter> typeParameterKetSet = typeParameterToResolvedType.keySet();
Optional<PsiTypeParameter> keyTypeParam =
typeParameterKetSet.stream().filter(v -> requireNonNull(v.getName()).equals("K"))
.findFirst();
Optional<PsiTypeParameter> valueTypeParam =
typeParameterKetSet.stream().filter(v -> requireNonNull(v.getName()).equals("V"))
.findFirst();
if (keyTypeParam.isPresent()) {
this.keyType = typeParameterToResolvedType.get(keyTypeParam.get());
if (this.keyType != null) {
keyMetadataProxy = newMetadataProxy(module, this.keyType);
}
}
if (valueTypeParam.isPresent()) {
this.valueType = typeParameterToResolvedType.get(valueTypeParam.get());
if (this.valueType != null) {
valueMetadataProxy = newMetadataProxy(module, this.valueType);
}
}
}
}
public static String print(PsiTypeParameter[] parameters, TranslationContext ctx) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < parameters.length; i++) {
PsiTypeParameter p = parameters[i];
builder.append(p.getName());
PsiClassType[] extensions = p.getExtendsList().getReferencedTypes();
if (extensions.length > 0) {
builder.append(" extends ");
for (PsiClassType ext : extensions) {
builder.append(TypeHelper.printType(ext, ctx));
}
}
if (i != parameters.length - 1) {
builder.append(", ");
}
}
return builder.toString();
}
/**
* Make the class implementing Parcelable
*/
private void makeClassImplementParcelable(PsiElementFactory elementFactory, JavaCodeStyleManager styleManager) {
final PsiClassType[] implementsListTypes = psiClass.getImplementsListTypes();
final String implementsType = "android.os.Parcelable";
for (PsiClassType implementsListType : implementsListTypes) {
PsiClass resolved = implementsListType.resolve();
// Already implements Parcelable, no need to add it
if (resolved != null && implementsType.equals(resolved.getQualifiedName())) {
return;
}
}
PsiJavaCodeReferenceElement implementsReference =
elementFactory.createReferenceFromText(implementsType, psiClass);
PsiReferenceList implementsList = psiClass.getImplementsList();
if (implementsList != null) {
styleManager.shortenClassReferences(implementsList.add(implementsReference));
}
}
private void validateCleanUpMethodExists(@NotNull PsiLocalVariable psiVariable, @NotNull String cleanupName, @NotNull ProblemNewBuilder problemNewBuilder) {
final PsiType psiType = psiVariable.getType();
if (psiType instanceof PsiClassType) {
final PsiClassType psiClassType = (PsiClassType) psiType;
final PsiClass psiClassOfField = psiClassType.resolve();
final PsiMethod[] methods;
if (psiClassOfField != null) {
methods = psiClassOfField.findMethodsByName(cleanupName, true);
boolean hasCleanupMethod = false;
for (PsiMethod method : methods) {
if (0 == method.getParameterList().getParametersCount()) {
hasCleanupMethod = true;
}
}
if (!hasCleanupMethod) {
problemNewBuilder.addError("'@Cleanup': method '%s()' not found on target class", cleanupName);
}
}
} else {
problemNewBuilder.addError("'@Cleanup': is legal only on a local variable declaration inside a block");
}
}
@Override public void navigate(final MouseEvent mouseEvent, final PsiElement psiElement) {
PsiMethod subscribeMethod = (PsiMethod) psiElement;
final PsiTypeElement parameterTypeElement = getMethodParameter(subscribeMethod);
final SubscriberMetadata subscriberMetadata = SubscriberMetadata.getSubscriberMetadata(subscribeMethod);
if ((parameterTypeElement.getType() instanceof PsiClassType) && (subscriberMetadata != null)) {
final PsiClass eventClass = ((PsiClassType) parameterTypeElement.getType()).resolve();
PickAction.startPicker(subscriberMetadata.displayedTypesOnSubscriberMethods(),
new RelativePoint(mouseEvent), new PickAction.Callback() {
@Override public void onTypeChose(PickAction.Type type) {
if (type.equals(PickAction.Type.PRODUCER)) {
new ShowUsagesAction(PRODUCERS).startFindUsages(eventClass,
new RelativePoint(mouseEvent), PsiUtilBase.findEditor(psiElement),
MAX_USAGES);
} else if (type.equals(PickAction.Type.EVENT_POST)) {
PsiMethod ottoBusMethod = subscriberMetadata.getBusPostMethod(psiElement.getProject());
new ShowUsagesAction(new BusPostDecider(eventClass)).startFindUsages(
ottoBusMethod, new RelativePoint(mouseEvent),
PsiUtilBase.findEditor(psiElement), MAX_USAGES);
}
}
});
}
}
@Override
public String generate(PsiElement element) {
if (!(element instanceof PsiMethod)) {
return "";
}
List<String> exceptionNameList = Arrays.stream(((PsiMethod)element).getThrowsList().getReferencedTypes())
.map(PsiClassType::getName).collect(Collectors.toList());
if (exceptionNameList.isEmpty()) {
return "";
}
return exceptionNameList.stream()
.map(name -> "@throws " + name + " " + translatorService.translate(name))
.collect(Collectors.joining("\n"));
}
@Override
protected void visitConfigTypeAnnotation(final UAnnotation node, final UClass owner) {
final PsiClass resolverClass = ((PsiImmediateClassType) node.getAttributeValues()
.get(0)
.getExpression()
.evaluate()).resolve();
final PsiClassType resolverClassType = getConfigTypeResolverClassType(resolverClass);
if (resolverClassType == null) {
return;
}
final PsiType annotationType = getAnnotationType(resolverClassType);
final PsiType rawType = getRawType(resolverClassType);
if (!annotationType.getCanonicalText()
.equals(owner.getQualifiedName())) {
report(node);
return;
}
final UMethod defaultValueMethod = getDefaultValueMethod(owner);
if (defaultValueMethod == null) {
return;
}
if (!rawType.equals(defaultValueMethod.getReturnType())) {
report(node);
}
}
private PsiClassType getConfigTypeResolverClassType(final PsiClass resolverClass) {
if (resolverClass != null) {
for (final PsiClassType classInterface : resolverClass.getImplementsListTypes()) {
if (classInterface.getClassName()
.equals(CLASS_CONFIG_TYPE_RESOLVER)) {
return classInterface;
}
}
}
return null;
}
/**
* Tries to guess if the given methodCall requires event handler.
*
* @return Qualified name of the handled Event or null, if methodCall neither accepts event
* handler, nor require fix.
*/
@Nullable
private static String resolveEventName(PsiMethodCallExpression methodCall) {
return Optional.of(methodCall.getMethodExpression().multiResolve(true))
.map(results -> results.length == 1 ? results[0] : JavaResolveResult.EMPTY)
.filter(MethodCandidateInfo.class::isInstance)
.map(MethodCandidateInfo.class::cast)
.filter(MethodCandidateInfo::isTypeArgumentsApplicable)
.filter(info -> !info.isApplicable() && !info.isValidResult())
.map(info -> info.getElement().getParameterList().getParameters())
.filter(parameters -> parameters.length > 0) // method(EventHandler<T> e)
.map(parameters -> parameters[0].getType())
.filter(PsiClassType.class::isInstance)
.filter(
parameterType -> {
String fullName = parameterType.getCanonicalText();
int genericIndex = fullName.indexOf('<');
if (genericIndex <= 0) {
return false;
}
String className = fullName.substring(0, genericIndex);
return LithoClassNames.EVENT_HANDLER_CLASS_NAME.equals(className);
})
.map(parameterType -> ((PsiClassType) parameterType).getParameters())
.filter(generics -> generics.length == 1) // <T>
.map(generics -> generics[0].getCanonicalText())
.orElse(null);
}
@Nullable
public static Map<PsiTypeParameter, PsiType> getTypeParameters(PsiType type) {
if (type instanceof PsiArrayType) {
return getTypeParameters(((PsiArrayType) type).getComponentType());
} else if (type instanceof PsiPrimitiveType) {
return null;
} else if (type instanceof PsiClassType) {
PsiClassType.ClassResolveResult resolveResult =
PsiClassType.class.cast(type).resolveGenerics();
if (resolveResult.isValidResult()) {
return resolveResult.getSubstitutor().getSubstitutionMap();
}
}
return null;
}
@Nullable
public static String toClassFqn(@NotNull PsiType type) {
if (type instanceof PsiArrayType) {
String componentLongName = toClassFqn(PsiArrayType.class.cast(type).getComponentType());
if (componentLongName != null) {
return componentLongName + "[]";
}
} else if (type instanceof PsiPrimitiveType) {
return type.getPresentableText();
} else if (type instanceof PsiClassType) {
return type.getCanonicalText();
}
return null;
}
@Nullable
public static String toClassNonQualifiedName(@NotNull PsiType type) {
if (type instanceof PsiArrayType) {
String componentLongName =
toClassNonQualifiedName(PsiArrayType.class.cast(type).getComponentType());
if (componentLongName != null) {
return componentLongName + "[]";
}
} else if (type instanceof PsiPrimitiveType) {
return type.getPresentableText();
} else if (type instanceof PsiClassType) {
return ((PsiClassType) type).getClassName();
}
return null;
}
@Nullable
public static String typeToFqn(Module module, @NotNull PsiType type) {
if (isValidType(type)) {
if (type instanceof PsiArrayType) {
type = PsiArrayType.class.cast(type).getComponentType();
return type.getCanonicalText();
} else if (type instanceof PsiPrimitiveType) {
return getBoxedTypeFromPrimitiveType(module, (PsiPrimitiveType) type).getCanonicalText();
} else if (type instanceof PsiClassType) {
return type.getCanonicalText();
}
}
return null;
}
@Nullable
public static PsiClass toValidPsiClass(@NotNull PsiClassType type) {
if (isValidType(type)) {
return type.resolve();
}
return null;
}
@Nullable
private static PsiType getFieldType(final PsiField field) {
return getCachedValue(field, SPRING_ASSISTANT_PLUGIN_ERASE_FREE_TYPE_PARAMETER_TYPE_KEY, () -> {
final PsiType fieldType = field.getType();
final PsiClassType.ClassResolveResult resolveResult = resolveGenericsClassInType(fieldType);
final PsiClass fieldClass = resolveResult.getElement();
if (fieldClass == null) {
final PsiType propertyType = eraseFreeTypeParameters(fieldType, field);
return create(propertyType, JAVA_STRUCTURE_MODIFICATION_COUNT);
}
return null;
});
}
static ClassMetadata newClassMetadata(@NotNull PsiType type) {
SuggestionNodeType nodeType = getSuggestionNodeType(type);
switch (nodeType) {
case BOOLEAN:
return new BooleanClassMetadata();
case BYTE:
case SHORT:
case INT:
case LONG:
case FLOAT:
case DOUBLE:
case CHAR:
case STRING:
return new DummyClassMetadata(nodeType);
case ENUM:
return new EnumClassMetadata((PsiClassType) type);
case ITERABLE:
return new IterableClassMetadata((PsiClassType) type);
case MAP:
return new MapClassMetadata((PsiClassType) type);
case KNOWN_CLASS:
return new GenericClassMetadata((PsiClassType) type);
case UNKNOWN_CLASS:
return new DummyClassMetadata(nodeType);
default:
throw new IllegalStateException(
"Class suggestion node for the specified class " + type + " is undefined");
}
}
private void init(@NotNull PsiClassType type) {
if (isValidType(type)) {
childLookup = getSanitisedPropertyToPsiMemberWrapper(toValidPsiClass(type));
if (childLookup != null) {
childrenTrie = new PatriciaTrie<>();
childLookup.forEach((k, v) -> childrenTrie.put(k, v));
}
} else {
childLookup = null;
childrenTrie = null;
}
}
static List<PsiClass> getExtendsClasses(PsiClass psiClass, int lowDepth, int currentDepth){
List<PsiClass> list = new ArrayList<>();
for(PsiClassType type : psiClass.getExtendsListTypes()) {
PsiClass superPsiClass = type.resolve();
if(superPsiClass != null){
if(currentDepth + 1 >= lowDepth) {
list.add(superPsiClass);
}
list.addAll(getExtendsClasses(superPsiClass, lowDepth, currentDepth + 1));
}
}
return list;
}
static boolean hasSelectable(PsiClass psiClass){
PsiClassType[] listTypes = psiClass.getExtendsListTypes();
for(PsiClassType type : listTypes){
PsiClass superPsiClass = type.resolve();
if (superPsiClass != null && NAME_SELECTABLE.equals(superPsiClass.getQualifiedName())) {
return true;
}
}
return false;
}
/**
* 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
*/
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 String getNonGenericType(PsiType type) {
if (type instanceof PsiClassType) {
PsiClassType pct = (PsiClassType) type;
final PsiClass psiClass = pct.resolve();
return psiClass != null ? psiClass.getQualifiedName() : null;
}
return type.getCanonicalText();
}
@Nullable
@Override
public String getQuickNavigateInfo(PsiElement element, PsiElement originalElement) {
if (ServiceManager.getService(element.getProject(), CamelService.class).isCamelPresent()) {
PsiExpressionList exps = PsiTreeUtil.getNextSiblingOfType(originalElement, PsiExpressionList.class);
if (exps != null) {
if (exps.getExpressions().length >= 1) {
// grab first string parameter (as the string would contain the camel endpoint uri
final PsiClassType stringType = PsiType.getJavaLangString(element.getManager(), element.getResolveScope());
PsiExpression exp = Arrays.stream(exps.getExpressions()).filter(
e -> e.getType() != null && stringType.isAssignableFrom(e.getType()))
.findFirst().orElse(null);
if (exp instanceof PsiLiteralExpression) {
Object o = ((PsiLiteralExpression) exp).getValue();
String val = o != null ? o.toString() : null;
// okay only allow this popup to work when its from a RouteBuilder class
PsiClass clazz = PsiTreeUtil.getParentOfType(originalElement, PsiClass.class);
if (clazz != null) {
PsiClassType[] types = clazz.getExtendsListTypes();
boolean found = Arrays.stream(types).anyMatch(p -> p.getClassName().equals("RouteBuilder"));
if (found) {
String componentName = asComponentName(val);
if (componentName != null) {
// the quick info cannot be so wide so wrap at 120 chars
return generateCamelComponentDocumentation(componentName, val, 120, element.getProject());
}
}
}
}
}
}
}
return null;
}
public List<ReferenceableBeanId> findReferenceableBeanIdsByType(Module module,
Predicate<String> idCondition,
PsiType expectedBeanType) {
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(module.getProject());
return findReferenceableBeanIds(module, idCondition).stream()
.filter(ref -> {
PsiClass psiClass = resolveToPsiClass(ref);
if (psiClass != null) {
PsiClassType beanType = elementFactory.createType(psiClass);
return expectedBeanType.isAssignableFrom(beanType);
}
return false;
})
.collect(Collectors.toList());
}