public void visitReferenceExpression(GrReferenceExpression refExpr) { super.visitReferenceExpression(refExpr); if (myPolicy.isReferenceAccepted(refExpr)) { String name = refExpr.getReferenceName(); if (name == null) return; if (ControlFlowUtils.isIncOrDecOperand(refExpr)) { final InstructionImpl i = new ReadWriteVariableInstruction(name, refExpr, READ); addNodeAndCheckPending(i); addNode(new ReadWriteVariableInstruction(name, refExpr, WRITE)); } else { final int type = PsiUtil.isLValue(refExpr) ? WRITE : READ; addNodeAndCheckPending(new ReadWriteVariableInstruction(name, refExpr, type)); if (refExpr.getParent() instanceof GrArgumentList && refExpr.getParent().getParent() instanceof GrCall) { addNodeAndCheckPending(new ArgumentInstruction(refExpr)); } } } if (refExpr.isQualified() && !(refExpr.getParent() instanceof GrCall)) { visitCall(refExpr); } }
private static void registerReferenceFixes( GrReferenceExpression refExpr, HighlightInfo info, boolean compileStatic, final HighlightDisplayKey key) { PsiClass targetClass = QuickfixUtil.findTargetClass(refExpr, compileStatic); if (targetClass == null) return; if (!compileStatic) { addDynamicAnnotation(info, refExpr, key); } if (targetClass.isWritable()) { QuickFixAction.registerQuickFixAction( info, new CreateFieldFromUsageFix(refExpr, targetClass), key); if (refExpr.getParent() instanceof GrCall && refExpr.getParent() instanceof GrExpression) { QuickFixAction.registerQuickFixAction( info, new CreateMethodFromUsageFix(refExpr, targetClass), key); } } if (!refExpr.isQualified()) { GrVariableDeclarationOwner owner = PsiTreeUtil.getParentOfType(refExpr, GrVariableDeclarationOwner.class); if (!(owner instanceof GroovyFileBase) || ((GroovyFileBase) owner).isScript()) { QuickFixAction.registerQuickFixAction( info, new CreateLocalVariableFromUsageFix(refExpr, owner), key); } if (PsiTreeUtil.getParentOfType(refExpr, GrMethod.class) != null) { QuickFixAction.registerQuickFixAction(info, new CreateParameterFromUsageFix(refExpr), key); } } }
private static boolean isPropertyAccessInStaticMethod(GrReferenceExpression referenceExpression) { if (referenceExpression.getParent() instanceof GrMethodCall || referenceExpression.getQualifier() != null) return false; GrMember context = PsiTreeUtil.getParentOfType( referenceExpression, GrMember.class, true, GrClosableBlock.class); return (context instanceof GrMethod || context instanceof GrClassInitializer) && context.hasModifierProperty(STATIC); }
@Nullable private static HighlightInfo checkRefInner(GrReferenceExpression ref) { PsiElement refNameElement = ref.getReferenceNameElement(); if (refNameElement == null) return null; boolean cannotBeDynamic = PsiUtil.isCompileStatic(ref) || isPropertyAccessInStaticMethod(ref); GroovyResolveResult resolveResult = getBestResolveResult(ref); if (resolveResult.getElement() != null) { if (!isInspectionEnabled(ref.getContainingFile(), ref.getProject())) return null; if (isStaticOk(resolveResult)) return null; String message = GroovyBundle.message("cannot.reference.non.static", ref.getReferenceName()); return createAnnotationForRef(ref, cannotBeDynamic, message); } if (ResolveUtil.isKeyOfMap(ref) || isClassReference(ref)) { return null; } if (!cannotBeDynamic) { if (!isInspectionEnabled(ref.getContainingFile(), ref.getProject())) return null; GrUnresolvedAccessInspection inspection = getInstance(ref.getContainingFile(), ref.getProject()); if (!inspection.myHighlightIfGroovyObjectOverridden && areGroovyObjectMethodsOverridden(ref)) return null; if (!inspection.myHighlightIfMissingMethodsDeclared && areMissingMethodsDeclared(ref)) return null; if (GroovySuppressableInspectionTool.isElementToolSuppressedIn(ref, SHORT_NAME)) return null; } if (cannotBeDynamic || shouldHighlightAsUnresolved(ref)) { HighlightInfo info = createAnnotationForRef( ref, cannotBeDynamic, GroovyBundle.message("cannot.resolve", ref.getReferenceName())); LOG.assertTrue(info != null); HighlightDisplayKey displayKey = HighlightDisplayKey.find(SHORT_NAME); if (ref.getParent() instanceof GrMethodCall) { registerStaticImportFix(ref, info, displayKey); } else { registerCreateClassByTypeFix(ref, info, displayKey); registerAddImportFixes(ref, info, displayKey); } registerReferenceFixes(ref, info, cannotBeDynamic, displayKey); UnresolvedReferenceQuickFixProvider.registerReferenceFixes( ref, new QuickFixActionRegistrarAdapter(info, displayKey)); OrderEntryFix.registerFixes(new QuickFixActionRegistrarAdapter(info, displayKey), ref); return info; } return null; }
private static void registerStaticImportFix( @NotNull GrReferenceExpression referenceExpression, @Nullable HighlightInfo info, @Nullable final HighlightDisplayKey key) { final String referenceName = referenceExpression.getReferenceName(); if (StringUtil.isEmpty(referenceName)) return; if (referenceExpression.getQualifier() != null) return; QuickFixAction.registerQuickFixAction( info, new GroovyStaticImportMethodFix((GrMethodCall) referenceExpression.getParent()), key); }
private static boolean areMissingMethodsDeclared(GrReferenceExpression ref) { PsiType qualifierType = GrReferenceResolveUtil.getQualifierType(ref); if (!(qualifierType instanceof PsiClassType)) return false; PsiClass resolved = ((PsiClassType) qualifierType).resolve(); if (resolved == null) return false; if (ref.getParent() instanceof GrCall) { PsiMethod[] found = resolved.findMethodsByName("methodMissing", true); for (PsiMethod method : found) { if (MissingMethodAndPropertyUtil.isMethodMissing(method)) return true; } } else { PsiMethod[] found = resolved.findMethodsByName("propertyMissing", true); for (PsiMethod method : found) { if (MissingMethodAndPropertyUtil.isPropertyMissing(method)) return true; } } return false; }
private static boolean areGroovyObjectMethodsOverridden(GrReferenceExpression ref) { PsiType qualifierType = GrReferenceResolveUtil.getQualifierType(ref); if (!(qualifierType instanceof PsiClassType)) return false; PsiClass resolved = ((PsiClassType) qualifierType).resolve(); if (resolved == null) return false; PsiClass groovyObject = JavaPsiFacade.getInstance(ref.getProject()) .findClass(GroovyCommonClassNames.GROOVY_OBJECT, ref.getResolveScope()); if (groovyObject == null) return false; String methodName; if (ref.getParent() instanceof GrCall) { methodName = "invokeMethod"; } else if (PsiUtil.isLValue(ref)) { methodName = "setProperty"; } else { methodName = "getProperty"; } PsiMethod[] patternMethods = groovyObject.findMethodsByName(methodName, false); if (patternMethods.length != 1) return false; PsiMethod patternMethod = patternMethods[0]; PsiMethod found = resolved.findMethodBySignature(patternMethod, true); if (found == null) return false; PsiClass aClass = found.getContainingClass(); if (aClass == null) return false; String qname = aClass.getQualifiedName(); if (GroovyCommonClassNames.GROOVY_OBJECT.equals(qname)) return false; if (GroovyCommonClassNames.GROOVY_OBJECT_SUPPORT.equals(qname)) return false; return true; }