下面列出了怎么用com.intellij.psi.PsiJavaCodeReferenceElement的API类实例代码及写法,或者点击链接到github查看源代码。
private static Map<String, List<PsiElement>> collectRedSymbols(
PsiFile psiFile, Document document, Project project, ProgressIndicator daemonIndicator) {
Map<String, List<PsiElement>> redSymbolToElements = new HashMap<>();
List<HighlightInfo> infos =
((DaemonCodeAnalyzerImpl) DaemonCodeAnalyzer.getInstance(project))
.runMainPasses(psiFile, document, daemonIndicator);
for (HighlightInfo info : infos) {
if (!info.getSeverity().equals(HighlightSeverity.ERROR)) continue;
final String redSymbol = document.getText(new TextRange(info.startOffset, info.endOffset));
if (!StringUtil.isJavaIdentifier(redSymbol) || !StringUtil.isCapitalized(redSymbol)) continue;
final PsiJavaCodeReferenceElement ref =
PsiTreeUtil.findElementOfClassAtOffset(
psiFile, info.startOffset, PsiJavaCodeReferenceElement.class, false);
if (ref == null) continue;
redSymbolToElements.putIfAbsent(redSymbol, new ArrayList<>());
redSymbolToElements.get(redSymbol).add(ref);
}
return redSymbolToElements;
}
private static boolean extendsTestCase(PsiClass psiClass, Set<PsiClass> checkedClasses) {
if (!checkedClasses.add(psiClass)) {
return false;
}
PsiReferenceList extendsList = psiClass.getExtendsList();
if (extendsList == null) {
return false;
}
for (PsiJavaCodeReferenceElement ref : extendsList.getReferenceElements()) {
if (JUnitUtil.TEST_CASE_CLASS.equals(ref.getQualifiedName())) {
return true;
}
PsiElement clazz = ref.resolve();
if (clazz instanceof PsiClass && extendsTestCase((PsiClass) clazz, checkedClasses)) {
return true;
}
}
return false;
}
/**
* 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 static PsiClass resolveClass(final PsiClassObjectAccessExpressionImpl expression) {
if (expression == null) {
return null;
}
final PsiJavaCodeReferenceElement referenceElement = expression.getOperand()
.getInnermostComponentReferenceElement();
return referenceElement != null ? (PsiClass) referenceElement.resolve() : null;
}
/**
* @return Stream of resolved elements from the given element or an empty stream if nothing found.
*/
static Stream<PsiElement> resolve(PsiElement sourceElement) {
return Optional.of(sourceElement)
.filter(PsiIdentifier.class::isInstance)
.map(element -> PsiTreeUtil.getParentOfType(element, PsiJavaCodeReferenceElement.class))
.map(PsiElement::getReferences)
.map(
psiReferences ->
Stream.of(psiReferences).map(PsiReference::resolve).filter(Objects::nonNull))
.orElse(Stream.empty());
}
@Override
public PsiClass getBeanClass(PsiElement element) {
final PsiElement beanPsiElement = getPsiElementForCamelBeanMethod(element);
if (beanPsiElement != null) {
if (beanPsiElement instanceof PsiClass) {
return (PsiClass) beanPsiElement;
}
PsiJavaCodeReferenceElement referenceElement = PsiTreeUtil.findChildOfType(beanPsiElement, PsiJavaCodeReferenceElement.class);
final PsiClass psiClass = getJavaClassUtils().resolveClassReference(referenceElement);
if (psiClass != null && !JAVA_LANG_STRING.equals(psiClass.getQualifiedName())) {
return psiClass;
}
String beanName = "";
if (referenceElement instanceof PsiReferenceExpression) {
beanName = getStaticBeanName(referenceElement, beanName);
} else {
final String[] beanParameters = beanPsiElement.getText().replace("(", "").replace(")", "").split(",");
if (beanParameters.length > 0) {
beanName = StringUtils.stripDoubleQuotes(beanParameters[0]);
}
}
return searchForMatchingBeanClass(beanName, beanPsiElement.getProject()).orElse(null);
}
return null;
}
private String getStaticBeanName(PsiJavaCodeReferenceElement referenceElement, String beanName) {
final PsiType type = ((PsiReferenceExpression) referenceElement).getType();
if (type != null && JAVA_LANG_STRING.equals(type.getCanonicalText())) {
beanName = StringUtils.stripDoubleQuotes(PsiTreeUtil.getChildOfAnyType(referenceElement.getReference().resolve(), PsiLiteralExpression.class).getText());
}
return beanName;
}
/**
* @param referenceElement - Psi Code reference element to resolve
* @return Resolving the Psi reference and return the PsiClass
*/
public PsiClass resolveClassReference(@Nullable PsiJavaCodeReferenceElement referenceElement) {
if (referenceElement != null) {
PsiReference reference = referenceElement.getReference();
if (reference != null) {
return resolveClassReference(reference);
}
}
return null;
}
private RemoveAnnotationValueFix( @NotNull PsiAnnotationMemberValue annotationValueToRemove,
@NotNull PsiJavaCodeReferenceElement sideEffectClassReference )
{
super( message( "side.effects.annotation.declared.correctly.fix.remove.class.reference",
sideEffectClassReference.getQualifiedName() ) );
this.annotationValueToRemove = annotationValueToRemove;
}
public RemoveInvalidConcernClassReferenceFix( @NotNull PsiAnnotationMemberValue annotationValueToRemove,
@NotNull PsiJavaCodeReferenceElement concernClassReference )
{
super( message( "concerns.annotation.declared.correctly.fix.remove.concern.class.reference",
concernClassReference.getQualifiedName() ) );
this.concernClassAnnotationValue = annotationValueToRemove;
}
private ProblemDescriptor createProblemDescriptor( @NotNull InspectionManager manager,
@NotNull PsiAnnotationMemberValue mixinAnnotationValue,
@NotNull PsiJavaCodeReferenceElement mixinClassReference,
@NotNull String message )
{
RemoveInvalidMixinClassReferenceFix fix = new RemoveInvalidMixinClassReferenceFix(
mixinAnnotationValue, mixinClassReference
);
return manager.createProblemDescriptor( mixinAnnotationValue, message, fix, GENERIC_ERROR_OR_WARNING );
}
@NotNull
@Override
public PsiClassType[] getReferencedTypes() {
LOG.debug("getReferencedTypes");
PsiJavaCodeReferenceElement[] refs = getReferenceElements();
PsiElementFactory factory = JavaPsiFacade.getInstance(getProject()).getElementFactory();
PsiClassType[] types = new PsiClassType[refs.length];
for (int i = 0; i < types.length; i++) {
types[i] = factory.createType(refs[i]);
}
return types;
}
@NotNull
@Override
public PsiJavaCodeReferenceElement[] getReferenceElements() {
LOG.debug("getReferenceElements");
List<HaxeType> typeList = getTypeList();
PsiJavaCodeReferenceElement[] refList = new PsiJavaCodeReferenceElement[typeList.size()];
for (int i = 0; i < typeList.size(); ++i) {
refList[i] = typeList.get(i).getReferenceExpression();
}
return refList;
}
@Nullable
private static PsiAnnotation findAnnotationQuick(@Nullable PsiAnnotationOwner annotationOwner, @NotNull String qualifiedName) {
if (annotationOwner == null) {
return null;
}
PsiAnnotation[] annotations = annotationOwner.getAnnotations();
if (annotations.length == 0) {
return null;
}
final String shortName = StringUtil.getShortName(qualifiedName);
for (PsiAnnotation annotation : annotations) {
PsiJavaCodeReferenceElement referenceElement = annotation.getNameReferenceElement();
if (null != referenceElement) {
final String referenceName = referenceElement.getReferenceName();
if (shortName.equals(referenceName)) {
if (referenceElement.isQualified() && referenceElement instanceof SourceJavaCodeReference) {
String possibleFullQualifiedName = ((SourceJavaCodeReference) referenceElement).getClassNameText();
if (qualifiedName.equals(possibleFullQualifiedName)) {
return annotation;
}
}
final String annotationQualifiedName = getAndCacheFQN(annotation, referenceName);
if (null != annotationQualifiedName && qualifiedName.endsWith(annotationQualifiedName)) {
return annotation;
}
}
}
}
return null;
}
@Nullable
private static PsiAnnotation findAnnotationQuick(@Nullable PsiAnnotationOwner annotationOwner, @NotNull String... qualifiedNames) {
if (annotationOwner == null || qualifiedNames.length == 0) {
return null;
}
PsiAnnotation[] annotations = annotationOwner.getAnnotations();
if (annotations.length == 0) {
return null;
}
final String[] shortNames = new String[qualifiedNames.length];
for (int i = 0; i < qualifiedNames.length; i++) {
shortNames[i] = StringUtil.getShortName(qualifiedNames[i]);
}
for (PsiAnnotation annotation : annotations) {
final PsiJavaCodeReferenceElement referenceElement = annotation.getNameReferenceElement();
if (null != referenceElement) {
final String referenceName = referenceElement.getReferenceName();
if (ArrayUtil.find(shortNames, referenceName) > -1) {
if (referenceElement.isQualified() && referenceElement instanceof SourceJavaCodeReference) {
final String possibleFullQualifiedName = ((SourceJavaCodeReference) referenceElement).getClassNameText();
if (ArrayUtil.find(qualifiedNames, possibleFullQualifiedName) > -1) {
return annotation;
}
}
final String annotationQualifiedName = getAndCacheFQN(annotation, referenceName);
if (ArrayUtil.find(qualifiedNames, annotationQualifiedName) > -1) {
return annotation;
}
}
}
}
return null;
}
@Override
public void registerFixes(
@NotNull PsiJavaCodeReferenceElement referenceElement,
@NotNull QuickFixActionRegistrar quickFixActionRegistrar) {
List<IntentionAction> fixes = findFixesForReference(referenceElement);
fixes.forEach(quickFixActionRegistrar::register);
if (fixes.isEmpty() || Boolean.parseBoolean(System.getProperty(KEEP_DEFAULT_AUTODEPS))) {
// Don't unregister the default if:
// 1) We can't replace it with anything.
// 2) The user has requested to keep it.
return;
}
// If we think we can add both a Buck dependency and an IntelliJ module dependency,
// unregister the default fix, which only adds an IntelliJ module dependency.
quickFixActionRegistrar.unregister(
new Condition<IntentionAction>() {
private static final String ADD_MODULE_DEPENDENCY_FIX_CLASSNAME =
"com.intellij.codeInsight.daemon.impl.quickfix.AddModuleDependencyFix";
@Override
public boolean value(IntentionAction intentionAction) {
String className = intentionAction.getClass().getName();
if (ADD_MODULE_DEPENDENCY_FIX_CLASSNAME.equals(className)) {
return true;
}
return false;
}
});
}
private List<IntentionAction> findFixesForReference(
PsiJavaCodeReferenceElement referenceElement) {
Project project = referenceElement.getProject();
String className = referenceElement.getQualifiedName();
List<IntentionAction> results = new ArrayList<>();
if (className != null) {
findPsiClasses(project, className).stream()
.map(psiClass -> BuckAddDependencyIntention.create(referenceElement, psiClass))
.filter(Objects::nonNull)
.forEach(results::add);
}
return results;
}
@Override public boolean shouldShow(Usage usage) {
PsiElement element = ((UsageInfo2UsageAdapter) usage).getElement();
if (element instanceof PsiJavaCodeReferenceElement) {
if ((element = element.getContext()) instanceof PsiTypeElement) {
if ((element = element.getContext()) instanceof PsiParameter) {
if ((element = element.getContext()) instanceof PsiParameterList) {
if ((element = element.getContext()) instanceof PsiMethod) {
return SubscriberMetadata.isAnnotatedWithSubscriber((PsiMethod) element);
}
}
}
}
}
return false;
}
public static PsiClass getAnnotationDeclarationClass(final PsiAnnotation configAnnotation) {
final PsiJavaCodeReferenceElement nameReferenceElement = configAnnotation.getNameReferenceElement();
return nameReferenceElement != null ? (PsiClass) nameReferenceElement.resolve() : null;
}
@Override
protected Response handle(Request request) {
Project project = findProject(request.file);
if (project == null) {
throw new RuntimeException("Cannot find the target project");
}
Application application = ApplicationManager.getApplication();
Response response = new Response();
application.runReadAction(
() -> {
PsiFile psiFile =
PsiFileFactory.getInstance(project)
.createFileFromText(JavaLanguage.INSTANCE, request.text);
if (!(psiFile instanceof PsiJavaFile)) {
throw new RuntimeException("Cannot parse as Java file");
}
PsiJavaFile psiJavaFile = (PsiJavaFile) psiFile;
Set<String> processed = new HashSet<>();
for (PsiClass psiClass : psiJavaFile.getClasses()) {
psiClass.accept(
new JavaRecursiveElementWalkingVisitor() {
@Override
public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
try {
if (reference.getQualifier() != null) {
return;
}
String name = reference.getReferenceName();
if (processed.contains(name)) {
return;
}
processed.add(name);
Set<String> candidates = new HashSet<>();
for (PsiClass t : new ImportClassFix(reference).getClassesToImport()) {
candidates.add(String.format("import %s;", t.getQualifiedName()));
}
if (!candidates.isEmpty()) {
response.choices.add(candidates.stream().sorted().collect(toList()));
}
} finally {
super.visitReferenceElement(reference);
}
}
});
}
});
return response;
}
private static ElementPattern<? extends PsiElement> codeReferencePattern() {
return PlatformPatterns.psiElement(PsiIdentifier.class)
.withParent(PsiJavaCodeReferenceElement.class)
.withLanguage(JavaLanguage.INSTANCE);
}
@Override
public final ProblemDescriptor[] checkClass( @NotNull PsiClass psiClass,
@NotNull InspectionManager manager,
boolean isOnTheFly )
{
// If psiClass is not an interface, ignore
if( !psiClass.isInterface() )
{
return null;
}
// If @Mixins annotation is empty, ignore
List<PsiAnnotationMemberValue> mixinAnnotationValues = getMixinsAnnotationValue( psiClass );
if( mixinAnnotationValues.isEmpty() )
{
return null;
}
// Get all valid mixin type
Set<PsiClass> validMixinsType = getAllValidMixinTypes( psiClass );
if( validMixinsType.isEmpty() )
{
return null;
}
// For each mixin
List<ProblemDescriptor> problems = new LinkedList<ProblemDescriptor>();
for( PsiAnnotationMemberValue mixinAnnotationValue : mixinAnnotationValues )
{
PsiJavaCodeReferenceElement mixinClassReference = getMixinClassReference( mixinAnnotationValue );
// If it's not a class reference, ignore
if( mixinClassReference == null )
{
continue;
}
// If class reference can't be resolved, ignore
PsiClass mixinClass = (PsiClass) mixinClassReference.resolve();
if( mixinClass == null )
{
continue;
}
String mixinQualifiedName = mixinClass.getQualifiedName();
boolean isMixinsDeclarationValid = false;
String message = "";
if( mixinClass.isInterface() )
{
// Mixin can't be an interface
message = message( "mixin.implements.mixin.type.error.mixin.is.an.interface", mixinQualifiedName );
}
else if( isAConcern( mixinClass ) )
{
// Mixin can't be a concern
message = message( "mixin.implements.mixin.type.error.mixin.is.a.concern", mixinQualifiedName );
}
else if( isASideEffect( mixinClass ) )
{
// Mixin can't be a side effect
message = message( "mixin.implements.mixin.type.error.mixin.is.a.side.effect", mixinQualifiedName );
}
else
{
// If doesn't implement any mixin type, it's a problem
if( !isImplementValidMixinType( mixinClass, validMixinsType ) )
{
message = message(
"mixin.implements.mixin.type.error.does.not.implement.any.mixin.type",
mixinQualifiedName,
psiClass.getQualifiedName()
);
}
else
{
isMixinsDeclarationValid = true;
}
}
if( !isMixinsDeclarationValid )
{
ProblemDescriptor problemDescriptor = createProblemDescriptor(
manager, mixinAnnotationValue, mixinClassReference, message );
problems.add( problemDescriptor );
}
}
return problems.toArray( new ProblemDescriptor[problems.size()] );
}
public RemoveInvalidMixinClassReferenceFix( @NotNull PsiAnnotationMemberValue mixinClassAnnotationValue,
@NotNull PsiJavaCodeReferenceElement mixinClassReference )
{
super( message( "mixin.implements.mixin.type.fix.remove.class.reference", mixinClassReference.getQualifiedName() ) );
this.mixinClassAnnotationValue = mixinClassAnnotationValue;
}
@NotNull
@Override
public Class getReferenceClass() {
return PsiJavaCodeReferenceElement.class;
}
@Override
public PsiJavaCodeReferenceElement getPackageReference() {
return findChildByClass(HaxeReferenceExpression.class);
}
@NotNull
public static String getSimpleNameOf(@NotNull PsiAnnotation psiAnnotation) {
PsiJavaCodeReferenceElement referenceElement = psiAnnotation.getNameReferenceElement();
return StringUtil.notNullize(null == referenceElement ? null : referenceElement.getReferenceName());
}
@NotNull
@Override
public Class<PsiJavaCodeReferenceElement> getReferenceClass() {
return PsiJavaCodeReferenceElement.class;
}