@Nullable @Override public PsiElement getElementByReference(@NotNull PsiReference ref, int flags) { if (ref instanceof JSTextReference) { final PsiElement element = ref.getElement(); final JSCallExpression call = PsiTreeUtil.getParentOfType(element, JSCallExpression.class); final JSExpression expression = call != null ? call.getMethodExpression() : null; if (expression instanceof JSReferenceExpression) { JSReferenceExpression callee = (JSReferenceExpression)expression; JSExpression qualifier = callee.getQualifier(); if (qualifier != null && "component".equals(callee.getReferencedName()) && EmberIndexUtil.hasEmberJS(element.getProject())) { return element; } } } return null; }
@Override public void visitJSCallExpression(JSCallExpression jsCallExpression) { super.visitJSCallExpression(jsCallExpression); final JSExpression methodExpression; try { methodExpression = jsCallExpression.getMethodExpression(); } catch (Exception e) { return; //catching an intelliJ CCE } if (!(methodExpression instanceof JSReferenceExpression)) { return; } final JSReferenceExpression referenceExpression = (JSReferenceExpression) methodExpression; final JSExpression qualifier = referenceExpression.getQualifier(); @NonNls final String methodName = referenceExpression.getReferencedName(); if (!"eval".equals(methodName) && !"setTimeout".equals(methodName) && !"setInterval".equals(methodName)) { return; } registerError(methodExpression); }
@Override public void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { final JSIfStatement exp = (JSIfStatement) element; final JSExpression condition = exp.getCondition(); final JSStatement thenBranch = exp.getThen(); final JSStatement elseBranch = exp.getElse(); final String negatedText = BoolUtils.getNegatedExpressionText(condition); final boolean emptyThenBranch = (thenBranch == null || (thenBranch instanceof JSBlockStatement && ((JSBlockStatement) thenBranch).getStatements().length == 0)); final String thenText = (emptyThenBranch ? "" : ELSE_KEYWORD + thenBranch.getText()); final String elseText = ((elseBranch == null) ? "{}" : elseBranch.getText()); final String newStatement = IF_PREFIX + negatedText + ')' + elseText + thenText; JSElementFactory.replaceStatement(exp, newStatement); }
@Override public void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { assert (element.getParent() != null); assert (element.getParent() instanceof JSIfStatement || element instanceof JSIfStatement); final JSIfStatement parentStatement = (JSIfStatement) (element.getParent() instanceof JSIfStatement ? element.getParent() : element); final JSIfStatement childStatement = (JSIfStatement) ConditionalUtils.stripBraces(parentStatement.getThen()); final JSExpression childCondition = childStatement.getCondition(); final JSExpression parentCondition = parentStatement.getCondition(); final String childConditionText = ParenthesesUtils.getParenthesized(childCondition, ParenthesesUtils.AND_PRECENDENCE); final String parentConditionText = ParenthesesUtils.getParenthesized(parentCondition, ParenthesesUtils.AND_PRECENDENCE); final JSStatement childThenBranch = childStatement.getThen(); final String statement = IF_STATEMENT_PREFIX + parentConditionText + " && " + childConditionText + ')' + childThenBranch.getText(); JSElementFactory.replaceStatement(parentStatement, statement); }
private static boolean isConstantMask(JSExpression expression) { if (expression == null) { return false; } if (!(expression instanceof JSBinaryExpression)) { return false; } final JSBinaryExpression binaryExpression = (JSBinaryExpression) expression; final IElementType tokenType = binaryExpression.getOperationSign(); if (!JSTokenTypes.OR.equals(tokenType) && !JSTokenTypes.AND.equals(tokenType)) { return false; } final JSExpression rhs = binaryExpression.getROperand(); if (ExpressionUtil.isConstantExpression(rhs)) { return true; } final JSExpression lhs = binaryExpression.getLOperand(); return ExpressionUtil.isConstantExpression(lhs); }
@Override public boolean satisfiedBy(@NotNull PsiElement element) { if (!(element instanceof JSBinaryExpression)) { return false; } final JSBinaryExpression expression = (JSBinaryExpression) element; final IElementType sign = expression.getOperationSign(); if (!sign.equals(JSTokenTypes.PLUS)) { return false; } final JSExpression lhs = expression.getLOperand(); final JSExpression rhs = expression.getROperand(); if (!isApplicableLiteral(lhs)) { return false; } if (!isApplicableLiteral(rhs)) { return false; } return true; }
@Override public boolean satisfiedBy(@NotNull PsiElement element) { if (!(element instanceof JSConditionalExpression)) { return false; } if (ErrorUtil.containsError(element)) { return false; } final JSConditionalExpression condition = (JSConditionalExpression) element; final JSExpression thenExpression = ParenthesesUtils.stripParentheses(condition.getThen()); final JSExpression elseExpression = ParenthesesUtils.stripParentheses(condition.getElse()); if (condition.getCondition() == null || thenExpression == null || elseExpression == null) { return false; } final String thenText = thenExpression.getText(); final String elseText = elseExpression.getText(); return ((BoolUtils.TRUE.equals(elseText) && BoolUtils.FALSE.equals(thenText)) || (BoolUtils.TRUE.equals(thenText) && BoolUtils.FALSE.equals(elseText))); }
@Override public JSExpression getIndexExpression() { ASTNode child = getNode().getFirstChildNode(); boolean bracketPassed = false; while(child != null) { final IElementType type = child.getElementType(); if(type == JSTokenTypes.LBRACKET) { bracketPassed = true; } if(bracketPassed && JSElementTypes.EXPRESSIONS.contains(type)) { return (JSExpression) child.getPsi(); } child = child.getTreeNext(); } return null; }
private static boolean binaryExpressionDefinitelyRecurses( JSBinaryExpression expression, JSFunction method) { final JSExpression lhs = expression.getLOperand(); if (RecursionUtil.expressionDefinitelyRecurses(lhs, method)) { return true; } final IElementType tokenType = expression.getOperationSign(); if (tokenType.equals(JSTokenTypes.ANDAND) || tokenType.equals(JSTokenTypes.OROR)) { return false; } return RecursionUtil.expressionDefinitelyRecurses(expression.getROperand(), method); }
@Override public void visitJSBinaryExpression(@NotNull JSBinaryExpression expression) { super.visitJSBinaryExpression(expression); if (!(expression.getROperand() != null)) { return; } if (!ComparisonUtils.isComparison(expression)) { return; } final JSExpression lhs = expression.getLOperand(); final JSExpression rhs = expression.getROperand(); if (lhs instanceof JSLiteralExpression || !(rhs instanceof JSLiteralExpression)) { return; } registerError(expression); }
@Override public void visitJSBinaryExpression( @NotNull JSBinaryExpression expression) { super.visitJSBinaryExpression(expression); final JSExpression rhs = expression.getROperand(); if (rhs == null) { return; } final IElementType tokenType = expression.getOperationSign(); if (!JSTokenTypes.DIV.equals(tokenType) && !JSTokenTypes.PERC.equals(tokenType)) { return; } if(!isZero(rhs)) { return; } registerError(expression); }
@Override public void visitJSConditionalExpression(JSConditionalExpression exp) { super.visitJSConditionalExpression(exp); final JSExpression thenExpression = exp.getThen(); if (thenExpression == null) { return; } final JSExpression elseExpression = exp.getElse(); if (elseExpression == null) { return; } if (((isFalse(thenExpression) && isTrue(elseExpression)) || (isTrue(thenExpression) && isFalse(elseExpression))) && "Boolean".equals(JSResolveUtil.getExpressionType(exp.getCondition(), exp.getContainingFile())) ) { registerError(exp); } }
@Override public JSExpression getCollectionExpression() { ASTNode child = getNode().getFirstChildNode(); boolean inPassed = false; while(child != null) { if(child.getElementType() == JSTokenTypes.IN_KEYWORD) { inPassed = true; } if(inPassed && JSElementTypes.EXPRESSIONS.contains(child.getElementType())) { return (JSExpression) child.getPsi(); } child = child.getTreeNext(); } return null; }
@Override public boolean processDeclarations(@NotNull PsiScopeProcessor processor, @NotNull ResolveState state, PsiElement lastParent, @NotNull PsiElement place) { if(lastParent != null) { final JSVarStatement statement = getDeclarationStatement(); if(statement != null) { return statement.processDeclarations(processor, state, lastParent, place); } else { final JSExpression expression = getVariableExpression(); if(expression != null && !processor.execute(expression, null)) { return false; } } } return true; }
@NotNull @Override public JavaScriptType getType() { final JSExpression initializer = getInitializer(); if(initializer != null) { JavaScriptType javaScriptType = RecursionManager.doPreventingRecursion(this, false, new Computable<JavaScriptType>() { @Override @RequiredReadAction public JavaScriptType compute() { return initializer.getType(); } }); return javaScriptType == null ? JavaScriptType.UNKNOWN : javaScriptType; } return JavaScriptType.UNKNOWN; }
public static JSExpression replaceExpression(@NotNull JSExpression expression, @NotNull JSExpression newExpression) throws IncorrectOperationException { final ASTNode newExpressionNode = newExpression.getNode(); final ASTNode oldExpressionNode = expression.getNode(); final PsiElement parentNode = expression.getParent(); final ASTNode grandParentNode = parentNode.getNode(); if (grandParentNode == null || oldExpressionNode == null || newExpressionNode == null) { return null; } grandParentNode.replaceChild(oldExpressionNode, newExpressionNode); reformat(parentNode); return (JSExpression) newExpressionNode.getPsi(); }
@Override public JSExpression getCondition() { ASTNode child = getNode().getFirstChildNode(); int semicolonCount = 0; while(child != null) { if(child.getElementType() == JSTokenTypes.SEMICOLON) { semicolonCount++; if(semicolonCount == 2) { return null; } } else if(semicolonCount == 1 && JSElementTypes.EXPRESSIONS.contains(child.getElementType())) { return (JSExpression) child.getPsi(); } child = child.getTreeNext(); } return null; }
@Override public JSExpression getUpdate() { ASTNode child = getNode().getFirstChildNode(); int semicolonCount = 0; while(child != null) { if(child.getElementType() == JSTokenTypes.SEMICOLON) { semicolonCount++; } else if(semicolonCount == 2 && JSElementTypes.EXPRESSIONS.contains(child.getElementType())) { return (JSExpression) child.getPsi(); } child = child.getTreeNext(); } return null; }
private void mergeForInStatements(StringBuilder statementBuffer, JSForInStatement firstStatement, JSForInStatement secondStatement) { final JSExpression variableExpression = getVariableExpression(firstStatement); final JSVarStatement declaration = firstStatement.getDeclarationStatement(); final JSExpression collectionExpression = getCollectionExpression(firstStatement); final JSStatement firstBody = firstStatement .getBody(); final JSStatement secondBody = secondStatement.getBody(); statementBuffer.append(FOR_IN_PREFIX) .append((declaration == null) ? variableExpression.getText() : declaration.getText()) .append(FOR_IN_COLLECTION_PREFIX) .append(collectionExpression.getText()) .append(')'); ControlFlowUtils.appendStatementsInSequence(statementBuffer, firstBody, secondBody); }
private static boolean callExpressionDefinitelyRecurses( JSCallExpression exp, JSFunction method) { final JSFunction calledMethod = ControlFlowUtils.resolveMethod(exp); if (calledMethod != null && calledMethod.equals(method)) { return true; } final JSExpression methodExpression = exp.getMethodExpression(); if (methodExpression == null) { return false; } else if (RecursionUtil.expressionDefinitelyRecurses(methodExpression, method)) { return true; } for (final JSExpression arg : exp.getArgumentList().getArguments()) { if (RecursionUtil.expressionDefinitelyRecurses(arg, method)) { return true; } } return false; }
@Override protected String getTextForElement(PsiElement element) { final PsiElement parent = element.getParent(); final JSBinaryExpression binaryExpression = (JSBinaryExpression) (parent instanceof JSBinaryExpression ? parent : element); final JSExpression lhs = binaryExpression.getLOperand(); final JSExpression leftSide; if (lhs instanceof JSBinaryExpression) { leftSide = ((JSBinaryExpression) lhs).getROperand(); } else { leftSide = lhs; } final IElementType operationSign = binaryExpression.getOperationSign(); final JSExpression rhs = binaryExpression.getROperand(); assert (rhs != null); assert (leftSide != null); return this.getText(leftSide.getText(), BinaryOperatorUtils.getOperatorText(operationSign), rhs.getText()); }
/** * Method provided as a workaround of a bug in the JavaScript language IDEA plugin. * @param forInStatement the for-in statement * @return the for-in statement collection expression */ private static JSExpression getVariableExpression(JSForInStatement forInStatement) { final ASTNode statementNode = forInStatement.getNode(); ASTNode child = ((statementNode == null) ? null : statementNode.getFirstChildNode()); while (child != null) { if (child.getElementType() == JSTokenTypes.IN_KEYWORD) { return null; } if (JSElementTypes.EXPRESSIONS.contains(child.getElementType())) { return (JSExpression) child.getPsi(); } child = child.getTreeNext(); } return null; }
private static JSExpression findExpressionInRange(PsiFile file, int startOffset, int endOffset) { PsiElement element1 = file.findElementAt(startOffset); PsiElement element2 = file.findElementAt(endOffset - 1); if(element1 instanceof PsiWhiteSpace) { startOffset = element1.getTextRange().getEndOffset(); } if(element2 instanceof PsiWhiteSpace) { endOffset = element2.getTextRange().getStartOffset(); } JSExpression expression = PsiTreeUtil.findElementOfClassAtRange(file, startOffset, endOffset, JSExpression.class); if(expression == null || expression.getTextRange().getEndOffset() != endOffset) { return null; } if(expression instanceof JSReferenceExpression && expression.getParent() instanceof JSCallExpression) { return null; } return expression; }
public static int getLogBase2(JSExpression rhs) { final String value = rhs.getText(); long intValue; try { intValue = Integer.decode(value).longValue(); } catch (NumberFormatException e) { assert(false); return 0; } int log = 0; while ((intValue & 1) == 0) { intValue >>= 1; log++; } return log; }
private boolean isAssignmentShiftByLiteral(JSAssignmentExpression expression) { final IElementType tokenType = expression.getOperationSign(); if (tokenType == null || !(tokenType.equals(JSTokenTypes.LTLTEQ) || tokenType.equals(JSTokenTypes.GTGTEQ) ) ) { return false; } final JSExpression rhs = expression.getROperand(); if (rhs == null) { return false; } return ShiftUtils.isIntLiteral(rhs); }
public JSExpression getCollection() { final ASTNode myNode = getNode(); final ASTNode secondExpression = myNode.findChildByType( JSElementTypes.EXPRESSIONS, myNode.findChildByType(JSTokenTypes.IN_KEYWORD) ); return secondExpression != null ? (JSExpression) secondExpression.getPsi() : null; }
public static boolean containsTestsInFiles(JSFile file) { JSSourceElement[] statements = file.getStatements(); for(JSSourceElement statement : statements) { if(statement instanceof JSExpressionStatement) { JSExpression expression = ((JSExpressionStatement) statement).getExpression(); if(expression instanceof JSCallExpression) { JSExpression methodExpression = ((JSCallExpression) expression).getMethodExpression(); if(methodExpression instanceof JSReferenceExpression) { JSExpression qualifier = ((JSReferenceExpression) methodExpression).getQualifier(); if(qualifier != null) { continue; } String referencedName = ((JSReferenceExpression) methodExpression).getReferencedName(); if("describe".equals(referencedName)) { JSArgumentList argumentList = ((JSCallExpression) expression).getArgumentList(); if(argumentList != null && argumentList.getArguments().length == 2) { return true; } } } } } } return false; }
public JSExpression getCollection() { final ASTNode myNode = getNode(); final ASTNode secondExpression = myNode.findChildByType( JSElementTypes.EXPRESSIONS, myNode.findChildByType(JSTokenTypes.IN_KEYWORD) ); return secondExpression != null ? (JSExpression)secondExpression.getPsi() : null; }
private static void collectCaseLabels(JSSwitchStatement statement, Set<JSExpression> conditions) { final JSCaseClause[] clauses = statement.getCaseClauses(); for (JSCaseClause clause : clauses) { if (!clause.isDefault()) { final JSExpression caseExpression = clause.getCaseExpression(); if (caseExpression != null) { conditions.add(caseExpression); } } } }
public static boolean forInStatementsCanBeMerged(JSForInStatement statement1, JSForInStatement statement2) { // final JSExpression firstVarExpression = statement1.getVariableExpression(); // final JSExpression secondVarExpression = statement2.getVariableExpression(); final JSExpression firstVarExpression = getVariableExpression(statement1); final JSExpression secondVarExpression = getVariableExpression(statement2); if (!EquivalenceChecker.expressionsAreEquivalent(firstVarExpression, secondVarExpression)) { return false; } final JSVarStatement firstDeclaration = statement1.getDeclarationStatement(); final JSVarStatement secondDeclaration = statement2.getDeclarationStatement(); if (!EquivalenceChecker.statementsAreEquivalent(firstDeclaration, secondDeclaration)) { return false; } // final JSExpression firstCollection = statement1.getCollectionExpression(); // final JSExpression secondCollection = statement2.getCollectionExpression(); final JSExpression firstCollection = getCollectionExpression(statement1); final JSExpression secondCollection = getCollectionExpression(statement2); if (!EquivalenceChecker.expressionsAreEquivalent(firstCollection, secondCollection)) { return false; } final JSStatement firstBody = statement1.getBody(); final JSStatement secondBody = statement2.getBody(); return (firstBody == null || secondBody == null || ControlFlowUtils.canBeMerged(firstBody, secondBody)); }
@Override public void visitJSBinaryExpression( @NotNull JSBinaryExpression expression) { super.visitJSBinaryExpression(expression); if (!(expression.getROperand() != null)) { return; } final IElementType sign = expression.getOperationSign(); if (!arithmeticTokens.contains(sign)) { return; } final JSExpression rhs = expression.getROperand(); final JSExpression lhs = expression.getLOperand(); if (rhs == null) { return; } final boolean isPointless; if (sign.equals(JSTokenTypes.PLUS)) { isPointless = additionExpressionIsPointless(lhs, rhs); } else if (sign.equals(JSTokenTypes.MINUS)) { isPointless = subtractionExpressionIsPointless(rhs); } else if (sign.equals(JSTokenTypes.MULT)) { isPointless = multiplyExpressionIsPointless(lhs, rhs); } else if (sign.equals(JSTokenTypes.DIV)) { isPointless = divideExpressionIsPointless(rhs); } else { isPointless = false; } if (!isPointless) { return; } registerError(expression); }
private static boolean isMultiplyByPowerOfTwo(JSBinaryExpression expression) { final IElementType operator = expression.getOperationSign(); if (operator == null || !(operator.equals(JSTokenTypes.MULT) || operator.equals(JSTokenTypes.DIV))) { return false; } final JSExpression leftOperand = expression.getLOperand(); final JSExpression rightOperand = expression.getROperand(); if (leftOperand == null || rightOperand == null) { return false; } return (ShiftUtils.isPowerOfTwo(leftOperand) || ShiftUtils.isPowerOfTwo(rightOperand)); }
public static boolean isComparison(@Nullable JSExpression exp) { if (!(exp instanceof JSBinaryExpression)) { return false; } final JSBinaryExpression binaryExpression = (JSBinaryExpression) exp; final IElementType sign = binaryExpression.getOperationSign(); return s_comparisonStrings.contains(sign); }
public MockJSArrayLiteralExpression(String[] defines) { super(mock(ASTNode.class)); expressions = new JSExpression[defines.length]; for(int i=0;i<defines.length;i++) { expressions[i] = new MockJSLiteralExpression(defines[i]); } }
private boolean isZero(JSExpression expression) { if (m_ignoreExpressionsContainingConstants && !(expression instanceof JSLiteralExpression)) { return false; } final Object value = ExpressionUtil.computeConstantExpression(expression); return value instanceof Integer && (Integer) value == 0; }
public static void replaceSimplifiableReturn(JSIfStatement statement, boolean negated) throws IncorrectOperationException { final JSExpression condition = statement.getCondition(); final String conditionText = (negated ? BoolUtils.getNegatedExpressionText(condition) : condition.getText()); @NonNls final String newStatement = "return " + conditionText + ';'; JSElementFactory.replaceStatement(statement, newStatement); }
@Override public void visitJSBinaryExpression( @NotNull JSBinaryExpression expression) { super.visitJSBinaryExpression(expression); final JSExpression rhs = expression.getROperand(); if (!ComparisonUtils.isEqualityComparison(expression)) { return; } final JSExpression strippedRhs = ParenthesesUtils.stripParentheses(rhs); if (strippedRhs == null) { return; } final JSExpression lhs = expression.getLOperand(); final JSExpression strippedLhs = ParenthesesUtils.stripParentheses(lhs); if (strippedLhs == null) { return; } if (isConstantMask(strippedLhs) && ExpressionUtil.isConstantExpression(strippedRhs)) { if (isIncompatibleMask((JSBinaryExpression) strippedLhs, strippedRhs)) { registerError(expression, expression); } } else if (isConstantMask(strippedRhs) && ExpressionUtil.isConstantExpression(strippedLhs)) { if (isIncompatibleMask((JSBinaryExpression) strippedRhs, strippedLhs)) { registerError(expression, expression); } } }
private static boolean arrayLiteralExpressionDefinitelyRecurses( JSArrayLiteralExpression expression, JSFunction method) { for (final JSExpression initializer : expression.getExpressions()) { if (RecursionUtil.expressionDefinitelyRecurses(initializer, method)) { return true; } } return false; }
@Test public void testPropertyIsGenerated() { List<JSExpressionStatement> methods = new ArrayList<JSExpressionStatement>(); methods.add(new MockJSExpressionStatement(new MockJSAssignmentExpression("util.", "property", "'value'"))); String result = converter.buildUtilPatternString(null, new JSExpression[0], methods, "util"); assertTrue(result.contains("property: 'value'")); }