Search in sources :

Example 1 with ScannerState

use of com.redhat.qute.parser.template.scanner.ScannerState in project quarkus-ls by redhat-developer.

the class TemplateParser method parse.

public static Template parse(TextDocument textDocument, SectionFactory sectionFactory, CancelChecker cancelChecker) {
    if (cancelChecker == null) {
        cancelChecker = DEFAULT_CANCEL_CHECKER;
    }
    Template template = new Template(textDocument);
    template.setCancelChecker(cancelChecker);
    Node curr = template;
    String content = textDocument.getText();
    int endTagOpenOffset = -1;
    int startSectionOffset = -1;
    int endSectionOffset = -1;
    Scanner<TokenType, ScannerState> scanner = TemplateScanner.createScanner(content);
    TokenType token = scanner.scan();
    while (token != TokenType.EOS) {
        cancelChecker.checkCanceled();
        curr = createSectionIfNeeded(startSectionOffset, endSectionOffset, curr, scanner, token, sectionFactory);
        startSectionOffset = -1;
        endSectionOffset = -1;
        switch(token) {
            case StartTagOpen:
                {
                    if (!curr.isClosed() && curr.getParent() != null) {
                        // The next node's parent (curr) is not closed at this point
                        // so the node's parent (curr) will have its end position updated
                        // to a newer end position.
                        curr.setEnd(scanner.getTokenOffset());
                    }
                    if (canSwithToParentNode(curr)) {
                        // The next node being considered is a child of 'curr'
                        // and if 'curr' is already closed then 'curr' was not updated properly.
                        curr = curr.getParent();
                    }
                    startSectionOffset = scanner.getTokenOffset();
                    endSectionOffset = scanner.getTokenEnd();
                    break;
                }
            case StartTag:
                {
                    curr.setEnd(scanner.getTokenEnd());
                    break;
                }
            case StartTagClose:
                if (curr.getKind() == NodeKind.Section) {
                    Section section = (Section) curr;
                    // might be later set to end tag position
                    curr.setEnd(scanner.getTokenEnd());
                    section.setStartTagCloseOffset(scanner.getTokenOffset());
                    // never enters isEmptyElement() is always false
                    if (section.getTag() != null && isEmptyElement(section.getTag()) && curr.getParent() != null) {
                        curr.setClosed(true);
                        curr = curr.getParent();
                    }
                }
                curr.setEnd(scanner.getTokenEnd());
                break;
            case EndTagOpen:
                endTagOpenOffset = scanner.getTokenOffset();
                curr.setEnd(endTagOpenOffset);
                break;
            case EndTag:
                // end tag (ex: {/if})
                String closeTag = scanner.getTokenText();
                Node current = curr;
                /**
                 * eg: <a><b><c></d> will set a,b,c end position to the start of |</d>
                 */
                while (!(curr.getKind() == NodeKind.Section && Objects.equals(((Section) curr).getTag(), closeTag)) && curr.getParent() != null) {
                    curr.setEnd(endTagOpenOffset);
                    curr = curr.getParent();
                }
                if (curr != template) {
                    curr.setClosed(true);
                    if (curr.getKind() == NodeKind.Section) {
                        ((Section) curr).setEndTagOpenOffset(endTagOpenOffset);
                    }
                    curr.setEnd(scanner.getTokenEnd());
                } else {
                    // element open tag not found (ex: <root>) add a fake element which only has an
                    // end tag (no start tag).
                    Section element = sectionFactory.createSection(closeTag, scanner.getTokenOffset() - 2, scanner.getTokenEnd());
                    element.setEndTagOpenOffset(endTagOpenOffset);
                    current.addChild(element);
                    curr = element;
                }
                break;
            case StartTagSelfClose:
                if (curr.getParent() != null) {
                    curr.setClosed(true);
                    Section section = (Section) curr;
                    section.setSelfClosed(true);
                    section.setStartTagCloseOffset(scanner.getTokenOffset());
                    curr.setEnd(scanner.getTokenEnd());
                    curr = curr.getParent();
                }
                break;
            case EndTagSelfClose:
                if (curr.getParent() != null) {
                    Section section = (Section) curr;
                    curr.setClosed(true);
                    curr.setEnd(scanner.getTokenEnd());
                    section.setEndTagOpenOffset(scanner.getTokenOffset());
                    section.setEndTagCloseOffset(scanner.getTokenEnd() - 1);
                    curr = curr.getParent();
                }
                break;
            case EndTagClose:
                if (curr.getParent() != null) {
                    Section section = (Section) curr;
                    curr.setEnd(scanner.getTokenEnd());
                    section.setEndTagCloseOffset(scanner.getTokenOffset());
                    curr = curr.getParent();
                }
                break;
            case StartExpression:
                {
                    // curr should be set to the root node.
                    if (curr.isClosed() && curr.getKind() != NodeKind.Template) {
                        curr = curr.getParent();
                    }
                    int start = scanner.getTokenOffset();
                    int end = scanner.getTokenEnd();
                    Expression expression = new Expression(start, end);
                    curr.addChild(expression);
                    curr = expression;
                    break;
                }
            case EndExpression:
                {
                    int end = scanner.getTokenEnd();
                    Expression expression = (Expression) curr;
                    expression.setClosed(true);
                    expression.setEnd(end);
                    curr = curr.getParent();
                    break;
                }
            case StartComment:
                {
                    // curr should be set to the root node.
                    if (curr.isClosed() && curr.getKind() != NodeKind.Template) {
                        curr = curr.getParent();
                    }
                    int start = scanner.getTokenOffset();
                    int end = scanner.getTokenEnd();
                    Comment comment = new Comment(start, end);
                    curr.addChild(comment);
                    curr = comment;
                    break;
                }
            case Comment:
                {
                    Comment comment = (Comment) curr;
                    comment.setStartContent(scanner.getTokenOffset());
                    comment.setEndContent(scanner.getTokenEnd());
                    break;
                }
            case EndComment:
                {
                    int end = scanner.getTokenEnd();
                    Comment comment = (Comment) curr;
                    comment.setClosed(true);
                    comment.setEnd(end);
                    curr = curr.getParent();
                    break;
                }
            case CDATATagOpen:
            case CDATAOldTagOpen:
                {
                    // curr should be set to the root node.
                    if (curr.isClosed() && curr.getKind() != NodeKind.Template) {
                        curr = curr.getParent();
                    }
                    int start = scanner.getTokenOffset();
                    int end = scanner.getTokenEnd();
                    CData cdata = new CData(start, end);
                    curr.addChild(cdata);
                    curr = cdata;
                    break;
                }
            case CDATAContent:
                {
                    CData cdata = (CData) curr;
                    cdata.setStartContent(scanner.getTokenOffset());
                    cdata.setEndContent(scanner.getTokenEnd());
                    break;
                }
            case CDATATagClose:
            case CDATAOldTagClose:
                {
                    int end = scanner.getTokenEnd();
                    CData cdata = (CData) curr;
                    cdata.setClosed(true);
                    cdata.setEnd(end);
                    curr = curr.getParent();
                    break;
                }
            case StartParameterDeclaration:
                {
                    // curr should be set to the root node.
                    if (curr.isClosed() && curr.getKind() != NodeKind.Template) {
                        curr = curr.getParent();
                    }
                    int start = scanner.getTokenOffset();
                    int end = scanner.getTokenEnd();
                    ParameterDeclaration parameter = new ParameterDeclaration(start, end);
                    curr.addChild(parameter);
                    curr = parameter;
                    break;
                }
            case EndParameterDeclaration:
                {
                    int end = scanner.getTokenEnd();
                    ParameterDeclaration parameter = (ParameterDeclaration) curr;
                    parameter.setClosed(true);
                    parameter.setEnd(end);
                    curr = curr.getParent();
                    break;
                }
            case Content:
                {
                    int start = scanner.getTokenOffset();
                    int end = scanner.getTokenEnd();
                    Text text = new Text(start, end);
                    curr.addChild(text);
                    break;
                }
            default:
        }
        token = scanner.scan();
    }
    curr = createSectionIfNeeded(startSectionOffset, endSectionOffset, curr, scanner, token, sectionFactory);
    while (curr.getParent() != null) {
        curr.setEnd(content.length());
        curr = curr.getParent();
    }
    return template;
}
Also used : ElseSection(com.redhat.qute.parser.template.sections.ElseSection) CaseSection(com.redhat.qute.parser.template.sections.CaseSection) IsSection(com.redhat.qute.parser.template.sections.IsSection) TokenType(com.redhat.qute.parser.template.scanner.TokenType) ScannerState(com.redhat.qute.parser.template.scanner.ScannerState)

