org.ballerinalang.composer.service.workspace.suggetions.CapturePossibleTokenStrategy.java Source code

Java tutorial

Introduction

Here is the source code for org.ballerinalang.composer.service.workspace.suggetions.CapturePossibleTokenStrategy.java

Source

/*
*  Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
*  WSO2 Inc. licenses this file to you under the Apache License,
*  Version 2.0 (the "License"); you may not use this file except
*  in compliance with the License.
*  You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing,
*  software distributed under the License is distributed on an
*  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
*  KIND, either express or implied.  See the License for the
*  specific language governing permissions and limitations
*  under the License.
*/
package org.ballerinalang.composer.service.workspace.suggetions;

import org.antlr.v4.runtime.DefaultErrorStrategy;
import org.antlr.v4.runtime.InputMismatchException;
import org.antlr.v4.runtime.NoViableAltException;
import org.antlr.v4.runtime.Parser;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.misc.IntervalSet;
import org.ballerinalang.composer.service.workspace.langserver.dto.Position;

import java.util.LinkedList;
import java.util.List;

/**
 * Capture possible errors from source
 */
public class CapturePossibleTokenStrategy extends DefaultErrorStrategy {

    protected final Position cursorPosition;

    protected List<PossibleToken> possibleTokens;

    private SuggestionsFilterDataModel suggestionsFilterDataModel;

    public CapturePossibleTokenStrategy(Position cursorPosition) {
        this.cursorPosition = cursorPosition;
        possibleTokens = new LinkedList<>();
        this.setSuggestionsFilterDataModel(new SuggestionsFilterDataModel());
    }

    @Override
    public void reportInputMismatch(Parser parser, InputMismatchException e) {
        fetchPossibleTokens(parser, e.getOffendingToken(), e.getExpectedTokens());
    }

    @Override
    public void reportMissingToken(Parser parser) {
        fetchPossibleTokens(parser, parser.getCurrentToken(), parser.getExpectedTokens());
    }

    @Override
    public void reportNoViableAlternative(Parser parser, NoViableAltException e) {
        fetchPossibleTokens(parser, e.getOffendingToken(), e.getExpectedTokens());
    }

    @Override
    public void reportUnwantedToken(Parser parser) {
        fetchPossibleTokens(parser, parser.getCurrentToken(), parser.getExpectedTokens());
    }

    public List<PossibleToken> getPossibleTokens() {
        return possibleTokens;
    }

    protected void fetchPossibleTokens(Parser parser, Token currentToken, IntervalSet expectedTokens) {
        ParserRuleContext currentContext = parser.getContext();
        if (isCursorBetweenGivenTokenAndLastNonHiddenToken(currentToken, parser)) {
            expectedTokens.getIntervals().forEach((interval) -> {
                int a = interval.a;
                int b = interval.b;
                if (a == b) {
                    possibleTokens
                            .add(new PossibleToken(a, parser.getVocabulary().getDisplayName(a), currentContext));
                } else {
                    for (int i = a; i <= b; ++i) {
                        possibleTokens.add(
                                new PossibleToken(i, parser.getVocabulary().getDisplayName(i), currentContext));
                    }
                }
            });

            SuggestionsFilterDataModel sfdModel = new SuggestionsFilterDataModel(parser, currentContext,
                    this.possibleTokens);
            this.setSuggestionsFilterDataModel(sfdModel);
        }

    }

    /**
     * Checks whether cursor is within the whitespace region between current token to last token
     * @param token Token to be evaluated
     * @param parser Parser Instance
     * @return true|false
     */
    protected boolean isCursorBetweenGivenTokenAndLastNonHiddenToken(Token token, Parser parser) {
        boolean isCursorBetween = false;
        if (cursorPosition.equals(getSourcePosition(token))) {
            isCursorBetween = true;
        } else {
            Token lastNonHiddenToken = null;
            for (int tokenIdx = token.getTokenIndex() - 1; tokenIdx >= 0; tokenIdx--) {
                Token lastToken = parser.getTokenStream().get(tokenIdx);
                if (lastToken.getChannel() != Token.HIDDEN_CHANNEL) {
                    lastNonHiddenToken = lastToken;
                    break;
                }
            }
            if (lastNonHiddenToken != null) {
                if (cursorPosition.getLine() >= lastNonHiddenToken.getLine()
                        && cursorPosition.getLine() <= token.getLine()) {
                    if (cursorPosition.getLine() == lastNonHiddenToken.getLine()) {
                        isCursorBetween = cursorPosition
                                .getCharacter() >= (lastNonHiddenToken.getCharPositionInLine()
                                        + lastNonHiddenToken.getText().length());
                    } else if (cursorPosition.getLine() == token.getLine()) {
                        isCursorBetween = cursorPosition.getCharacter() <= token.getCharPositionInLine();
                    } else {
                        isCursorBetween = true;
                    }
                }
            }

        }
        return isCursorBetween;
    }

    protected Position getSourcePosition(Token token) {
        Position position = new Position();
        position.setLine(token.getLine());
        position.setCharacter(token.getCharPositionInLine());
        return position;
    }

    /**
     * Get the SuggestionsFilterDataModel
     * @return {@link SuggestionsFilterDataModel}
     */
    public SuggestionsFilterDataModel getSuggestionsFilterDataModel() {
        if (this.suggestionsFilterDataModel == null) {
            this.suggestionsFilterDataModel = new SuggestionsFilterDataModel(null, null, null);
        }
        return suggestionsFilterDataModel;
    }

    /**
     * Set the SuggestionsFilterDataModel
     * @param suggestionsFilterDataModel - suggestions filter data model
     */
    public void setSuggestionsFilterDataModel(SuggestionsFilterDataModel suggestionsFilterDataModel) {
        this.suggestionsFilterDataModel = suggestionsFilterDataModel;
    }
}