private static boolean isOtherTypeOrDifferent( @NotNull GrReferenceExpression referenceExpression, GrVariable resolved) { if (ControlFlowUtils.findControlFlowOwner(referenceExpression) != ControlFlowUtils.findControlFlowOwner(resolved)) return true; final PsiType currentType = referenceExpression.getType(); return currentType != null && currentType != PsiType.NULL && !ControlFlowUtils.findAccess(resolved, referenceExpression, false, true).isEmpty(); }
private static boolean isTailAfterIf( @NotNull GrIfStatement ifStatement, @NotNull GrStatementOwner owner) { final GrControlFlowOwner flowOwner = ControlFlowUtils.findControlFlowOwner(ifStatement); if (flowOwner == null) return false; final Instruction[] flow = flowOwner.getControlFlow(); final GrStatement[] statements = owner.getStatements(); final int index = ArrayUtilRt.find(statements, ifStatement); if (index == statements.length - 1) return false; final GrStatement then = ifStatement.getThenBranch(); for (Instruction i : flow) { final PsiElement element = i.getElement(); if (element == null || !PsiTreeUtil.isAncestor(then, element, true)) continue; for (Instruction succ : i.allSuccessors()) { if (succ instanceof IfEndInstruction) { return false; } } } return true; }
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); } }
@Nullable public static PsiType inferReturnType(PsiElement position) { final GrControlFlowOwner flowOwner = ControlFlowUtils.findControlFlowOwner(position); if (flowOwner == null) return null; final PsiElement parent = flowOwner.getContext(); if (flowOwner instanceof GrOpenBlock && parent instanceof GrMethod) { final GrMethod method = (GrMethod) parent; if (method.isConstructor()) return null; return method.getReturnType(); } return null; }
public void generateMethodBody(GrMethod method) { final GrOpenBlock block = method.getBlock(); boolean shouldInsertReturnNull; myExitPoints.clear(); PsiType returnType = context.typeProvider.getReturnType(method); if (!method.isConstructor() && returnType != PsiType.VOID) { myExitPoints.addAll(ControlFlowUtils.collectReturns(block)); shouldInsertReturnNull = block != null && !(returnType instanceof PsiPrimitiveType) && MissingReturnInspection.methodMissesSomeReturns( block, MissingReturnInspection.ReturnStatus.getReturnStatus(method)); } else { shouldInsertReturnNull = false; } if (block != null) { generateCodeBlock(block, shouldInsertReturnNull); } }
private void checkExitPoint() { final PsiElement element = PsiTreeUtil.getParentOfType(myExpression, PsiMethod.class, GrClosableBlock.class); if (element instanceof GrMethod) { final GrMethod method = (GrMethod) element; ControlFlowUtils.visitAllExitPoints( method.getBlock(), new ControlFlowUtils.ExitPointVisitor() { @Override public boolean visitExitPoint( Instruction instruction, @Nullable GrExpression returnValue) { if (returnValue == myExpression) { final PsiType returnType = method.getReturnType(); if (returnType != null) { myResult = createSimpleSubTypeResult(returnType); } return false; } return true; } }); } }