@Override public PsiElement getValueDeclaration(XmlElement xmlElement, String value) { CatberryProjectConfigurationManager configurationManager = CatberryProjectConfigurationManager.getInstance(project); PsiDirectory directory = configurationManager.getStoresDirectory(); if(directory == null) return super.getValueDeclaration(xmlElement, value); final String requiredPath = directory.getVirtualFile().getPath() + "/" + value+".js"; int index = value.lastIndexOf('/'); String className = index == -1 ? value : value.substring(index+1); Collection<JSElement> elements = StubIndex.getElements(JSClassIndex.KEY, className, project, GlobalSearchScope.allScope(project), JSElement.class); for(JSElement element : elements) { if (element instanceof JSClass && element.getContainingFile().getVirtualFile().getPath().equals(requiredPath)) return element; } return super.getValueDeclaration(xmlElement, value); }
@Override public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { // final PsiFile file = element.getContainingFile(); if (!FileModificationService.getInstance().prepareFileForWrite(file)) return; // InspectionManager inspectionManager = InspectionManager.getInstance(project); // ProblemDescriptor descriptor = inspectionManager.createProblemDescriptor(element, element, "", ProblemHighlightType.GENERIC_ERROR_OR_WARNING, false); final JSElement property = PsiTreeUtil.getParentOfType(element, JSElement.class); LOG.assertTrue(property != null); final int start = property.getTextRange().getStartOffset(); @NonNls final Document doc = PsiDocumentManager.getInstance(project).getDocument(file); LOG.assertTrue(doc != null); final int line = doc.getLineNumber(start); final int lineStart = doc.getLineStartOffset(line); doc.insertString(lineStart, "/*eslint " + rule + ":0*/\n"); DaemonCodeAnalyzer.getInstance(project).restart(file); }
@Override public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { // final PsiFile file = element.getContainingFile(); if (!FileModificationService.getInstance().prepareFileForWrite(file)) return; // InspectionManager inspectionManager = InspectionManager.getInstance(project); // ProblemDescriptor descriptor = inspectionManager.createProblemDescriptor(element, element, "", ProblemHighlightType.GENERIC_ERROR_OR_WARNING, false); final JSElement property = PsiTreeUtil.getParentOfType(element, JSElement.class); LOG.assertTrue(property != null); final int start = property.getTextRange().getStartOffset(); @NonNls final Document doc = PsiDocumentManager.getInstance(project).getDocument(file); LOG.assertTrue(doc != null); final int line = doc.getLineNumber(start); final int lineEnd = doc.getLineEndOffset(line); doc.insertString(lineEnd, " //eslint-disable-line " + rule); DaemonCodeAnalyzer.getInstance(project).restart(file); }
public void invoke(@NotNull final Project project, final Editor editor, @NotNull final PsiElement element) throws IncorrectOperationException { final PsiFile file = element.getContainingFile(); if (!FileModificationService.getInstance().prepareFileForWrite(file)) return; // InspectionManager inspectionManager = InspectionManager.getInstance(project); // ProblemDescriptor descriptor = inspectionManager.createProblemDescriptor(element, element, "", ProblemHighlightType.GENERIC_ERROR_OR_WARNING, false); final JSElement property = PsiTreeUtil.getParentOfType(element, JSElement.class); LOG.assertTrue(property != null); final int start = property.getTextRange().getStartOffset(); @NonNls final Document doc = PsiDocumentManager.getInstance(project).getDocument(file); LOG.assertTrue(doc != null); final int line = doc.getLineNumber(start); final int lineEnd = doc.getLineEndOffset(line); doc.insertString(lineEnd, " //eslint-disable-line " + rule); }
private void moveElementToEnd(PsiElement define, PsiElement parameter, PsiElement lastDefine, PsiElement lastParameter, DefineStatement defineStatement) { if(lastDefine.equals(define)) { return; } PsiElement ignoreComment = AMDPsiUtil.getIgnoreCommentAfterLiteral(define); PsiElement newElement = moveImportToEnd(defineStatement.getArguments(), defineStatement.getFunction().getParameterList(), define.getText(), parameter.getText(), lastDefine, lastParameter); if(ignoreComment != null) { defineStatement.getArguments().addAfter(ignoreComment, newElement); } AMDPsiUtil.removeSingleImport(new AMDImport((JSElement) define, (JSElement)parameter)); }
@Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor problemDescriptor) { CommandProcessor.getInstance().executeCommand(project, new Runnable() { @Override public void run() { ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { AMDPsiUtil.removeSingleImport(new AMDImport((JSElement)define, (JSElement) parameter)); } }); } }, "Remove unused import", "Remove unused import"); }
/** * Entry point for this class. Locates the AMD import define literal and parameter that the user has selected * * @param elementAtCaretPosition * @param file * @return null if either the define literal or the parameter is null */ public @Nullable AMDImport findNearestImport(PsiElement elementAtCaretPosition, PsiFile file) { DefineResolver resolver = new DefineResolver(); DefineStatement defineStatement = null; defineStatement = resolver.getNearestImportBlock(elementAtCaretPosition); if(defineStatement == null) { defineStatement = new DefineResolver().getDefineStatementItems(file); } JSElement defineLiteral = getDefineLiteral(elementAtCaretPosition, defineStatement); JSElement parameter = getParameter(elementAtCaretPosition, defineStatement); if(defineLiteral == null || parameter == null) { return null; } return new AMDImport(defineLiteral, parameter); }
@Test /** * covers the case: (underscore = cursor) * * define(['a/b/a_', 'a/b/b', 'a/b/c'], function(a, b, c){}); * */ public void testCursorInsideLiteral() { MockJSElement caretElement = new MockJSElement("a/b/a"); caretElement.setParent(new MockJSLiteralExpression("a/b/a")); JSElement defineLiteral = locator.getDefineLiteral(caretElement, defineStatement); assertNotNull(defineLiteral); assertEquals("a/b/a", defineLiteral.getText()); }
@Test /** * covers the case: (underscore = cursor) * * define(['a/b/a'_, 'a/b/b', 'a/b/c'], function(a, b, c){}); * */ public void testCursorBeforeComma() { MockJSElement caretElement = BasicPsiElements.comma(); caretElement.setPrevSibling(new MockJSLiteralExpression("a/b/a")); JSElement defineLiteral = locator.getDefineLiteral(caretElement, defineStatement); assertNotNull(defineLiteral); assertEquals("a/b/a", defineLiteral.getText()); }
@Test /** * covers the case: (underscore = cursor) * * define(['a/b/a', 'a/b/b', 'a/b/c'], function(a_, b, c){}); * */ public void testCursorBeforeCommaForParameter() { MockJSElement caretElement = BasicPsiElements.comma(); caretElement.setPrevSibling(new MockJSParameter("a")); JSElement parameter = locator.getParameter(caretElement, defineStatement); assertNotNull(parameter); assertEquals("a", parameter.getText()); }
@Test /** * covers the case: (underscore = cursor) * * define(['a/b/a', 'a/b/b', 'a/b/c'], function(_a, b, c){}); * */ public void testCursorBeforeParameter() { MockJSElement caretElement = new MockJSElement("a"); caretElement.setParent(new MockJSParameter("a")); JSElement parameter = locator.getParameter(caretElement, defineStatement); assertNotNull(parameter); assertEquals("a", parameter.getText()); }
@Test /** * covers the case: (underscore = cursor) * * define(['a/b/a', 'a/b/b', 'a/b/c'], function(_a, b, c){}); * */ public void testDefineLiteralIsRetrievedWhenCursorIsOverParameter() { MockJSElement caretElement = new MockJSElement("a"); caretElement.setParent(new MockJSParameter("a")); JSElement defineLiteral = locator.getDefineLiteral(caretElement, defineStatement); assertNotNull(defineLiteral); assertEquals("a/b/a", defineLiteral.getText()); }
@Test /** * covers the case: (underscore = cursor) * * define(['a/b/a_', 'a/b/b', 'a/b/c'], function(a, b, c){}); * */ public void testParameterIsRetrievedWhenCursorIsOverDefineLiteral() { MockJSElement caretElement = BasicPsiElements.comma(); caretElement.setPrevSibling(new MockJSLiteralExpression("a/b/a")); JSElement parameter = locator.getParameter(caretElement, defineStatement); assertNotNull(parameter); assertEquals("a", parameter.getText()); }
public static boolean isCaughtLocally(@NotNull JSThrowStatement throwStatement) { JSElement currentElement = throwStatement; while (true) { final JSTryStatement tryStatement = PsiTreeUtil.getParentOfType(currentElement, JSTryStatement.class); if (tryStatement == null) { return false; } if (tryStatement.getCatchBlock() != null) { final JSStatement tryBlock = tryStatement.getStatement(); if (tryBlock != null) { if (PsiTreeUtil.isAncestor(tryBlock, currentElement, true)) { return true; } } } currentElement = tryStatement; } }
public static JSStatement replaceElementWithStatement(@NotNull JSElement element, @NonNls @NotNull String statementText) throws IncorrectOperationException { final ASTNode newStatementNode = JSChangeUtil.createStatementFromText( element.getProject(), statementText); final ASTNode oldStatementParentNode = element.getNode(); final PsiElement parentNode = element.getParent(); final ASTNode newStatementParentNode = parentNode.getNode(); if (newStatementParentNode == null || oldStatementParentNode == null || newStatementNode == null) { return null; } newStatementParentNode.replaceChild(oldStatementParentNode, newStatementNode); reformat(parentNode); return (JSStatement) newStatementNode.getPsi(); }
private static Iterable<PsiElement> getReferences(@NotNull final JSVariable variable, @Nullable final PsiElement scope, final int minTextOffset, final int maxTextOffset) { final PsiElement iteratedScope; if (scope == null) { JSElement function = PsiTreeUtil.getParentOfType(variable, JSFunction.class); iteratedScope = ((function == null) ? FindReferenceUtil.getFarthestAncestor(variable, XmlFile.class) : function); } else { iteratedScope = scope; } return new Iterable<PsiElement>() { @Override public Iterator<PsiElement> iterator() { return new JSReferenceIterator(variable, minTextOffset, maxTextOffset, iteratedScope); } }; }
public static void replaceSimplifiableImplicitAssignment(JSIfStatement statement, boolean negated) throws IncorrectOperationException { final JSElement prevStatement = (JSElement) JSElementFactory.getNonWhiteSpaceSibling(statement, false); final JSExpression condition = statement.getCondition(); final String conditionText = (negated ? BoolUtils.getNegatedExpressionText(condition) : condition.getText()); final JSExpressionStatement assignmentStatement = (JSExpressionStatement) ConditionalUtils.stripBraces(statement.getThen()); final JSAssignmentExpression assignmentExpression = (JSAssignmentExpression) assignmentStatement.getExpression(); final IElementType operator = assignmentExpression.getOperationSign(); final String operand = BinaryOperatorUtils.getOperatorText(operator); final JSExpression lhs = assignmentExpression.getLOperand(); final String lhsText = lhs.getText(); JSElementFactory.replaceStatement(statement, lhsText + operand + conditionText + ';'); assert (prevStatement != null); JSElementFactory.removeElement(prevStatement); }
@Override protected String getTextForElement(PsiElement element) { final JSElement parent = (JSElement) element.getParent(); final String keyword; assert (parent != null); if (parent instanceof JSIfStatement) { final JSIfStatement ifStatement = (JSIfStatement) parent; final JSStatement elseBranch = ifStatement.getElse(); keyword = (element.equals(elseBranch) ? ELSE_KEYWORD : IF_KEYWORD); } else { final PsiElement keywordChild = parent.getFirstChild(); assert (keywordChild != null); keyword = keywordChild.getText(); } return this.getText(keyword); }
private void replaceMultiplyOrDivideWithShift(JSBinaryExpression exp) throws IncorrectOperationException { JSExpression lhs = exp.getLOperand(); JSExpression rhs = exp.getROperand(); final IElementType tokenType = exp.getOperationSign(); final String operatorString = (tokenType.equals(JSTokenTypes.MULT) ? "<<" : ">>"); if (ShiftUtils.isPowerOfTwo(lhs) && tokenType.equals(JSTokenTypes.MULT)) { JSExpression swap = lhs; lhs = rhs; rhs = swap; } final String lhsText = ParenthesesUtils.getParenthesized(lhs, ParenthesesUtils.SHIFT_PRECENDENCE); String expString = lhsText + operatorString + ShiftUtils.getLogBase2(rhs); final JSElement parent = (JSElement) exp.getParent(); if (parent != null && parent instanceof JSExpression) { if (!(parent instanceof JSParenthesizedExpression) && ParenthesesUtils.getPrecendence((JSExpression) parent) < ParenthesesUtils.SHIFT_PRECENDENCE) { expString = '(' + expString + ')'; } } JSElementFactory.replaceExpression(exp, expString); }
private void replaceShiftWithMultiplyOrDivide(JSBinaryExpression exp) throws IncorrectOperationException { final JSExpression lhs = exp.getLOperand(); final JSExpression rhs = exp.getROperand(); final IElementType tokenType = exp.getOperationSign(); final String operatorString = ((tokenType.equals(JSTokenTypes.LTLT)) ? "*" : "/"); final String lhsText = ParenthesesUtils.getParenthesized(lhs, ParenthesesUtils.MULTIPLICATIVE_PRECENDENCE); String expString = lhsText + operatorString + ShiftUtils.getExpBase2(rhs); final JSElement parent = (JSElement) exp.getParent(); if (parent != null && parent instanceof JSExpression) { if (!(parent instanceof JSParenthesizedExpression) && ParenthesesUtils.getPrecendence((JSExpression) parent) < ParenthesesUtils.MULTIPLICATIVE_PRECENDENCE) { expString = '(' + expString + ')'; } } JSElementFactory.replaceExpression(exp, expString); }
public JSElementIterator(PsiElement element, boolean reverse, int minTextOffset, int maxTextOffset) { this.reverse = reverse; this.minTextOffset = minTextOffset; this.maxTextOffset = maxTextOffset; this.retrieveNext = true; this.elementStack = new ArrayStack<PsiElement>(); if (element instanceof XmlFile) { for (JSElement embeddedElement : JSFunctionVisitor.getEmbeddedJSElements((XmlFile) element)) { if (reverse) { this.elementStack.add(0, embeddedElement); } else { this.elementStack.add(embeddedElement); } } } else if (element instanceof JSElement) { this.elementStack.push(element); } else { throw new ClassCastException(element.getClass().getName()); } }
@Override protected void moveAction(AnActionEvent e, PsiElement define, PsiElement parameter, List<PsiElement> defines, List<PsiElement> parameters, DefineStatement defineStatement) { String parameterText = parameter.getText(); AMDPsiUtil.removeSingleImport(new AMDImport((JSElement) define, (JSElement) parameter)); // define is already quoted, so passing an empty quote character new ImportCreator().createImport(define.getText(), "", parameterText, defineStatement.getArguments(), defineStatement.getFunction().getParameterList()); Editor editor = e.getData(PlatformDataKeys.EDITOR); int index = defineStatement.getArguments().getFirstChild().getTextOffset(); editor.getScrollingModel().scrollVertically(index); }
protected @Nullable JSElement getDefineLiteral(PsiElement elementAtCaretPosition, DefineStatement defineStatement) { iterations += 1; if(elementAtCaretPosition == null || iterations > 10) { return null; } if(elementAtCaretPosition.getParent() instanceof JSLiteralExpression) { return (JSElement) elementAtCaretPosition.getParent(); } if(elementAtCaretPosition.getPrevSibling() instanceof JSLiteralExpression) { return (JSElement) elementAtCaretPosition.getPrevSibling(); } // I know I know ... but this accounts for the case where the cursor is right after the comma so it's a special case if(elementAtCaretPosition.getPrevSibling() != null && elementAtCaretPosition.getPrevSibling().getPrevSibling() instanceof JSLiteralExpression) { return (JSElement) elementAtCaretPosition.getPrevSibling().getPrevSibling(); } // if none of the above cases work, we assume this is a parameter and find its corresponding literal JSElement parameter = getParameter(elementAtCaretPosition, defineStatement); if(parameter == null) { return null; } int parameterIndex = getIndexOfParameter(defineStatement, parameter); if(parameterIndex >= defineStatement.getArguments().getExpressions().length) { return null; } return defineStatement.getArguments().getExpressions()[parameterIndex]; }
private int getIndexOfDefine(DefineStatement defineStatement, JSElement literal) { for(int i=0; i<defineStatement.getArguments().getExpressions().length;i++) { if(defineStatement.getArguments().getExpressions()[i].getText().equals(literal.getText())) { return i; } } return -1; }
private int getIndexOfParameter(DefineStatement defineStatement, JSElement parameter) { for(int i=0;i<defineStatement.getFunction().getParameters().length;i++) { if(defineStatement.getFunction().getParameters()[i].getText().equals(parameter.getText())) { return i; } } return -1; }
public JSElement isLastChildOf(MockJSElement element) { element.lastChild = this; this.parent = element; return this; }
public static JSElement elementFromText(final String text) { return new JSElementImpl(mock(ASTNode.class)) { @Override public String getText() { return text; } }; }
@Override public void visitJSReferenceExpression(@NotNull JSReferenceExpression ref) { if (used) { return; } super.visitJSReferenceExpression(ref); PsiElement element = ref.resolve(); final JSElement referent = element instanceof JSElement ? (JSElement) element:null; if (referent == null) { return; } if (referent.equals(variable)) { used = true; } }
@Override public void visitJSElement(JSElement jsElement) { int oldCount = 0; if (jsElement instanceof JSFunction) { oldCount = negationCount; } super.visitJSElement(jsElement); if (jsElement instanceof JSFunction) { negationCount = oldCount; } }
public static JSReferenceExpression[] findReferences(@NotNull JSVariable variable) { final JSReferenceVisitor visitor = new JSReferenceVisitor(variable, Integer.MAX_VALUE, 0, Integer.MAX_VALUE); JSElement scope = PsiTreeUtil.getParentOfType(variable, JSFunction.class); if (scope == null) { scope = getFarthestAncestor(variable, JSElement.class); } visitor.visitJSElement(scope); return visitor.getReferences(); }
public static void replaceSimplifiableImplicitReturn(JSIfStatement statement, boolean negated) throws IncorrectOperationException { final JSExpression condition = statement.getCondition(); final String conditionText = (negated ? BoolUtils.getNegatedExpressionText(condition) : condition.getText()); final JSElement nextStatement = (JSElement) JSElementFactory.getNonWhiteSpaceSibling(statement, true); @NonNls final String newStatement = "return " + conditionText + ';'; JSElementFactory.replaceStatement(statement, newStatement); assert (nextStatement != null); JSElementFactory.removeElement(nextStatement); }
public static boolean isAncestor(@NotNull JSElement ancestor, @NotNull JSElement element, boolean strict) { PsiElement parent = (strict ? element.getParent() : element); while (parent != null && parent instanceof JSElement) { if (parent.equals(ancestor)) { return true; } parent = parent.getParent(); } return false; }
@Override public boolean satisfiedBy(@NotNull PsiElement element) { if (!(element instanceof JSElement || element.getPrevSibling() instanceof JSElement)) { return false; } PsiElement parent = element.getParent(); if (!(parent instanceof JSBinaryExpression)) { if (element instanceof JSBinaryExpression && ((JSBinaryExpression) element).getLOperand() instanceof JSBinaryExpression) { parent = element; } else { return false; } } final JSBinaryExpression binaryExpression = (JSBinaryExpression) parent; final JSBinaryExpression subexpression = getSubexpression(binaryExpression); if (subexpression == null) { return false; } if (binaryExpression.equals(subexpression) && !isPartOfConstantExpression(binaryExpression)) { // handled by JSConstantExpressionIntention return false; } if (!ExpressionUtil.isConstantExpression(subexpression)) { return false; } return (ExpressionUtil.computeConstantExpression(subexpression) != null); }
@Override protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { final JSBlockStatement blockStatement = (JSBlockStatement) element; final JSStatement[] statements = blockStatement.getStatements(); final JSStatement statement = statements[0]; // handle comments final JSElement parent = (JSElement) blockStatement.getParent(); assert (parent != null); final JSElement grandParent = (JSElement) parent.getParent(); assert (grandParent != null); PsiElement sibling = statement.getFirstChild(); assert (sibling != null); sibling = sibling.getNextSibling(); while (sibling != null && !sibling.equals(statement)) { if (sibling instanceof PsiComment) { grandParent.addBefore(sibling, parent); } sibling = sibling.getNextSibling(); } final PsiElement lastChild = blockStatement.getLastChild(); if (lastChild instanceof PsiComment) { final JSElement nextSibling = (JSElement) parent.getNextSibling(); grandParent.addAfter(lastChild, nextSibling); } String text = statement.getText(); JSElementFactory.replaceStatement(blockStatement, text); }
private static boolean isConjunctionExpression(JSElement expression, IElementType conjunctionType) { if(!(expression instanceof JSBinaryExpression)) { return false; } final JSBinaryExpression binaryExpression = (JSBinaryExpression) expression; return binaryExpression.getOperationSign().equals(conjunctionType); }
private static boolean isConjunctionExpression(JSElement exp, IElementType conjunctionType) { if (!(exp instanceof JSBinaryExpression)) { return false; } final JSBinaryExpression binaryExpression = (JSBinaryExpression) exp; final IElementType tokenType = binaryExpression.getOperationSign(); return tokenType.equals(conjunctionType); }
@Override public void visitJSReferenceExpression(JSReferenceExpression expression) { final JSElement reference = (JSElement) expression.resolve(); if (this.variable.equals(reference)) { this.used = true; } super.visitJSReferenceExpression(expression); }
@Override public void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { assert (element instanceof JSElement); JSElement jsElement = (JSElement) element; if (MergeIfOrPredicate.isMergableExplicitIf(jsElement)) { replaceMergeableExplicitIf(jsElement); } else { replaceMergeableImplicitIf(jsElement); } }
private static void replaceMergeableExplicitIf(JSElement token) throws IncorrectOperationException { final JSIfStatement parentStatement = (JSIfStatement) (token.getParent() instanceof JSIfStatement ? token.getParent() : token); assert (parentStatement != null); final JSIfStatement childStatement = (JSIfStatement) parentStatement.getElse(); final JSExpression childCondition = childStatement.getCondition(); final JSExpression condition = parentStatement.getCondition(); final String childConditionText = ParenthesesUtils.getParenthesized(childCondition, ParenthesesUtils.OR_PRECENDENCE); final String parentConditionText = ParenthesesUtils.getParenthesized(condition, ParenthesesUtils.OR_PRECENDENCE); final JSStatement parentThenBranch = parentStatement.getThen(); final String parentThenBranchText = parentThenBranch.getText(); final StringBuilder statement = new StringBuilder(IF_STATEMENT_PREFIX) .append(parentConditionText) .append(" || ") .append(childConditionText) .append(')') .append(parentThenBranchText); final JSStatement childElseBranch = childStatement.getElse(); if (childElseBranch != null) { final String childElseBranchText = childElseBranch.getText(); statement.append(ELSE_KEYWORD) .append(childElseBranchText); } JSElementFactory.replaceStatement(parentStatement, statement.toString()); }
private static void replaceMergeableImplicitIf(JSElement token) throws IncorrectOperationException { final JSIfStatement parentStatement = (JSIfStatement) (token.getParent() instanceof JSIfStatement ? token.getParent() : token); final JSIfStatement childStatement = (JSIfStatement) JSElementFactory.getNonWhiteSpaceSibling(parentStatement, true); assert (childStatement != null); assert (parentStatement != null); final JSExpression childCondition = childStatement.getCondition(); final JSExpression condition = parentStatement.getCondition(); final String childConditionText = ParenthesesUtils.getParenthesized(childCondition, ParenthesesUtils.OR_PRECENDENCE); final String parentConditionText = ParenthesesUtils.getParenthesized(condition, ParenthesesUtils.OR_PRECENDENCE); final JSStatement parentThenBranch = parentStatement.getThen(); final JSStatement childElseBranch = childStatement.getElse(); StringBuilder statement = new StringBuilder(IF_STATEMENT_PREFIX) .append(parentConditionText) .append(" || ") .append(childConditionText) .append(')') .append(parentThenBranch.getText()); if (childElseBranch != null) { statement.append(ELSE_KEYWORD) .append(childElseBranch.getText()); } JSElementFactory.replaceStatement(parentStatement, statement.toString()); JSElementFactory.removeElement(childStatement); }