@Override @Nullable public PsiDocCommentOwner getContainer(final PsiElement element) { PsiDocCommentOwner container = super.getContainer(element); if (container == null || container instanceof PsiClass){ return null; } while (container != null ) { final PsiClass parentClass = PsiTreeUtil.getParentOfType(container, PsiClass.class); if ((parentClass == null || container.getParent() instanceof PsiDeclarationStatement || container.getParent() instanceof PsiClass) && container instanceof PsiClass){ return container; } container = parentClass; } return container; }
private PsiMethodCallExpression findMethodCall(PsiElement element) { // This covers the case if there is a method being used to initialize a variable.. // i.e int a = random(); if (element instanceof PsiDeclarationStatement) { PsiDeclarationStatement declarationStatement = (PsiDeclarationStatement) element; for (PsiElement declarationElement : declarationStatement.getDeclaredElements()) { if (declarationElement instanceof PsiVariable) { PsiVariable variable = (PsiVariable) declarationElement; PsiExpression initializer = variable.getInitializer(); if (initializer instanceof PsiMethodCallExpression) { return (PsiMethodCallExpression) initializer; } } } } if (element instanceof PsiExpressionStatement) { PsiExpression expression = ((PsiExpressionStatement) element).getExpression(); if (expression instanceof PsiMethodCallExpression) { return (PsiMethodCallExpression) expression; } } return null; }
public void verifyVariable(@NotNull final PsiLocalVariable psiLocalVariable, @NotNull final ProblemsHolder holder) { boolean isVal = isSameName(psiLocalVariable.getTypeElement().getText()); boolean isVar = isVar(psiLocalVariable.getTypeElement().getText()); final String ann = isVal ? "val" : "var"; if (isVal || isVar) { final PsiExpression initializer = psiLocalVariable.getInitializer(); if (initializer == null) { holder.registerProblem(psiLocalVariable, "'" + ann + "' on a local variable requires an initializer expression", ProblemHighlightType.ERROR); } else if (initializer instanceof PsiArrayInitializerExpression) { holder.registerProblem(psiLocalVariable, "'" + ann + "' is not compatible with array initializer expressions. Use the full form (new int[] { ... } instead of just { ... })", ProblemHighlightType.ERROR); } else if (initializer instanceof PsiLambdaExpression) { holder.registerProblem(psiLocalVariable, "'" + ann + "' is not allowed with lambda expressions.", ProblemHighlightType.ERROR); } else if (isVal) { final PsiElement typeParentParent = psiLocalVariable.getParent(); if (typeParentParent instanceof PsiDeclarationStatement && typeParentParent.getParent() instanceof PsiForStatement) { holder.registerProblem(psiLocalVariable, "'" + ann + "' is not allowed in old-style for loops", ProblemHighlightType.ERROR); } } } }
@Override public void visitDeclarationStatement( @NotNull PsiDeclarationStatement statement) { if (assignedFrom) { return; } super.visitDeclarationStatement(statement); final PsiElement[] declaredElements = statement.getDeclaredElements(); for (PsiElement declaredElement : declaredElements) { if (declaredElement instanceof PsiVariable) { final PsiVariable declaredVariable = (PsiVariable)declaredElement; final PsiExpression initializer = declaredVariable.getInitializer(); if (initializer != null && VariableAccessUtils.mayEvaluateToVariable(initializer, variable)) { assignedFrom = true; return; } } } }
private static void extractDeclarations(@NonNull PsiElement element, List<PsiDeclarationStatement> declarations) { for (PsiElement child : element.getChildren()) { if (child instanceof PsiDeclarationStatement) { declarations.add((PsiDeclarationStatement) child); continue; } extractDeclarations(child, declarations); } }
/** * ローカル変数取得 (宣言文で定義された変数) * @param declaration ルートノード * @return ローカル変数 (空要素の場合もあります) */ public static @Nullable PsiLocalVariable getVariable(PsiDeclarationStatement declaration) { PsiElement[] elements = declaration.getDeclaredElements(); for (PsiElement element : elements) { if (element instanceof PsiLocalVariable) { PsiLocalVariable valiable = (PsiLocalVariable) element; return valiable; } } return null; }
public static void debugDeclarations(String tag, PsiElement root, List<PsiDeclarationStatement> declarations) { System.out.println(tag + " :root=>>>>\n" + root.getText() + "\n<<<"); for (PsiDeclarationStatement declaration : declarations) { System.out.println("declaration -> " + declaration.getText()); debugVariable(declaration); } System.out.println(); }
/** * 宣言文抽出 * @param element ルートノード * @return 宣言文のリスト (空要素の場合もあります) */ public static @NonNull List<PsiDeclarationStatement> extractDeclarations(@NonNull PsiElement element) { List<PsiDeclarationStatement> declarations = new ArrayList<>(); extractDeclarations(element, declarations); return declarations; }
public static void debugVariable(PsiDeclarationStatement declaration) { PsiLocalVariable variable = getVariable(declaration); debugVariable(variable); System.out.println(); }
@Override public void visitDeclarationStatement(PsiDeclarationStatement statement) { mVisitor.report("PsiDeclarationStatement", statement.getText(), statement); super.visitStatement(statement); }
@Override public void visitClass(@NotNull PsiClass aClass) { if (aClass.getParent() instanceof PsiDeclarationStatement) { registerClassError(aClass); } }
@Nullable public static CountingLoop from(PsiForStatement forStatement) { // check that initialization is for(int/long i = <initial_value>;...;...) PsiDeclarationStatement initialization = tryCast(forStatement.getInitialization(), PsiDeclarationStatement.class); if(initialization == null || initialization.getDeclaredElements().length != 1) { return null; } PsiLocalVariable counter = tryCast(initialization.getDeclaredElements()[0], PsiLocalVariable.class); if(counter == null) { return null; } if(!counter.getType().equals(PsiType.INT) && !counter.getType().equals(PsiType.LONG)) { return null; } PsiExpression initializer = PsiUtil.skipParenthesizedExprDown(counter.getInitializer()); if(initializer == null) { return null; } // check that increment is like for(...;...;i++) if(!VariableAccessUtils.variableIsIncremented(counter, forStatement.getUpdate())) { return null; } // check that condition is like for(...;i<bound;...) or for(...;i<=bound;...) PsiBinaryExpression condition = tryCast(forStatement.getCondition(), PsiBinaryExpression.class); if(condition == null) { return null; } IElementType type = condition.getOperationTokenType(); boolean closed = false; PsiExpression bound; PsiExpression ref; if(type.equals(JavaTokenType.LE)) { bound = condition.getROperand(); ref = condition.getLOperand(); closed = true; } else if(type.equals(JavaTokenType.LT)) { bound = condition.getROperand(); ref = condition.getLOperand(); } else if(type.equals(JavaTokenType.GE)) { bound = condition.getLOperand(); ref = condition.getROperand(); closed = true; } else if(type.equals(JavaTokenType.GT)) { bound = condition.getLOperand(); ref = condition.getROperand(); } else { return null; } if(bound == null || !ExpressionUtils.isReferenceTo(ref, counter)) { return null; } if(!TypeConversionUtil.areTypesAssignmentCompatible(counter.getType(), bound)) { return null; } return new CountingLoop(forStatement, counter, initializer, bound, closed); }
@Override public void apply(Editor editor, JavaSmartEnterProcessor processor, PsiElement psiElement) throws IncorrectOperationException { if(!(psiElement instanceof PsiMethod)) { return; } PsiMethod method = (PsiMethod) psiElement; final PsiClass containingClass = method.getContainingClass(); if(!shouldHaveBody(method)) { return; } final PsiCodeBlock body = method.getBody(); final Document doc = editor.getDocument(); if(body != null) { // See IDEADEV-1093. This is quite hacky heuristic but it seem to be best we can do. String bodyText = body.getText(); if(bodyText.startsWith("{")) { final PsiStatement[] statements = body.getStatements(); if(statements.length > 0) { if(statements[0] instanceof PsiDeclarationStatement) { if(PsiTreeUtil.getDeepestLast(statements[0]) instanceof PsiErrorElement) { if(containingClass.getRBrace() == null) { doc.insertString(body.getTextRange().getStartOffset() + 1, "\n}"); } } } } } return; } int endOffset = method.getThrowsList().getTextRange().getEndOffset(); if(endOffset < doc.getTextLength() && doc.getCharsSequence().charAt(endOffset) == ';') { doc.deleteString(endOffset, endOffset + 1); } doc.insertString(endOffset, "{\n}"); }
@Nullable public static PsiElement getContextElement(final StackFrameContext context, final SourcePosition position) { if(LOG.isDebugEnabled()) { final SourcePosition sourcePosition = getSourcePosition(context); LOG.assertTrue(Comparing.equal(sourcePosition, position)); } return ReadAction.compute(() -> { final PsiElement element = getContextElement(position); if(element == null) { return null; } // further code is java specific, actually if(element.getLanguage().getAssociatedFileType() != DefaultCodeFragmentFactory.getInstance().getFileType()) { return element; } final StackFrameProxyImpl frameProxy = (StackFrameProxyImpl) context.getFrameProxy(); if(frameProxy == null) { return element; } try { List<LocalVariableProxyImpl> list = frameProxy.visibleVariables(); PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(element.getProject()).getResolveHelper(); StringBuilder buf = null; for(LocalVariableProxyImpl localVariable : list) { final String varName = localVariable.name(); if(resolveHelper.resolveReferencedVariable(varName, element) == null) { if(buf == null) { buf = new StringBuilder("{"); } buf.append(localVariable.getVariable().typeName()).append(" ").append(varName).append(";"); } } if(buf == null) { return element; } buf.append('}'); final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(element.getProject()).getElementFactory(); final PsiCodeBlock codeBlockFromText = elementFactory.createCodeBlockFromText(buf.toString(), element); final PsiStatement[] statements = codeBlockFromText.getStatements(); for(PsiStatement statement : statements) { if(statement instanceof PsiDeclarationStatement) { PsiDeclarationStatement declStatement = (PsiDeclarationStatement) statement; PsiElement[] declaredElements = declStatement.getDeclaredElements(); for(PsiElement declaredElement : declaredElements) { declaredElement.putUserData(IS_JSP_IMPLICIT, Boolean.TRUE); } } } return codeBlockFromText; } catch(IncorrectOperationException | EvaluateException ignored) { return element; } }); }