Package com.dubture.twig.core.format

Source Code of com.dubture.twig.core.format.CurlyCloseIndentationStrategy

/*******************************************************************************
* This file is part of the Twig eclipse plugin.
*
* (c) Robert Gruendler <r.gruendler@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
******************************************************************************/
package com.dubture.twig.core.format;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IRegion;
import org.eclipse.php.internal.core.documentModel.parser.regions.PHPRegionTypes;
import org.eclipse.php.internal.core.format.IIndentationStrategy;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionContainer;

import com.dubture.twig.core.documentModel.parser.TwigRegionContext;
import com.dubture.twig.core.documentModel.parser.regions.ITwigScriptRegion;

@SuppressWarnings("restriction")
public class CurlyCloseIndentationStrategy implements IIndentationStrategy
{

    public void placeMatchingBlanks(IStructuredDocument document,
            StringBuffer result, int lineNumber, int forOffset)
            throws BadLocationException
    {
        final IRegion curlyOpenLine = getCurlyOpenLineInformation(document,
                forOffset);
        if (curlyOpenLine == null) {
            return;
        }
        int indentationBaseLineIndex = DefaultIndentationStrategy
                .getIndentationBaseLine(document,
                        document.getLineOfOffset(curlyOpenLine.getOffset()),
                        forOffset, true);
        final IRegion indentationBaseLine = document
                .getLineInformation(indentationBaseLineIndex);
        String blanks = "";
        if (indentationBaseLine != null) {
            blanks = FormatterUtils
                    .getLineBlanks(document, indentationBaseLine);
        } else { // if no matching bracket was found leaving the bracket as is.
            blanks = FormatterUtils.getLineBlanks(document,
                    document.getLineInformationOfOffset(forOffset));
        }
        result.append(blanks);
    }

    /**
     * This function returns the line in which the corresponding '{' of the '}'
     * found
     *
     * TODO this function has a bug in it: if there is a '{' inside inner state
     * then it will not ignore it as it should.
     */
    protected IRegion getCurlyOpenLineInformation(IStructuredDocument document,
            int forOffset) throws BadLocationException
    {
        int offset = forOffset;
        int curlyCount = 0;

        IStructuredDocumentRegion sdRegion = document
                .getRegionAtCharacterOffset(offset);
        if (sdRegion == null) {
            return null;
        }
        ITextRegion tRegion = sdRegion.getRegionAtCharacterOffset(offset);
        if (tRegion == null && offset == document.getLength()) {
            tRegion = sdRegion.getRegionAtCharacterOffset(offset - 1);
        }
        int regionStart = sdRegion.getStartOffset(tRegion);

        // in case of container we have the extract the PhpScriptRegion
        if (tRegion instanceof ITextRegionContainer) {
            ITextRegionContainer container = (ITextRegionContainer) tRegion;
            tRegion = container.getRegionAtCharacterOffset(offset);
            regionStart += tRegion.getStart();
        }
        do {
            if (tRegion instanceof ITwigScriptRegion) {
                ITwigScriptRegion scriptRegion = (ITwigScriptRegion) tRegion;
                tRegion = scriptRegion.getTwigToken(offset - regionStart - 1);

                // go backward over the region to find a 'case' or 'default'
                // region
                // in this case is the same indentation
                // other case if look for the '{' of the 'switch' region
                while (tRegion != null) {
                    String token = tRegion.getType();
                    if (token == PHPRegionTypes.PHP_CURLY_OPEN) {
                        curlyCount--;
                        if (curlyCount < 0) {
                            return document.getLineInformationOfOffset(tRegion
                                    .getStart() + regionStart);
                        }
                    } else if (token == PHPRegionTypes.PHP_CURLY_CLOSE) {
                        curlyCount++;
                    }
                    if (tRegion.getStart() > 0) {
                        tRegion = scriptRegion
                                .getTwigToken(tRegion.getStart() - 1);
                    } else {
                        break;
                    }
                }
            }

            tRegion = null;
            // looking for the previous php block, maybe the '{' is in it
            // (https://bugs.eclipse.org/bugs/show_bug.cgi?id=201648)
            while ((sdRegion = sdRegion.getPrevious()) != null) {
                if (sdRegion.getFirstRegion().getType()
                        .equals(TwigRegionContext.TWIG_OPEN)
                        || sdRegion.getFirstRegion().getType()
                                .equals(TwigRegionContext.TWIG_STMT_OPEN)) {
                    tRegion = sdRegion.getRegions().get(1);
                    regionStart = sdRegion.getStartOffset(tRegion);
                    offset = sdRegion.getEndOffset(tRegion);
                    break;
                }
            }
        } while (tRegion != null);
        return null;

    }

}
TOP

Related Classes of com.dubture.twig.core.format.CurlyCloseIndentationStrategy

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.