private void addFormatToken()

in php/php.editor/src/org/netbeans/modules/php/editor/indent/FormatVisitor.java [2735:3182]


    private void addFormatToken(List<FormatToken> tokens) {
        if (lastIndex == ts.index()) {
            assert false : showAssertionFor188809();
            ts.moveNext();
            return;
        }
        lastIndex = ts.index();
        switch (ts.token().id()) {
            case WHITESPACE:
                tokens.addAll(resolveWhitespaceTokens());
                break;
            case PHP_LINE_COMMENT:
                if (ts.token().text().charAt(ts.token().length() - 1) == '\n') {
                    CharSequence text = ts.token().text().subSequence(0, ts.token().length() - 1);
                    int newOffset = ts.offset() + ts.token().length() - 1;
                    if (text.length() > 0) {
                        tokens.add(new FormatToken(FormatToken.Kind.LINE_COMMENT, ts.offset(), text.toString()));
                    }
                    if (ts.moveNext()) {
                        if (ts.token().id() == PHPTokenId.WHITESPACE) {
                            if (countOfNewLines(ts.token().text()) > 0) {
                                // reset group alignment, if there is an empty line
                                resetAndCreateGroupAlignment();
                            }
                            tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_INDENT, newOffset, "\n" + ts.token().text().toString()));
                            if (ts.moveNext() && ts.token().id() == PHPTokenId.PHP_LINE_COMMENT) {
                                ASTNode parent = path.get(0);
                                if (!(parent instanceof IfStatement) || isCurly) {
                                    // GH-7185 don't add this to an "if" statement without curly braces
                                    // e.g.
                                    // if (true)
                                    //     $example = 1; // comment1
                                    //
                                    // // comment2
                                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BETWEEN_LINE_COMMENTS, ts.offset()));
                                }
                            }
                            // #268710 for adding/checking the PHP_LINE_COMMENT token later
                            ts.movePrevious();
                        } else {
                            tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_INDENT, newOffset, "\n"));
                            ts.movePrevious();
                        }
                    } else {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_INDENT, newOffset, "\n"));
                    }

                } else {
                    tokens.add(new FormatToken(FormatToken.Kind.LINE_COMMENT, ts.offset(), ts.token().text().toString()));
                }
                break;
            case PHP_OPENTAG:
            case T_OPEN_TAG_WITH_ECHO:
                tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_OPEN_PHP_TAG, ts.offset()));
                tokens.add(new FormatToken(FormatToken.Kind.OPEN_TAG, ts.offset(), ts.token().text().toString()));
                tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AFTER_OPEN_PHP_TAG, ts.offset() + ts.token().length()));
                break;
            case PHP_CLOSETAG:
                tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_CLOSE_PHP_TAG, ts.offset()));
                tokens.add(new FormatToken(FormatToken.Kind.CLOSE_TAG, ts.offset(), ts.token().text().toString()));
                tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AFTER_CLOSE_PHP_TAG, ts.offset() + ts.token().length()));
                break;
            case PHP_COMMENT_START:
                tokens.add(new FormatToken(FormatToken.Kind.COMMENT_START, ts.offset(), ts.token().text().toString()));
                break;
            case PHP_COMMENT_END:
                tokens.add(new FormatToken(FormatToken.Kind.COMMENT_END, ts.offset(), ts.token().text().toString()));
                break;
            case PHP_COMMENT:
                tokens.add(new FormatToken(FormatToken.Kind.COMMENT, ts.offset(), ts.token().text().toString()));
                break;
            case PHPDOC_COMMENT:
                tokens.add(new FormatToken(FormatToken.Kind.DOC_COMMENT, ts.offset(), ts.token().text().toString()));
                break;
            case PHPDOC_COMMENT_START:
                tokens.add(new FormatToken(FormatToken.Kind.DOC_COMMENT_START, ts.offset(), ts.token().text().toString()));
                break;
            case PHPDOC_COMMENT_END:
                tokens.add(new FormatToken(FormatToken.Kind.DOC_COMMENT_END, ts.offset(), ts.token().text().toString()));
                break;
            case PHP_PAAMAYIM_NEKUDOTAYIM:
                tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AROUND_SCOPE_RESOLUTION_OP, ts.offset()));
                tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AROUND_SCOPE_RESOLUTION_OP, ts.offset() + ts.token().length()));
                break;
            case PHP_OBJECT_OPERATOR:
                tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AROUND_OBJECT_OP, ts.offset()));
                tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AROUND_OBJECT_OP, ts.offset() + ts.token().length()));
                break;
            case PHP_NULLSAFE_OBJECT_OPERATOR:
                tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AROUND_NULLSAFE_OBJECT_OP, ts.offset()));
                tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AROUND_NULLSAFE_OBJECT_OP, ts.offset() + ts.token().length()));
                break;
            case PHP_CASTING:
                String text = ts.token().text().toString();
                String part1 = text.substring(0, text.indexOf('(') + 1);
                String part2 = text.substring(part1.length(), text.indexOf(')'));
                String part3 = text.substring(part1.length() + part2.length());
                StringBuilder ws1 = new StringBuilder();
                StringBuilder ws2 = new StringBuilder();
                int index = 0;
                while (index < part2.length() && part2.charAt(index) == ' ') {
                    ws1.append(' ');
                    index++;
                }
                index = part2.length() - 1;
                while (index > 0 && part2.charAt(index) == ' ') {
                    ws2.append(' ');
                    index--;
                }
                part2 = part2.trim();
                int length = 0;
                tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), part1));
                length += part1.length();
                tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_TYPE_CAST_PARENS, ts.offset() + part1.length()));
                if (ws1.length() > 0) {
                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE, ts.offset() + length, ws1.toString()));
                    length += ws1.length();
                }
                tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset() + length, part2));
                length += part2.length();
                if (ws2.length() > 0) {
                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE, ts.offset() + length, ws2.toString()));
                    length += ws2.length();
                }
                tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_TYPE_CAST_PARENS, ts.offset() + length));
                tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset() + length, part3));
                length += part3.length();
                tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AFTER_TYPE_CAST, ts.offset() + length));
                break;
            case PHP_TOKEN:
                CharSequence txt = ts.token().text();
                ASTNode parent = path.get(0);
                if (TokenUtilities.textEquals("(", txt)) { // NOI18N
                    if (isAnonymousClass(parent)) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_ANONYMOUS_CLASS_PAREN, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_ANONYMOUS_CLASS_PARENS, ts.offset() + ts.token().length()));
                    } else if (parent instanceof FunctionDeclaration || parent instanceof MethodDeclaration || parent instanceof ArrowFunctionDeclaration) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_METHOD_DEC_PAREN, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_METHOD_DECL_PARENS, ts.offset() + ts.token().length()));
                    } else if (parent instanceof LambdaFunctionDeclaration) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_ANONYMOUS_FUNCTION_PAREN, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_METHOD_DECL_PARENS, ts.offset() + ts.token().length()));
                    } else if (parent instanceof FunctionInvocation || parent instanceof MethodInvocation || parent instanceof ClassInstanceCreation) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_METHOD_CALL_PAREN, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_METHOD_CALL_PARENS, ts.offset() + ts.token().length()));
                    } else if (parent instanceof AttributeDeclaration) { // A("param")
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_ATTRIBUTE_DEC_PAREN, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_ATTRIBUTE_DECL_PARENS, ts.offset() + ts.token().length()));
                    } else if (parent instanceof IfStatement) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_IF_PAREN, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_IF_PARENS, ts.offset() + ts.token().length()));
                    } else if (parent instanceof ForEachStatement || parent instanceof ForStatement) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_FOR_PAREN, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_FOR_PARENS, ts.offset() + ts.token().length()));
                    } else if (parent instanceof WhileStatement || parent instanceof DoStatement) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_WHILE_PAREN, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_WHILE_PARENS, ts.offset() + ts.token().length()));
                    } else if (parent instanceof SwitchStatement) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_SWITCH_PAREN, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_SWITCH_PARENS, ts.offset() + ts.token().length()));
                    } else if (parent instanceof MatchExpression) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_MATCH_PAREN, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_MATCH_PARENS, ts.offset() + ts.token().length()));
                    } else if (parent instanceof CatchClause) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_CATCH_PAREN, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_CATCH_PARENS, ts.offset() + ts.token().length()));
                    } else if (parent instanceof ArrayCreation) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_ARRAY_DECL_PAREN, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AFTER_ARRAY_DECL_LEFT_PAREN, ts.offset() + ts.token().length()));
                    } else if (parent instanceof UnionType) {
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_DNF_TYPE_PARENS, ts.offset() + ts.token().length()));
                    } else if (isParenthesisExpression(parent)
                            || parent instanceof DereferencableVariable
                            || isAnonymousObjectVariable(parent)
                            ) {
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_OTHER_PARENS, ts.offset() + ts.token().length()));
                    } else {
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                    }
                } else if (TokenUtilities.textEquals(")", txt)) { // NOI18N
                    if (isAnonymousClass(parent)) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_ANONYMOUS_CLASS_PARENS, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                    } else if (parent instanceof FunctionDeclaration || parent instanceof MethodDeclaration
                            || parent instanceof LambdaFunctionDeclaration || parent instanceof ArrowFunctionDeclaration) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_METHOD_DECL_PARENS, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                    } else if (parent instanceof FunctionInvocation || parent instanceof MethodInvocation || parent instanceof ClassInstanceCreation) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_METHOD_CALL_PARENS, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                    } else if (parent instanceof AttributeDeclaration) { // A("param")
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_ATTRIBUTE_DECL_PARENS, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                    } else if (parent instanceof IfStatement) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_IF_PARENS, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                    } else if (parent instanceof ForEachStatement || parent instanceof ForStatement) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_FOR_PARENS, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                    } else if (parent instanceof WhileStatement || parent instanceof DoStatement) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_WHILE_PARENS, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                    } else if (parent instanceof SwitchStatement) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_SWITCH_PARENS, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                    } else if (parent instanceof MatchExpression) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_MATCH_PARENS, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                    } else if (parent instanceof CatchClause) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_CATCH_PARENS, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                    } else if (parent instanceof ArrayCreation) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_ARRAY_DECL_RIGHT_PAREN, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                    } else if (parent instanceof UnionType) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_DNF_TYPE_PARENS, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                    } else if (parent instanceof ParenthesisExpression
                            || parent instanceof DereferencableVariable
                            || parent instanceof AnonymousObjectVariable) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_OTHER_PARENS, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                    } else {
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                    }
                } else if (TokenUtilities.textEquals("[", txt)) {
                    if (parent instanceof ArrayCreation) {
                        // do not add this format token, it historically serves for case "array ()"
                        //tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_ARRAY_DECL_PAREN, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AFTER_ARRAY_DECL_LEFT_PAREN, ts.offset() + ts.token().length()));
                    } else {
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_ARRAY_BRACKETS_PARENS, ts.offset() + ts.token().length()));
                    }
                } else if (TokenUtilities.textEquals("]", txt)) {
                    if (parent instanceof ArrayCreation) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_ARRAY_DECL_RIGHT_PAREN, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                    } else if (isAttributeCloseBracket) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_ATTRIBUTE_BRACKETS, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                    } else {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_ARRAY_BRACKETS_PARENS, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                    }
                } else if (TokenUtilities.textEquals(",", txt)) {
                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_COMMA, ts.offset()));
                    tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AFTER_COMMA, ts.offset() + ts.token().length()));
                } else if (TokenUtilities.textEquals(":", txt)) { // NOI18N
                    if (parent instanceof FunctionDeclaration
                            || parent instanceof MethodDeclaration
                            || parent instanceof LambdaFunctionDeclaration
                            || parent instanceof ArrowFunctionDeclaration) {
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_RETURN_TYPE_SEPARATOR, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AFTER_RETURN_TYPE_SEPARATOR, ts.offset() + ts.token().length()));
                    } else if (parent instanceof NamedArgument){ // [NETBEANS-4443] PHP 8.0 Support
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_NAMED_ARGUMENT_SEPARATOR, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AFTER_NAMED_ARGUMENT_SEPARATOR, ts.offset() + ts.token().length()));
                    } else if (parent instanceof EnumDeclaration){ // [NETBEANS-5599] PHP 8.1 Support
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_ENUM_BACKING_TYPE_SEPARATOR, ts.offset()));
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                        tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AFTER_ENUM_BACKING_TYPE_SEPARATOR, ts.offset() + ts.token().length()));
                    } else if (parent instanceof FunctionInvocation){ // [NETBEANS-4443] PHP 8.0 Support
                        // e.g. functionInvocation(paramName: );
                        // add white space when "parameterName:" is added (via Code Completion)
                        boolean added = false;
                        FunctionInvocation functionInvocation = (FunctionInvocation) parent;
                        List<Expression> parameters = functionInvocation.getParameters();
                        for (Expression parameter : parameters) {
                            if (parameter instanceof ASTErrorExpression
                                    && ts.offset() >= parameter.getStartOffset()
                                    && ts.offset() <= parameter.getEndOffset()) {
                                tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_NAMED_ARGUMENT_SEPARATOR, ts.offset()));
                                tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                                tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AFTER_NAMED_ARGUMENT_SEPARATOR, ts.offset() + ts.token().length()));
                                added = true;
                                break;
                            }
                        }
                        if (!added) {
                            tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                        }
                    } else {
                        tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                    }
                } else {
                    tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                }
                break;
            case PHP_ATTRIBUTE: // #[
                tokens.add(new FormatToken(FormatToken.Kind.ATTRIBUTE_START, ts.offset(), ts.token().text().toString()));
                tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_WITHIN_ATTRIBUTE_BRACKETS, ts.offset() + ts.token().length()));
                break;
            case PHP_OPERATOR:
                CharSequence txt2 = ts.token().text();
                // assignment?
                if (TokenUtilities.equals(txt2, "=") // NOI18N
                        && path.get(0) instanceof DeclareStatement) {
                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AROUND_DECLARE_EQUAL, ts.offset()));
                    tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), txt2.toString()));
                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AROUND_DECLARE_EQUAL, ts.offset() + ts.token().length()));
                    break;
                }
                if (TokenUtilities.equals(txt2, Type.SEPARATOR)
                        && path.get(0) instanceof UnionType) {
                    // NETBEANS-4443 PHP 8.0 Union Types
                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AROUND_UNION_TYPE_SEPARATOR, ts.offset()));
                    tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), txt2.toString()));
                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AROUND_UNION_TYPE_SEPARATOR, ts.offset() + ts.token().length()));
                    break;
                }
                if (TokenUtilities.equals(txt2, Type.SEPARATOR_INTERSECTION)
                        && path.get(0) instanceof IntersectionType) {
                    // NETBEANS-5599 PHP 8.1 Pure intersection types
                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AROUND_INTERSECTION_TYPE_SEPARATOR, ts.offset()));
                    tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), txt2.toString()));
                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AROUND_INTERSECTION_TYPE_SEPARATOR, ts.offset() + ts.token().length()));
                    break;
                }
                if (!TokenUtilities.startsWith(txt2, "==") // NOI18N NETBEANS-2149
                        && TokenUtilities.endsWith(txt2, "=")) { // NOI18N
                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_ASSIGN_OP, ts.offset()));
                    tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AFTER_ASSIGN_OP, ts.offset() + ts.token().length()));
                    break;
                }
                int origOffset = ts.offset();
                if (TokenUtilities.textEquals(txt2, "!")) { // NOI18N
                    if (ts.movePrevious()) {
                        Token<? extends PHPTokenId> previous = LexUtilities.findPrevious(ts, Arrays.asList(PHPTokenId.WHITESPACE));
                        if (previous.id() == PHPTokenId.PHP_RETURN) {
                            tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AFTER_KEYWORD, origOffset));
                        }
                        ts.move(origOffset);
                        ts.moveNext();
                    }
                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AROUND_UNARY_OP, ts.offset()));
                    tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), txt2.toString()));
                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AROUND_UNARY_OP, ts.offset() + ts.token().length()));
                } else if (TokenUtilities.textEquals(txt2, "=>")) { // NOI18N
                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AROUND_KEY_VALUE_OP, ts.offset()));
                    tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), txt2.toString()));
                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AROUND_KEY_VALUE_OP, ts.offset() + ts.token().length()));
                } else if (TokenUtilities.textEquals(txt2, "++") // NOI18N
                        || TokenUtilities.textEquals(txt2, "--")) { // NOI18N
                    Token<? extends PHPTokenId> previousToken = LexUtilities.findPrevious(ts, Arrays.asList(PHPTokenId.PHP_OPERATOR, PHPTokenId.WHITESPACE));
                    if (previousToken != null) {
                        if (previousToken.id() == PHPTokenId.PHP_VARIABLE
                                || previousToken.id() == PHPTokenId.PHP_STRING
                                || (previousToken.id() == PHPTokenId.PHP_TOKEN && TokenUtilities.equals(previousToken.text(), "]"))) { // NOI18N
                            tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AROUND_UNARY_OP, ts.offset() + ts.token().length()));
                        } else if (previousToken.id() == PHPTokenId.PHP_TOKEN && TokenUtilities.equals(previousToken.text(), ".")) { // NOI18N
                            // see PHPFormatterBrokenTest.testIssue197074_02
                            tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE, ts.offset() + ts.token().length()));
                        }
                        ts.move(origOffset);
                        ts.moveNext();
                    }
                    tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), txt2.toString()));
                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AROUND_UNARY_OP, ts.offset() + ts.token().length()));
                } else if (TokenUtilities.textEquals(txt2, Type.SEPARATOR)
                        && path.get(0) instanceof CatchClause) {
                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_MULTI_CATCH_SEPARATOR, ts.offset()));
                    tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AFTER_MULTI_CATCH_SEPARATOR, ts.offset() + ts.token().length()));
                } else {
                    tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                }
                break;
            case PHP_WHILE:
                if (path.get(0) instanceof DoStatement && isCurly) {
                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_WHILE, ts.offset()));
                }
                tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                break;
            case PHP_ELSE:
            case PHP_ELSEIF:
                if (isCurly) {
                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_ELSE, ts.offset()));
                }
                tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                break;
            case PHP_SEMICOLON:
                if (!(ts.movePrevious() && ts.token().id() == PHPTokenId.WHITESPACE
                        && countOfNewLines(ts.token().text()) > 0)) {
                    // if a line starts with the semicolon, don't put this whitespace
                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_SEMI, ts.offset() + ts.token().length()));
                }
                ts.moveNext();
                tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                if (path.size() > 0 && !(path.get(0) instanceof ForStatement)) {
                    tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_AFTER_SEMI, ts.offset() + ts.token().length()));
                }
                break;
            case PHP_CATCH:
                tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_CATCH, ts.offset()));
                tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                break;
            case PHP_FINALLY:
                tokens.add(new FormatToken(FormatToken.Kind.WHITESPACE_BEFORE_FINALLY, ts.offset()));
                tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
                break;
            case T_INLINE_HTML:
                FormatToken.InitToken token = (FormatToken.InitToken) formatTokens.get(0);
                if (!token.hasHTML() && !isWhitespace(ts.token().text()) && !isShebang(ts.token().text())) {
                    token.setHasHTML(true);
                }
                int tokenStartOffset = ts.offset();
                StringBuilder sb = new StringBuilder(ts.token().text());
                // merge all html following tokens to one format token;
                while (ts.moveNext() && ts.token().id() == PHPTokenId.T_INLINE_HTML) {
                    sb.append(ts.token().text());
                }

                if (ts.moveNext()) {
                    ts.movePrevious();
                    ts.movePrevious();
                    tokens.add(new FormatToken(FormatToken.Kind.HTML, tokenStartOffset, sb.toString()));
                } else {
                    // this is the last token in the document
                    lastIndex--;
                }
                break;
            default:
                tokens.add(new FormatToken(FormatToken.Kind.TEXT, ts.offset(), ts.token().text().toString()));
        }
    }