@Override @RequiredReadAction public boolean isReferenceTo(PsiElement element) { final PsiElement element2 = resolve(); boolean proxyExpanded = false; if(element instanceof JSDefinitionExpression) { final JSExpression expression = ((JSDefinitionExpression) element).getExpression(); if(expression instanceof JSReferenceExpression) { return ((JSReferenceExpression) expression).isReferenceTo(element2); } } if(element != element2 && element instanceof JSProperty && element2 instanceof JSProperty) { return ((JSProperty) element).getName().equals(((JSProperty) element2).getName()); } return proxyExpanded && element == element2; }
@Override protected JSElementVisitor createVisitor(final ProblemsHolder holder) { return new JSElementVisitor() { @Override public void visitJSReferenceExpression(final JSReferenceExpression node) { for(ResolveResult r : node.multiResolve(false)) { final PsiElement element = r.getElement(); if((element instanceof JSDefinitionExpression && element.getParent() instanceof JSAssignmentExpression) || element == node.getParent()) { continue; } if(JSDocumentationUtils.isDeprecated(element)) { holder.registerProblem(node.getReferenceNameElement(), JavaScriptBundle.message("javascript.deprecated.symbol.used.name.message"), ProblemHighlightType.LIKE_DEPRECATED); break; } } } }; }
public Collection<JSDefinitionExpression> getDefinitions() { final PsiElement firstChild = getFirstChild(); if (firstChild instanceof JSDefinitionExpression) { return Collections.singletonList((JSDefinitionExpression) firstChild); } if (firstChild instanceof JSParenthesizedExpression) { final PsiElement commaExpression = PsiTreeUtil.findChildOfType(firstChild, JSCommaExpression.class); if (commaExpression != null) { return PsiTreeUtil.findChildrenOfType(commaExpression, JSDefinitionExpression.class); } } return Collections.emptyList(); }
public Collection<JSDefinitionExpression> getDefinitions() { final PsiElement firstChild = getFirstChild(); if (firstChild instanceof JSDefinitionExpression) { return Collections.singletonList((JSDefinitionExpression)firstChild); } else if (firstChild instanceof JSParenthesizedExpression) { final PsiElement commaExpression = PsiTreeUtil.findChildOfType(firstChild, JSCommaExpression.class); if (commaExpression != null) { return PsiTreeUtil.findChildrenOfType(commaExpression, JSDefinitionExpression.class); } } return Collections.emptyList(); }
public static boolean isLHSExpression(JSExpression expr) { if(expr instanceof JSDefinitionExpression) { expr = ((JSDefinitionExpression) expr).getExpression(); } if(expr instanceof JSReferenceExpression) { return true; } if(expr instanceof JSParenthesizedExpression) { return isLHSExpression(((JSParenthesizedExpression) expr).getInnerExpression()); } if(expr instanceof JSIndexedPropertyAccessExpression) { return true; } if(expr instanceof JSCallExpression) { return true; } if(expr instanceof JSNewExpression) { return true; } return false; }
@Override public int getTextEndOffset(@NotNull PsiElement element) { if(element instanceof JSDefinitionExpression) { element = PsiTreeUtil.getParentOfType(element, JSExpressionStatement.class); } return element.getTextRange().getEndOffset(); }
@Override public boolean isReadWriteAccessible(PsiElement element) { return element instanceof JSVariable || ((element instanceof JSFunction) && (((JSFunction) element).isGetProperty() || ((JSFunction) element).isSetProperty())) || element instanceof JSDefinitionExpression; }
@Override public Access getExpressionAccess(PsiElement expression) { expression = expression.getParent(); if(expression instanceof JSDefinitionExpression) { PsiElement grandParent = expression.getParent(); if(grandParent instanceof JSAssignmentExpression && ((JSAssignmentExpression) grandParent).getOperationSign() == JSTokenTypes.EQ) { return Access.Write; } return Access.ReadWrite; } if(expression instanceof JSPrefixExpression) { if(isIncrementOrDecrement(((JSPrefixExpression) expression).getOperationSign())) { return Access.ReadWrite; } } else if(expression instanceof JSPostfixExpression) { if(isIncrementOrDecrement(((JSPostfixExpression) expression).getOperationSign())) { return Access.ReadWrite; } } return Access.Read; }
@Override public boolean isSafeDeleteAvailable(PsiElement element) { boolean simpleElement = element instanceof JSFunction || element instanceof JSVariable || element instanceof JSDefinitionExpression || element instanceof JSProperty || element instanceof JSClass; return simpleElement && ((JSNamedElement) element).getName() != null; }
@Override public void visitJSAssignmentExpression(@NotNull JSAssignmentExpression assignment) { super.visitJSAssignmentExpression(assignment); final IElementType sign = assignment.getOperationSign(); if (!JSTokenTypes.EQ.equals(sign)) { return; } JSExpression lhs = assignment.getLOperand(); final JSExpression rhs = assignment.getROperand(); if (rhs == null || lhs == null) { return; } if (!(rhs instanceof JSBinaryExpression)) { return; } final JSBinaryExpression binaryRhs = (JSBinaryExpression) rhs; if (!(binaryRhs.getROperand() != null)) { return; } IElementType operationSign = binaryRhs.getOperationSign(); if (operationSign == JSTokenTypes.ANDAND || operationSign == JSTokenTypes.OROR) { return; } final JSExpression lOperand = binaryRhs.getLOperand(); if (SideEffectChecker.mayHaveSideEffects(lhs)) { return; } if(lhs instanceof JSDefinitionExpression) { lhs = ((JSDefinitionExpression)lhs).getExpression(); } if (!EquivalenceChecker.expressionsAreEquivalent(lhs, lOperand)) { return; } registerError(assignment); }
@Nullable public JSDefinitionExpression getDefinition() { return PsiTreeUtil.getChildOfType(this, JSDefinitionExpression.class); }
public MockJSAssignmentExpression(JSDefinitionExpression definition, String content) { super(mock(ASTNode.class)); this.definition = definition; this.content = content; }
@Override @NotNull public String getType(@NotNull PsiElement element) { if(element instanceof JSFunction) { return JavaScriptBundle.message("javascript.language.term.function"); } if(element instanceof JSClass) { return JavaScriptBundle.message("javascript.language.term.class"); } if(element instanceof JSNamespaceDeclaration) { return JavaScriptBundle.message("javascript.language.term.namespace"); } if(element instanceof JSParameter) { return JavaScriptBundle.message("javascript.language.term.parameter"); } if(element instanceof JSProperty) { return JavaScriptBundle.message("javascript.language.term.property"); } if(element instanceof JSVariable) { return JavaScriptBundle.message("javascript.language.term.variable"); } if(element instanceof JSLabeledStatement) { return JavaScriptBundle.message("javascript.language.term.label"); } if(element instanceof JSDefinitionExpression) { return JavaScriptBundle.message("javascript.language.term.value"); } if(element instanceof XmlTag) { return JavaScriptBundle.message("javascript.language.term.tag"); } if(element instanceof XmlToken) { return JavaScriptBundle.message("javascript.language.term.attribute.value"); } if(element instanceof JSPackageStatement) { return JavaScriptBundle.message("javascript.language.term.package"); } return ""; }
@Override public void visitJSAssignmentExpression(@NotNull JSAssignmentExpression assignment) { super.visitJSAssignmentExpression(assignment); final IElementType sign = assignment.getOperationSign(); if (!JSTokenTypes.EQ.equals(sign)) { return; } JSExpression lhs = assignment.getLOperand(); if(lhs instanceof JSDefinitionExpression) { lhs = ((JSDefinitionExpression)lhs).getExpression(); } final JSExpression rhs = assignment.getROperand(); if(rhs == null || lhs == null) { return; } if(!(rhs instanceof JSReferenceExpression) || !(lhs instanceof JSReferenceExpression) ) { return; } final JSReferenceExpression rhsReference = (JSReferenceExpression) rhs; final JSReferenceExpression lhsReference = (JSReferenceExpression) lhs; final JSExpression rhsQualifier = rhsReference.getQualifier(); final JSExpression lhsQualifier = lhsReference.getQualifier(); if(rhsQualifier !=null || lhsQualifier !=null) { if(!EquivalenceChecker.expressionsAreEquivalent(rhsQualifier, lhsQualifier)) { return; } } final String rhsName = rhsReference.getReferencedName(); final String lhsName = lhsReference.getReferencedName(); if(rhsName == null || lhsName == null) { return; } if(!rhsName.equals(lhsName)) { return; } final PsiElement rhsReferent = rhsReference.resolve(); final PsiElement lhsReferent = lhsReference.resolve(); if(rhsReferent != null && lhsReferent != null && !rhsReferent.equals(lhsReferent)) { return; } if (lhsName.equals("location") && lhsQualifier != null && lhsQualifier.getText().equals("document")) { // document.location = document.location causes browser refresh return; } registerError(assignment); }
@Override public boolean satisfiedBy(@NotNull PsiElement element) { if (!(element instanceof JSAssignmentExpression)) { return false; } if (ErrorUtil.containsError(element)) { return false; } final JSAssignmentExpression assignment = (JSAssignmentExpression) element; final IElementType tokenType = assignment.getOperationSign(); if (!JSTokenTypes.EQ.equals(tokenType)) { return false; } JSExpression lhs = assignment.getLOperand(); final JSExpression rhs = assignment.getROperand(); if (lhs instanceof JSDefinitionExpression) { lhs = ((JSDefinitionExpression) lhs).getExpression(); } if (lhs == null || rhs == null) { return false; } if (!(rhs instanceof JSBinaryExpression)) { return false; } final JSBinaryExpression binaryRhs = (JSBinaryExpression) rhs; final JSExpression rhsRhs = binaryRhs.getROperand(); final JSExpression rhsLhs = binaryRhs.getLOperand(); if (rhsRhs == null) { return false; } final IElementType rhsTokenType = binaryRhs.getOperationSign(); if (JSTokenTypes.OROR .equals(rhsTokenType) || JSTokenTypes.ANDAND.equals(rhsTokenType)) { return false; } if (SideEffectChecker.mayHaveSideEffects(lhs)) { return false; } return EquivalenceChecker.expressionsAreEquivalent(lhs, rhsLhs); }