Fundamentals 11 min read

How Refactoring an IDEA YAML Inspection Plugin Boosted Code Quality

This article examines the refactoring of an IntelliJ IDEA plugin for YAML file validation, comparing the original and improved implementations across structure, naming, readability, comments, method abstraction, conditional logic, and error handling, and demonstrates how these changes enhance maintainability and robustness.

Alibaba Cloud Developer
Alibaba Cloud Developer
Alibaba Cloud Developer
How Refactoring an IDEA YAML Inspection Plugin Boosted Code Quality

Background

Develop an IntelliJ IDEA plugin to perform customized format checks on YAML files.

Verify that the specified classpath is correct.

Check whether YAML keys match the field names in the class.

Ensure values can be converted to the field types.

Code Comparison

1 Structure Design

After refactoring, an abstract class method celtVisitMapping was added to provide a unified proxy for multiple inspection modules, enabling centralized error handling, logging, and parameter tagging for easier extension.

2 Code Readability

2.1 Naming

A good name conveys purpose and usage. The original class name YamlBaseInspection was vague, while the new name CeltClassInspection clearly indicates that it handles YAML class inspections.

2.2 Functions

Original function compareNameAndValue did not reflect its purpose. It was renamed to compareKeyAndValue, making it clear that the method validates the correspondence between a key and its value.

2.3 Variables

// before
ASTNode node = mapping.getNode().findChildByType(YAMLTokenTypes.TAG);
String className = node.getText().substring(2);

// after
ASTNode node = mapping.getNode().findChildByType(YAMLTokenTypes.TAG);
String tagClassName = node.getText().substring(2);

The new variable name tagClassName immediately reveals that the value originates from the YAML tag, reducing cognitive load.

3 Comments

3.1 Comment Format

Before: missing or non‑standard comments. After: JavaDoc‑style comments added to methods, providing clear @param and @return descriptions.

// before
private boolean checkSimpleValue(PsiClass psiClass, PsiElement value)

/**
 * @param psiClass
 * @param value
 * @return true if normal; false if abnormal
 */
private boolean checkSimpleValue(PsiClass psiClass, PsiElement value, ProblemsHolder holder)

3.2 Comment Placement

// simpleValue is null or "null"
if (YamlUtil.isNull(value)) {
    return;
}
// simple type: check key and value format
checkSimpleValue(psiClass, value, holder);

Inline comments are now placed inside the code block they explain.

4 Method Abstraction

Before, compareNameAndValue was long and handled type discrimination, complex logic, and error registration in one method, making it hard to read. After refactoring, the complex comparison logic was extracted to a separate method, and the original method now only determines the type and delegates the work.

public void compareKeyAndValue(PsiClass psiClass, YAMLValue value, ProblemsHolder holder) {
    if (YamlUtil.isNull(value)) {
        return;
    }
    if (PsiClassUtil.isSimpleType(psiClass)) {
        // simple type: check key and value format
        checkSimpleValue(psiClass, value, holder);
    } else if (PsiClassUtil.isGenericType(psiClass)) {
        // generic, Object, whitelist: no check
    } else {
        checkComplexValue(psiClass, value, holder);
    }
}

5 Complex Conditional Logic

Before the code contained deeply nested if statements, making the logic hard to follow. After refactoring, the nesting was reduced, improving readability and maintainability.

6 Robustness

6.1 Precise Error Messages

// before
holder.registerProblem(value, "类型无法转换", ProblemHighlightType.GENERIC_ERROR);

// after
String errorMsg = String.format("cannot find field:%s in class:%s", yamlKeyValue.getName(), psiClass.getQualifiedName());
holder.registerProblem(yamlKeyValue.getKey(), errorMsg, ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);

The new message specifies which field and class are missing, helping users locate the issue quickly.

6.2 Exception Handling

Before, null pointers could occur (e.g., deleteSqlList might be null). After refactoring, each potential null is checked, and appropriate error registration is performed.

@Override
public void doVisitMapping(@NotNull YAMLMapping mapping, @NotNull ProblemsHolder holder) {
    ASTNode node = mapping.getNode().findChildByType(YAMLTokenTypes.TAG);
    if (YamlUtil.isNull(node)) {
        return;
    }
    if (node.getText() == null || !node.getText().startsWith("!!")) {
        holder.registerProblem(node.getPsi(), "yaml plugin error: text is null or does not start with !!", ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);
        return;
    }
    String tagClassName = node.getText().substring(2);
    PsiClass[] psiClasses = ProjectService.findPsiClasses(tagClassName, mapping.getProject());
    if (ArrayUtils.isEmpty(psiClasses)) {
        String errorMsg = String.format("cannot find className = %s", tagClassName);
        holder.registerProblem(node.getPsi(), errorMsg, ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);
        return;
    }
    if (psiClasses.length == 1) {
        compareKeyAndValue(psiClasses[0], mapping, holder);
    }
}

6.3 Switch Default Handling

// before
switch (className) {
    case "java.lang.Boolean":
        break;
    case "java.lang.Character":
        break;
    case "java.math.BigDecimal":
        break;
    case "java.util.Date":
        break;
    default:
}

// after
switch (className) {
    case "java.lang.Boolean":
        break;
    case "java.lang.Character":
        break;
    case "java.math.BigDecimal":
        break;
    case "java.util.Date":
        break;
    case "java.lang.String":
        return true;
    default:
        holder.registerProblem(value, "Unrecognized className: " + className, ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);
        return false;
}

The revised switch adds explicit handling for String and registers an error for unknown classes, making the logic clearer and more robust.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Software qualityIDEA PluginYAML inspection
Alibaba Cloud Developer
Written by

Alibaba Cloud Developer

Alibaba's official tech channel, featuring all of its technology innovations.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.