Example 2 with ScannerState

use of com.redhat.qute.parser.template.scanner.ScannerState in project quarkus-ls by redhat-developer.

the class QuteTemplateIndex method collect.

private void collect(String template, List<QuteIndex> indexes) {
    Scanner<TokenType, ScannerState> scanner = TemplateScanner.createScanner(template);
    TokenType token = scanner.scan();
    String lastTag = null;
    int lastTokenOffset = -1;
    SectionKind lastSectionKind = null;
    while (token != TokenType.EOS) {
        switch(token) {
            case StartTag:
                {
                    String tag = scanner.getTokenText();
                    if (SectionKind.INCLUDE.name().toLowerCase().equals(tag)) {
                        lastTag = tag;
                        lastTokenOffset = scanner.getTokenOffset();
                        lastSectionKind = SectionKind.INCLUDE;
                    } else if (SectionKind.INSERT.name().toLowerCase().equals(tag)) {
                        lastTag = tag;
                        lastTokenOffset = scanner.getTokenOffset();
                        lastSectionKind = SectionKind.INSERT;
                    } else if (isCustomTag(tag)) {
                        collectIndex(scanner.getTokenOffset(), SectionKind.CUSTOM, scanner.getTokenText(), null, template, indexes);
                    }
                    break;
                }
            case ParameterTag:
                {
                    if (lastSectionKind != null) {
                        String parameter = scanner.getTokenText();
                        collectIndex(scanner.getTokenOffset(), lastSectionKind, lastTag, parameter, template, indexes);
                        lastTokenOffset = -1;
                        lastSectionKind = null;
                        lastTag = null;
                    }
                    break;
                }
            case Whitespace:
                {
                    break;
                }
            default:
                if (lastSectionKind != null) {
                    collectIndex(lastTokenOffset, lastSectionKind, lastTag, null, template, indexes);
                    lastTokenOffset = -1;
                    lastSectionKind = null;
                    lastTag = null;
                }
        }
        token = scanner.scan();
    }
}
Also used : SectionKind(com.redhat.qute.parser.template.SectionKind) TokenType(com.redhat.qute.parser.template.scanner.TokenType) ScannerState(com.redhat.qute.parser.template.scanner.ScannerState)

Aggregations

ScannerState (com.redhat.qute.parser.template.scanner.ScannerState)2 TokenType (com.redhat.qute.parser.template.scanner.TokenType)2 SectionKind (com.redhat.qute.parser.template.SectionKind)1 CaseSection (com.redhat.qute.parser.template.sections.CaseSection)1 ElseSection (com.redhat.qute.parser.template.sections.ElseSection)1 IsSection (com.redhat.qute.parser.template.sections.IsSection)1