package org.elixir_lang.inspection;
import com.intellij.codeInspection.*;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiRecursiveElementWalkingVisitor;
import org.elixir_lang.local_quick_fix.ConvertKeywordPairToTypeOperation;
import org.elixir_lang.psi.*;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import static org.elixir_lang.psi.impl.ElixirPsiImplUtil.identifierName;
import static org.elixir_lang.reference.ModuleAttribute.isTypeName;
public class KeywordPairColonInsteadOfTypeOperator extends LocalInspectionTool {
/*
* Instance Methods
*/
@NotNull
@Override
public ProblemDescriptor[] checkFile(@NotNull PsiFile file,
@NotNull InspectionManager manager,
boolean isOnTheFly) {
final ProblemsHolder problemsHolder = new ProblemsHolder(manager, file, isOnTheFly);
file.accept(
new PsiRecursiveElementWalkingVisitor() {
@Override
public void visitElement(@NotNull final PsiElement element) {
// See org.elixir_lang.annotator.ModuleAttribute.annotate for path of checks
if (element instanceof AtUnqualifiedNoParenthesesCall) {
visitAtUnqualifiedNoParenthesesCall((AtUnqualifiedNoParenthesesCall) element);
}
super.visitElement(element);
}
private void visitAtUnqualifiedNoParenthesesCall(
@NotNull final AtUnqualifiedNoParenthesesCall atUnqualifiedNoParenthesesCall
) {
ElixirAtIdentifier atIdentifier = atUnqualifiedNoParenthesesCall.getAtIdentifier();
String identifier = identifierName(atIdentifier);
if (isTypeName(identifier)) {
PsiElement child = atUnqualifiedNoParenthesesCall.getNoParenthesesOneArgument();
PsiElement[] grandChildren = child.getChildren();
if (grandChildren.length == 1) {
PsiElement grandChild = grandChildren[0];
if (grandChild instanceof QuotableKeywordList) {
QuotableKeywordList quotableKeywordList = (QuotableKeywordList) grandChild;
List<QuotableKeywordPair> quotableKeywordPairList =
quotableKeywordList.quotableKeywordPairList();
if (quotableKeywordPairList.size() == 1) {
QuotableKeywordPair quotableKeywordPair = quotableKeywordPairList.get(0);
Quotable keywordKey = quotableKeywordPair.getKeywordKey();
PsiElement keywordPairColon = keywordKey.getNextSibling();
LocalQuickFix localQuickFix = new ConvertKeywordPairToTypeOperation(
/* Can't be KEYWORD_PAIR_COLON because caret is never on the single
character in editor mode, only to left or right */
keywordPairColon
);
problemsHolder.registerProblem(
keywordPairColon,
"Type specifications separate the name from the definition using `::`, not `:`",
ProblemHighlightType.ERROR,
localQuickFix
);
}
}
}
}
}
}
);
return problemsHolder.getResultsArray();
}
@Nls
@NotNull
@Override
public String getDisplayName() {
return "Keyword pair colon (:) used in type spec instead of type operator (::)";
}
@Nls
@NotNull
@Override
public String getGroupDisplayName() {
return "Elixir";
}
@NotNull
@Override
public String getShortName() {
return "KeywordPairColonInsteadOfTypeOperator";
}
@Override
public boolean isEnabledByDefault() {
return true;
}
}