PsiType (@Nullable PsiElement context, @NotNull GrVariable variable) { if (context == null) return variable.getType(); final GrControlFlowOwner scope = isFlatDFAAllowed() ? ControlFlowUtils.getTopmostOwner(ControlFlowUtils.findControlFlowOwner(context)) : ControlFlowUtils.findControlFlowOwner(context); if (scope == null) return null; final Instruction nearest = ControlFlowUtils.findNearestInstruction(context, scope.getControlFlow()); if (nearest == null) return null; boolean mixinOnly = variable instanceof GrField && isCompileStatic(scope); final InferenceCache cache = getInferenceCache(scope); final VariableDescriptor descriptor = createDescriptor(variable); int descriptorIndex = cache.getGroovyFlow().getIndex(descriptor); if (descriptorIndex == 0) { if (variable instanceof GrField) { // variable is not used anywhere in the scope, therefore it is enough to return its declared type return variable.getDeclaredType(); } else { return null; } } final PsiType inferredType = cache.getInferredType(descriptorIndex, nearest, mixinOnly); return inferredType != null ? inferredType : variable.getType(); }