use of com.intellij.psi.PsiElement in project go-lang-idea-plugin by go-lang-plugin-org.
the class GoAssignmentNilWithoutExplicitTypeInspection method buildGoVisitor.
@NotNull
@Override
protected GoVisitor buildGoVisitor(@NotNull ProblemsHolder holder, @NotNull LocalInspectionToolSession session) {
return new GoVisitor() {
@Override
public void visitVarDeclaration(@NotNull GoVarDeclaration o) {
for (GoVarSpec spec : o.getVarSpecList()) {
checkVar(spec);
}
}
@Override
public void visitShortVarDeclaration(@NotNull GoShortVarDeclaration o) {
checkVar(o);
}
@Override
public void visitConstDeclaration(@NotNull GoConstDeclaration o) {
for (GoConstSpec spec : o.getConstSpecList()) {
checkConst(spec);
}
}
private void checkVar(@NotNull GoVarSpec spec) {
if (spec.getType() != null)
return;
checkExpressions(spec.getRightExpressionsList());
}
private void checkConst(@NotNull GoConstSpec spec) {
if (spec.getType() != null)
return;
checkExpressions(spec.getExpressionList());
}
private void checkExpressions(@NotNull List<GoExpression> expressions) {
for (GoExpression expr : expressions) {
if (expr instanceof GoReferenceExpressionImpl) {
GoReferenceExpressionImpl ref = (GoReferenceExpressionImpl) expr;
PsiElement resolve = ref.resolve();
if (ref.getIdentifier().textMatches(GoConstants.NIL) && resolve != null && GoPsiImplUtil.builtin(resolve)) {
holder.registerProblem(expr, "Cannot assign nil without explicit type", GENERIC_ERROR_OR_WARNING);
}
}
}
}
};
}
use of com.intellij.psi.PsiElement in project go-lang-idea-plugin by go-lang-plugin-org.
the class GoAssignmentToReceiverInspection method buildGoVisitor.
@NotNull
@Override
protected GoVisitor buildGoVisitor(@NotNull ProblemsHolder holder, @NotNull LocalInspectionToolSession session) {
return new GoVisitor() {
@Override
public void visitReferenceExpression(@NotNull GoReferenceExpression o) {
super.visitReferenceExpression(o);
if (o.getReadWriteAccess() == ReadWriteAccessDetector.Access.Write) {
PsiElement resolve = o.resolve();
if (resolve instanceof GoReceiver) {
String message = "Assignment to method receiver doesn't propagate to other calls";
if (((GoReceiver) resolve).getType() instanceof GoPointerType) {
if (o.getParent() instanceof GoUnaryExpr) {
GoUnaryExpr p = (GoUnaryExpr) o.getParent();
if (p.getMul() != null) {
// pointer dereference
return;
}
}
message = "Assignment to method receiver propagates only to callees but not to callers";
}
holder.registerProblem(o, message, WEAK_WARNING);
}
}
}
};
}
use of com.intellij.psi.PsiElement in project go-lang-idea-plugin by go-lang-plugin-org.
the class GoBoolExpressionsInspection method buildGoVisitor.
@NotNull
@Override
protected GoVisitor buildGoVisitor(@NotNull ProblemsHolder holder, @NotNull LocalInspectionToolSession session) {
return new GoVisitor() {
@Override
public void visitAndExpr(@NotNull GoAndExpr o) {
visitExpr(o, true);
}
@Override
public void visitOrExpr(@NotNull GoOrExpr o) {
visitExpr(o, false);
}
private void visitExpr(GoBinaryExpr o, boolean and) {
if (!isTopmostOperationOfType(o, and))
return;
List<GoExpression> elements = collect(o, and);
for (int i = 0; i < elements.size(); i++) {
GoExpression l = elements.get(i);
if (l instanceof GoReferenceExpression && (l.textMatches("true") || l.textMatches("false")) && GoPsiImplUtil.builtin(((GoReferenceExpression) l).resolve())) {
registerProblem(o, holder);
return;
}
for (int j = i + 1; j < elements.size(); j++) {
ProgressManager.checkCanceled();
GoExpression r = elements.get(j);
if (isEqualsWithNot(l, r) || isEqualsWithNot(r, l) || GoExpressionUtil.identical(l, r)) {
registerProblem(o, holder);
return;
}
// todo expr evaluating! x != c1 || x != c2 (c1, c2 const, c1 != c2)
}
}
}
private boolean isTopmostOperationOfType(GoBinaryExpr o, boolean isAndType) {
PsiElement parent = PsiTreeUtil.skipParentsOfType(o, GoParenthesesExpr.class);
return !(parent instanceof GoBinaryExpr) || !isSameOp((GoExpression) parent, isAndType);
}
};
}
use of com.intellij.psi.PsiElement in project go-lang-idea-plugin by go-lang-plugin-org.
the class GoDuplicateFunctionOrMethodInspection method buildGoVisitor.
@NotNull
@Override
protected GoVisitor buildGoVisitor(@NotNull ProblemsHolder holder, @NotNull LocalInspectionToolSession session) {
return new GoVisitor() {
@Override
public void visitMethodDeclaration(@NotNull GoMethodDeclaration method) {
if (method.isBlank())
return;
String methodName = method.getName();
if (methodName == null)
return;
String typeText = GoMethodDeclarationStubElementType.calcTypeText(method);
if (typeText == null)
return;
GoFile file = method.getContainingFile();
GlobalSearchScope scope = GoPackageUtil.packageScope(file);
IdFilter idFilter = GoIdFilter.getFilesFilter(scope);
Module module = ModuleUtilCore.findModuleForPsiElement(file);
String key = file.getPackageName() + "." + typeText;
GoMethodIndex.process(key, file.getProject(), scope, idFilter, declaration -> {
ProgressManager.checkCanceled();
if (!method.isEquivalentTo(declaration)) {
if (Comparing.equal(declaration.getName(), methodName) && GoPsiImplUtil.allowed(declaration.getContainingFile(), file, module)) {
PsiElement identifier = method.getNameIdentifier();
holder.registerProblem(identifier == null ? method : identifier, "Duplicate method name");
return false;
}
}
return true;
});
}
@Override
public void visitFunctionDeclaration(@NotNull GoFunctionDeclaration func) {
if (func.isBlank())
return;
String funcName = func.getName();
if (funcName == null)
return;
if (INIT.equals(funcName) && zeroArity(func))
return;
GoFile file = func.getContainingFile();
boolean isMainFunction = MAIN.equals(funcName) && MAIN.equals(file.getPackageName()) && zeroArity(func);
Module module = ModuleUtilCore.findModuleForPsiElement(file);
GlobalSearchScope scope = GoPackageUtil.packageScope(file);
IdFilter idFilter = GoIdFilter.getFilesFilter(scope);
GoFunctionIndex.process(funcName, file.getProject(), scope, idFilter, declaration -> {
ProgressManager.checkCanceled();
if (!func.isEquivalentTo(declaration) && GoPsiImplUtil.allowed(declaration.getContainingFile(), file, module)) {
if (!isMainFunction || Comparing.equal(declaration.getContainingFile(), file)) {
PsiElement identifier = func.getNameIdentifier();
holder.registerProblem(identifier == null ? func : identifier, "Duplicate function name");
return false;
}
}
return true;
});
}
};
}
use of com.intellij.psi.PsiElement in project go-lang-idea-plugin by go-lang-plugin-org.
the class GoFunctionCallInspection method buildGoVisitor.
@NotNull
@Override
protected GoVisitor buildGoVisitor(@NotNull ProblemsHolder holder, @NotNull LocalInspectionToolSession session) {
return new GoVisitor() {
@Override
public void visitCallExpr(@NotNull GoCallExpr o) {
super.visitCallExpr(o);
PsiElement resolve = GoPsiImplUtil.resolveCallRaw(o);
GoExpression expression = o.getExpression();
if (resolve != null && expression instanceof GoReferenceExpression) {
List<GoExpression> list = o.getArgumentList().getExpressionList();
int actualSize = list.size();
if (resolve instanceof GoTypeSpec && actualSize != 1) {
String message = String.format("%sto conversion to %s: %s.", actualSize == 0 ? "Missing argument " : "Too many arguments ", expression.getText(), o.getText());
holder.registerProblem(o, message);
} else if (resolve instanceof GoSignatureOwner) {
GoSignature signature = ((GoSignatureOwner) resolve).getSignature();
if (signature == null)
return;
int expectedSize = 0;
GoParameters parameters = signature.getParameters();
for (GoParameterDeclaration declaration : parameters.getParameterDeclarationList()) {
if (declaration.isVariadic() && actualSize >= expectedSize)
return;
int size = declaration.getParamDefinitionList().size();
expectedSize += size == 0 ? 1 : size;
}
if (actualSize == 1) {
GoExpression first = ContainerUtil.getFirstItem(list);
GoSignatureOwner firstResolve = GoPsiImplUtil.resolveCall(first);
if (firstResolve != null) {
actualSize = GoInspectionUtil.getFunctionResultCount(firstResolve);
}
}
GoReferenceExpression qualifier = ((GoReferenceExpression) expression).getQualifier();
boolean isMethodExpr = qualifier != null && qualifier.resolve() instanceof GoTypeSpec;
// todo: a temp workaround for method specs
if (isMethodExpr)
actualSize -= 1;
if (actualSize == expectedSize)
return;
String tail = " arguments in call to " + expression.getText();
holder.registerProblem(o.getArgumentList(), (actualSize > expectedSize ? "too many" : "not enough") + tail);
}
}
}
};
}
Aggregations