sleekbyte/tailor

View on GitHub
src/main/java/com/sleekbyte/tailor/listeners/whitespace/ColonWhitespaceListener.java

Summary

Maintainability
A
2 hrs
Test Coverage
package com.sleekbyte.tailor.listeners.whitespace;

import com.sleekbyte.tailor.antlr.SwiftBaseListener;
import com.sleekbyte.tailor.antlr.SwiftParser;
import com.sleekbyte.tailor.common.Messages;
import com.sleekbyte.tailor.common.Rules;
import com.sleekbyte.tailor.output.Printer;
import com.sleekbyte.tailor.utils.ParseTreeUtil;
import com.sleekbyte.tailor.utils.WhitespaceVerifier;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.TerminalNodeImpl;

/**
 * Flags invalid whitespace around colons.
 */
public final class ColonWhitespaceListener extends SwiftBaseListener {

    private WhitespaceVerifier verifier;

    public ColonWhitespaceListener(Printer printer) {
        verifier = new WhitespaceVerifier(printer, Rules.COLON_WHITESPACE);
    }

    @Override
    public void enterDictionaryLiteralItem(SwiftParser.DictionaryLiteralItemContext ctx) {
        Token left = ctx.expression(0).getStop();
        Token right = ctx.expression(1).getStart();
        Token colon = ((TerminalNodeImpl) ctx.getChild(1)).getSymbol();

        verifyColonLeftAssociation(left, right, colon);
    }

    @Override
    public void enterTypeAnnotation(SwiftParser.TypeAnnotationContext ctx) {
        TerminalNodeImpl colon = (TerminalNodeImpl) ctx.getChild(0);
        ParseTree parentLeftSibling = ParseTreeUtil.getLeftSibling(colon.getParent());
        ParseTree rightSibling = ctx.getChild(1);

        Token left = ParseTreeUtil.getStopTokenForNode(parentLeftSibling);
        Token right = ParseTreeUtil.getStartTokenForNode(rightSibling);
        Token colonToken = colon.getSymbol();

        verifyColonLeftAssociation(left, right, colonToken);
    }

    @Override
    public void enterDictionaryType(SwiftParser.DictionaryTypeContext ctx) {
        Token left = ctx.sType(0).getStop();
        Token right = ctx.sType(1).getStart();
        Token colon = ((TerminalNodeImpl) ctx.getChild(2)).getSymbol();

        verifyColonLeftAssociation(left, right, colon);
    }

    @Override
    public void enterSwitchCase(SwiftParser.SwitchCaseContext ctx) {
        Token left = null;
        Token right = null;
        Token colon = null;

        if (ctx.caseLabel() != null) {
            left = ctx.caseLabel().caseItemList().getStop();
            ParseTree rightChild = ctx.getChild(1);
            // right child can be statements or a semi colon
            right = ParseTreeUtil.getStartTokenForNode(rightChild);
            colon = ((TerminalNodeImpl) ctx.caseLabel().getChild(2)).getSymbol();
        } else {
            left = ((TerminalNodeImpl) ctx.defaultLabel().getChild(0)).getSymbol();
            ParseTree rightChild = ctx.getChild(1);
            right = ParseTreeUtil.getStartTokenForNode(rightChild);
            colon = ((TerminalNodeImpl) ctx.defaultLabel().getChild(1)).getSymbol();
        }

        verifyColonLeftAssociation(left, right, colon);
    }

    @Override
    public void enterTypeInheritanceClause(SwiftParser.TypeInheritanceClauseContext ctx) {
        Token colon = ((TerminalNodeImpl) ctx.getChild(0)).getSymbol();
        Token right = ((ParserRuleContext) ctx.getChild(1)).getStart();
        Token left = ((ParserRuleContext) ParseTreeUtil.getLeftSibling(ctx)).getStop();

        verifyColonLeftAssociation(left, right, colon);
    }

    @Override
    public void enterConditionalOperator(SwiftParser.ConditionalOperatorContext ctx) {
        Token colon = ((TerminalNodeImpl) ctx.getChild(ctx.getChildCount() - 1)).getSymbol();
        Token left = ctx.expression().getStop();
        Token right = ((ParserRuleContext) ParseTreeUtil.getRightSibling(ctx)).getStart();

        verifyColonIsSpaceDelimited(left, right, colon);
    }

    @Override
    public void enterTupleElement(SwiftParser.TupleElementContext ctx) {
        if (ctx.identifier() != null) {
            Token colon = ((TerminalNodeImpl) ctx.getChild(1)).getSymbol();
            Token left = ctx.identifier().getStop();

            if (ctx.expression() != null) {
                Token right = ctx.expression().getStart();
                verifyColonLeftAssociation(left, right, colon);
            } else {
                verifier.verifyPunctuationLeftAssociation(left, colon, Messages.COLON);
            }
        }
    }

    @Override
    public void enterFunctionCallArgument(SwiftParser.FunctionCallArgumentContext ctx) {
        if (ctx.functionCallIdentifier() != null) {
            Token colon = ((TerminalNodeImpl) ctx.getChild(1)).getSymbol();
            Token left = ctx.functionCallIdentifier().getStop();
            if (ctx.expression() == null && ctx.operator() == null) {
                verifier.verifyPunctuationLeftAssociation(left, colon, Messages.COLON);
                return;
            }
            ParserRuleContext rightCtx = ctx.expression() == null ? ctx.operator() : ctx.expression();
            Token right = rightCtx.getStart();

            verifyColonLeftAssociation(left, right, colon);
        }
    }

    @Override
    public void enterGenericParameter(SwiftParser.GenericParameterContext ctx) {
        if (ctx.getChildCount() == 3) {
            Token colon = ((TerminalNodeImpl) ctx.getChild(1)).getSymbol();
            Token left = ctx.typeName().getStop();
            Token right = ((ParserRuleContext) ctx.getChild(2)).getStart();

            verifyColonLeftAssociation(left, right, colon);
        }
    }

    @Override
    public void enterArgumentName(SwiftParser.ArgumentNameContext ctx) {
        Token colon = ((TerminalNodeImpl) ctx.getChild(1)).getSymbol();
        Token left = ctx.identifier() == null
            ? ((TerminalNodeImpl) ctx.getChild(0)).getSymbol()
            : ctx.identifier().getStop();
        verifier.verifyPunctuationLeftAssociation(left, colon, Messages.COLON);
    }

    private void verifyColonIsSpaceDelimited(Token left, Token right, Token colon) {
        verifier.verifyPunctuationIsSpaceDelimited(left, right, colon, Messages.COLON);
    }

    private void verifyColonLeftAssociation(Token left, Token right, Token colon) {
        verifier.verifyPunctuationLeftAssociation(left, right, colon, Messages.COLON);
    }


}