Search in sources :

Example 11 with IStrategoList

use of org.spoofax.interpreter.terms.IStrategoList in project spoofax by metaborg.

the class JSGLRCompletionService method createCompletionInsertBefore.

private ICompletion createCompletionInsertBefore(String name, String text, String additionalInfo, StrategoAppl change) {
    final StrategoTerm oldNode = (StrategoTerm) change.getSubterm(0);
    final StrategoTerm newNode = (StrategoTerm) change.getSubterm(1);
    // expect two terms and 1st should be an element of a list
    final StrategoTerm oldList = (StrategoTerm) ParentAttachment.getParent(oldNode);
    if (change.getSubtermCount() != 2 || !(oldNode instanceof IStrategoAppl) || !(newNode instanceof IStrategoList) || !(oldList instanceof IStrategoList)) {
        return null;
    }
    final String sort = ImploderAttachment.getSort(oldNode);
    int insertionPoint, suffixPoint;
    ITokens tokenizer = ImploderAttachment.getTokenizer(oldNode);
    IStrategoTerm[] subterms = oldList.getAllSubterms();
    int indexOfElement;
    for (indexOfElement = 0; indexOfElement < subterms.length; indexOfElement++) {
        if (subterms[indexOfElement] == oldNode)
            break;
    }
    // if inserted element is first (only two elements)
    if (indexOfElement == 0) {
        // insert after the first non-layout token before the leftmost token of the
        // completion node
        final ImploderAttachment oldNodeIA = oldNode.getAttachment(ImploderAttachment.TYPE);
        int tokenPosition = oldNodeIA.getLeftToken().getIndex() - 1 > 0 ? oldNodeIA.getLeftToken().getIndex() - 1 : 0;
        while ((tokenizer.getTokenAt(tokenPosition).getKind() == IToken.TK_LAYOUT || tokenizer.getTokenAt(tokenPosition).getKind() == IToken.TK_ERROR) && tokenPosition > 0) tokenPosition--;
        insertionPoint = tokenizer.getTokenAt(tokenPosition).getEndOffset();
    } else {
        // if inserted element is not first
        // insert after at end offset of the rightmost token of the element before the
        // completion
        StrategoTerm elementBefore = (StrategoTerm) oldList.getSubterm(indexOfElement - 1);
        insertionPoint = elementBefore.getAttachment(ImploderAttachment.TYPE).getRightToken().getEndOffset();
    }
    // if completion is separated by a newline, preserve indentation of the subsequent node
    // else separation follows from the grammar
    String separator = "";
    for (int i = text.length() - 1; i >= 0; i--) {
        if (text.charAt(i) == additionalInfo.charAt(additionalInfo.length() - 1)) {
            break;
        }
        separator = text.charAt(i) + separator;
    }
    IToken checkToken = oldNode.getAttachment(ImploderAttachment.TYPE).getLeftToken();
    int checkTokenIdx = oldNode.getAttachment(ImploderAttachment.TYPE).getLeftToken().getIndex();
    suffixPoint = insertionPoint;
    if (separator.contains("\n")) {
        for (; checkTokenIdx >= 0; checkTokenIdx--) {
            checkToken = tokenizer.getTokenAt(checkTokenIdx);
            if (tokenizer.toString(checkToken, checkToken).contains("\n")) {
                break;
            }
            suffixPoint = checkToken.getStartOffset();
        }
    } else {
        suffixPoint = checkToken.getStartOffset();
    }
    return new Completion(name, sort, text, additionalInfo, insertionPoint + 1, suffixPoint, CompletionKind.expansion);
}
Also used : IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) ICompletion(org.metaborg.core.completion.ICompletion) Completion(org.metaborg.core.completion.Completion) IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) StrategoTerm(org.spoofax.terms.StrategoTerm) IToken(org.spoofax.jsglr.client.imploder.IToken) IStrategoAppl(org.spoofax.interpreter.terms.IStrategoAppl) IStrategoList(org.spoofax.interpreter.terms.IStrategoList) IStrategoString(org.spoofax.interpreter.terms.IStrategoString) ImploderAttachment(org.spoofax.jsglr.client.imploder.ImploderAttachment) ListImploderAttachment(org.spoofax.jsglr.client.imploder.ListImploderAttachment) ITokens(org.spoofax.jsglr.client.imploder.ITokens)

Example 12 with IStrategoList

use of org.spoofax.interpreter.terms.IStrategoList in project spoofax by metaborg.

the class JSGLRCompletionService method getRightRecursiveTerms.

private Iterable<IStrategoTerm> getRightRecursiveTerms(int position, Iterable<IStrategoTerm> terms, Map<IStrategoTerm, Boolean> rightRecursiveTerms) {
    Collection<IStrategoTerm> rightRecursive = Lists.newLinkedList();
    for (IStrategoTerm term : terms) {
        boolean isRightRecursive = rightRecursiveTerms.containsKey(term);
        IToken left = ImploderAttachment.getLeftToken(term);
        IToken right = ImploderAttachment.getRightToken(term);
        if (isRightRecursive && position <= left.getStartOffset()) {
            rightRecursive.add(term);
        } else if (term instanceof IStrategoList || left.getStartOffset() > right.getEndOffset()) {
            continue;
        } else {
            break;
        }
    }
    return rightRecursive;
}
Also used : IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) IToken(org.spoofax.jsglr.client.imploder.IToken) IStrategoList(org.spoofax.interpreter.terms.IStrategoList)

Example 13 with IStrategoList

use of org.spoofax.interpreter.terms.IStrategoList in project spoofax by metaborg.

the class JSGLRCompletionService method createCompletionInsertBeforeFixing.

private ICompletion createCompletionInsertBeforeFixing(String name, String text, String additionalInfo, String prefix, String suffix, StrategoAppl change, String completionKind) {
    // expect two terms and 1st should be an element of a list
    final StrategoTerm oldNode = (StrategoTerm) change.getSubterm(0);
    final StrategoTerm newNode = (StrategoTerm) change.getSubterm(1);
    final StrategoTerm oldList = (StrategoTerm) ParentAttachment.getParent(oldNode);
    if (change.getSubtermCount() != 2 || !(oldNode instanceof IStrategoAppl) || !(newNode instanceof IStrategoAppl) || !(oldList instanceof IStrategoList)) {
        return null;
    }
    final String sort = ImploderAttachment.getSort(oldNode);
    int insertionPoint, suffixPoint;
    IStrategoTerm[] subterms = ((IStrategoList) oldList).getAllSubterms();
    int indexOfCompletion;
    for (indexOfCompletion = 0; indexOfCompletion < subterms.length; indexOfCompletion++) {
        if (subterms[indexOfCompletion] == oldNode)
            break;
    }
    // if inserted element is first (only two elements)
    if (indexOfCompletion == 1) {
        // insert after the first non-layout token before the leftmost token of the list
        ITokens tokenizer = ImploderAttachment.getTokenizer(oldList);
        // to avoid keeping duplicate tokens due to ambiguity
        IStrategoTerm topMostAmbOldList = findTopMostAmbNode(oldList);
        final ImploderAttachment oldListIA = topMostAmbOldList.getAttachment(ImploderAttachment.TYPE);
        int tokenPosition = oldListIA.getLeftToken().getIndex() - 1 > 0 ? oldListIA.getLeftToken().getIndex() - 1 : 0;
        while ((checkEmptyOffset(tokenizer.getTokenAt(tokenPosition)) || tokenizer.getTokenAt(tokenPosition).getKind() == IToken.TK_LAYOUT || tokenizer.getTokenAt(tokenPosition).getKind() == IToken.TK_ERROR) && tokenPosition > 0) tokenPosition--;
        insertionPoint = tokenizer.getTokenAt(tokenPosition).getEndOffset();
    } else {
        // if inserted element is not first
        // insert after at end offset of the rightmost token of the element before the completion
        StrategoTerm elementBefore = (StrategoTerm) oldList.getSubterm(indexOfCompletion - 2);
        insertionPoint = elementBefore.getAttachment(ImploderAttachment.TYPE).getRightToken().getEndOffset();
    }
    // suffix point should be the first token of the next element
    suffixPoint = oldNode.getAttachment(ImploderAttachment.TYPE).getLeftToken().getStartOffset();
    CompletionKind kind;
    if (completionKind.equals("recovery")) {
        kind = CompletionKind.recovery;
    } else if (completionKind.equals("expansionEditing")) {
        kind = CompletionKind.expansionEditing;
    } else {
        kind = CompletionKind.expansion;
    }
    return new Completion(name, sort, text, additionalInfo, insertionPoint + 1, suffixPoint, kind, prefix, suffix);
}
Also used : IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) ICompletion(org.metaborg.core.completion.ICompletion) Completion(org.metaborg.core.completion.Completion) IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) StrategoTerm(org.spoofax.terms.StrategoTerm) IStrategoAppl(org.spoofax.interpreter.terms.IStrategoAppl) IStrategoList(org.spoofax.interpreter.terms.IStrategoList) IStrategoString(org.spoofax.interpreter.terms.IStrategoString) ImploderAttachment(org.spoofax.jsglr.client.imploder.ImploderAttachment) ListImploderAttachment(org.spoofax.jsglr.client.imploder.ListImploderAttachment) CompletionKind(org.metaborg.core.completion.CompletionKind) ITokens(org.spoofax.jsglr.client.imploder.ITokens)

Example 14 with IStrategoList

use of org.spoofax.interpreter.terms.IStrategoList in project spoofax by metaborg.

the class JSGLRCompletionService method createCompletionInsertAtEndFixing.

private ICompletion createCompletionInsertAtEndFixing(String name, String text, String additionalInfo, String prefix, String suffix, StrategoAppl change, String completionKind) {
    final StrategoTerm oldNode = (StrategoTerm) change.getSubterm(0);
    final StrategoTerm newNode = (StrategoTerm) change.getSubterm(1);
    final StrategoTerm oldNodeTopMostAmb = findTopMostAmbNode(oldNode);
    if (change.getSubtermCount() != 2 || !(oldNode instanceof IStrategoList) || !(newNode instanceof IStrategoAppl)) {
        return null;
    }
    final String sort = ImploderAttachment.getElementSort(oldNode);
    int insertionPoint, suffixPoint;
    ITokens tokenizer = ImploderAttachment.getTokenizer(oldNodeTopMostAmb);
    final ImploderAttachment oldNodeIA = oldNodeTopMostAmb.getAttachment(ImploderAttachment.TYPE);
    // insert after the first non-layout token before the leftmost token of the completion node
    if (((IStrategoList) oldNode).size() == 1) {
        int tokenPosition = oldNodeIA.getLeftToken().getIndex() - 1 > 0 ? oldNodeIA.getLeftToken().getIndex() - 1 : 0;
        while (tokenPosition > 0 && (checkEmptyOffset(tokenizer.getTokenAt(tokenPosition)) || tokenizer.getTokenAt(tokenPosition).getKind() == IToken.TK_LAYOUT || tokenizer.getTokenAt(tokenPosition).getKind() == IToken.TK_ERROR)) tokenPosition--;
        insertionPoint = tokenizer.getTokenAt(tokenPosition).getEndOffset();
    } else {
        // if list is not empty
        // insert after at end offset of the rightmost token of the element before the completion
        StrategoTerm elementBefore = (StrategoTerm) oldNode.getSubterm(oldNode.getAllSubterms().length - 2);
        insertionPoint = elementBefore.getAttachment(ImploderAttachment.TYPE).getRightToken().getEndOffset();
    }
    // keep all the characters after the last non-layout token
    int tokenPosition = oldNodeIA.getRightToken().getIndex();
    while (tokenizer.getTokenAt(tokenPosition).getEndOffset() < tokenizer.getTokenAt(tokenPosition).getStartOffset() || tokenizer.getTokenAt(tokenPosition).getKind() == IToken.TK_LAYOUT && tokenPosition > 0) tokenPosition--;
    suffixPoint = tokenizer.getTokenAt(tokenPosition).getEndOffset() + 1;
    CompletionKind kind;
    if (completionKind.equals("recovery")) {
        kind = CompletionKind.recovery;
    } else if (completionKind.equals("expansionEditing")) {
        kind = CompletionKind.expansionEditing;
    } else {
        kind = CompletionKind.expansion;
    }
    return new Completion(name, sort, text, additionalInfo, insertionPoint + 1, suffixPoint, kind, prefix, suffix);
}
Also used : ICompletion(org.metaborg.core.completion.ICompletion) Completion(org.metaborg.core.completion.Completion) IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) StrategoTerm(org.spoofax.terms.StrategoTerm) IStrategoAppl(org.spoofax.interpreter.terms.IStrategoAppl) IStrategoList(org.spoofax.interpreter.terms.IStrategoList) IStrategoString(org.spoofax.interpreter.terms.IStrategoString) ImploderAttachment(org.spoofax.jsglr.client.imploder.ImploderAttachment) ListImploderAttachment(org.spoofax.jsglr.client.imploder.ListImploderAttachment) CompletionKind(org.metaborg.core.completion.CompletionKind) ITokens(org.spoofax.jsglr.client.imploder.ITokens)

Example 15 with IStrategoList

use of org.spoofax.interpreter.terms.IStrategoList in project spoofax by metaborg.

the class JSGLRCompletionService method completionErroneousPrograms.

public Collection<ICompletion> completionErroneousPrograms(int cursorPosition, Iterable<IStrategoTerm> completionTerms, ISpoofaxParseUnit completionParseResult) throws MetaborgException {
    final FileObject location = completionParseResult.source();
    final ILanguageImpl language = completionParseResult.input().langImpl();
    final String languageName = language.belongsTo().name();
    final Collection<ICompletion> completions = Lists.newLinkedList();
    final Collection<IStrategoTerm> proposalsTerm = Lists.newLinkedList();
    for (ILanguageComponent component : language.components()) {
        final ITermFactory termFactory = termFactoryService.get(component, null, false);
        for (IStrategoTerm completionTerm : completionTerms) {
            IStrategoTerm completionAst = completionParseResult.ast();
            final StrategoTerm topMostAmb = findTopMostAmbNode((StrategoTerm) completionTerm);
            if (ImploderAttachment.get(completionTerm).isSinglePlaceholderCompletion()) {
                Collection<IStrategoTerm> placeholders = Lists.newLinkedList();
                placeholders.addAll(findPlaceholderTerms(completionTerm));
                if (placeholders.size() != 1) {
                    logger.error("Getting proposals for {} failed", completionTerm);
                    continue;
                }
                IStrategoAppl placeholderTerm = (IStrategoAppl) Iterables.get(placeholders, 0);
                IStrategoAppl placeholder = termFactory.makeAppl(termFactory.makeConstructor(placeholderTerm.getConstructor().getName(), 0));
                IStrategoTerm parenthesized = parenthesizeTerm(completionTerm, termFactory);
                final IStrategoTerm inputStratego = termFactory.makeTuple(termFactory.makeString(ImploderAttachment.getElementSort(parenthesized)), completionAst, completionTerm, topMostAmb, parenthesized, placeholder, placeholderTerm);
                final HybridInterpreter runtime = strategoRuntimeService.runtime(component, location, false);
                final IStrategoTerm proposalTerm = strategoCommon.invoke(runtime, inputStratego, "get-proposals-incorrect-programs-single-placeholder-" + languageName);
                if (proposalTerm == null || !(proposalTerm instanceof IStrategoList)) {
                    logger.error("Getting proposals for {} failed", completionTerm);
                    continue;
                }
                for (IStrategoTerm proposalPlaceholder : proposalTerm) {
                    proposalsTerm.add(proposalPlaceholder);
                }
            } else {
                IStrategoTerm parenthesized = parenthesizeTerm(completionTerm, termFactory);
                final IStrategoTerm inputStratego = termFactory.makeTuple(termFactory.makeString(ImploderAttachment.getElementSort(parenthesized)), completionAst, completionTerm, topMostAmb, parenthesized);
                final HybridInterpreter runtime = strategoRuntimeService.runtime(component, location, false);
                final IStrategoTerm proposalTerm = strategoCommon.invoke(runtime, inputStratego, "get-proposals-incorrect-programs-" + languageName);
                if (proposalTerm == null) {
                    logger.error("Getting proposals for {} failed", completionTerm);
                    continue;
                }
                proposalsTerm.add(proposalTerm);
            }
        }
        for (IStrategoTerm proposalTerm : proposalsTerm) {
            if (!(proposalTerm instanceof IStrategoTuple)) {
                logger.error("Unexpected proposal term {}, skipping", proposalTerm);
                continue;
            }
            final IStrategoTuple tuple = (IStrategoTuple) proposalTerm;
            if (tuple.getSubtermCount() != 6 || !(tuple.getSubterm(0) instanceof IStrategoString) || !(tuple.getSubterm(1) instanceof IStrategoString) || !(tuple.getSubterm(2) instanceof IStrategoString) || !(tuple.getSubterm(3) instanceof IStrategoAppl) || (tuple.getSubterm(4) == null) || !(tuple.getSubterm(5) instanceof IStrategoString)) {
                logger.error("Unexpected proposal term {}, skipping", proposalTerm);
                continue;
            }
            final String name = Tools.asJavaString(tuple.getSubterm(0));
            String text = Tools.asJavaString(tuple.getSubterm(1));
            String additionalInfo = Tools.asJavaString(tuple.getSubterm(2));
            final StrategoAppl change = (StrategoAppl) tuple.getSubterm(3);
            final StrategoTerm completionTerm = (StrategoTerm) tuple.getSubterm(4);
            final String completionKind = Tools.asJavaString(tuple.getSubterm(5));
            String prefix = calculatePrefix(cursorPosition, completionTerm);
            String suffix = calculateSuffix(cursorPosition, completionTerm);
            // if the change is inserting at the end of a list
            if (change.getConstructor().getName().contains("INSERT_AT_END")) {
                // calls a different method because now, the program has errors that should be fixed
                final ICompletion completion = createCompletionInsertAtEndFixing(name, text, additionalInfo, prefix, suffix, change, completionKind);
                if (completion == null) {
                    logger.error("Unexpected proposal term {}, skipping", proposalTerm);
                    continue;
                }
                completions.add(completion);
            } else if (change.getConstructor().getName().contains("INSERT_BEFORE")) {
                final ICompletion completion = createCompletionInsertBeforeFixing(name, text, additionalInfo, prefix, suffix, change, completionKind);
                if (completion == null) {
                    logger.error("Unexpected proposal term {}, skipping", proposalTerm);
                    continue;
                }
                completions.add(completion);
            } else if (change.getConstructor().getName().contains("INSERTION_TERM")) {
                final ICompletion completion = createCompletionInsertionTermFixing(name, text, additionalInfo, prefix, suffix, change, completionKind);
                if (completion == null) {
                    logger.error("Unexpected proposal term {}, skipping", proposalTerm);
                    continue;
                }
                completions.add(completion);
            } else if (change.getConstructor().getName().contains("REPLACE_TERM")) {
                final ICompletion completion = createCompletionReplaceTermFixing(name, text, additionalInfo, prefix, suffix, change, completionKind);
                if (completion == null) {
                    logger.error("Unexpected proposal term {}, skipping", proposalTerm);
                    continue;
                }
                completions.add(completion);
            }
        }
    }
    return completions;
}
Also used : ICompletion(org.metaborg.core.completion.ICompletion) IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) IStrategoAppl(org.spoofax.interpreter.terms.IStrategoAppl) HybridInterpreter(org.strategoxt.HybridInterpreter) IStrategoTuple(org.spoofax.interpreter.terms.IStrategoTuple) IStrategoString(org.spoofax.interpreter.terms.IStrategoString) IStrategoList(org.spoofax.interpreter.terms.IStrategoList) IStrategoString(org.spoofax.interpreter.terms.IStrategoString) IStrategoAppl(org.spoofax.interpreter.terms.IStrategoAppl) StrategoAppl(org.spoofax.terms.StrategoAppl) ILanguageImpl(org.metaborg.core.language.ILanguageImpl) IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) StrategoTerm(org.spoofax.terms.StrategoTerm) FileObject(org.apache.commons.vfs2.FileObject) ILanguageComponent(org.metaborg.core.language.ILanguageComponent) ITermFactory(org.spoofax.interpreter.terms.ITermFactory)

Aggregations

IStrategoList (org.spoofax.interpreter.terms.IStrategoList)17 IStrategoTerm (org.spoofax.interpreter.terms.IStrategoTerm)16 IStrategoString (org.spoofax.interpreter.terms.IStrategoString)12 IStrategoAppl (org.spoofax.interpreter.terms.IStrategoAppl)8 ICompletion (org.metaborg.core.completion.ICompletion)7 IToken (org.spoofax.jsglr.client.imploder.IToken)7 ITokens (org.spoofax.jsglr.client.imploder.ITokens)5 ListImploderAttachment (org.spoofax.jsglr.client.imploder.ListImploderAttachment)5 StrategoTerm (org.spoofax.terms.StrategoTerm)5 Nullable (javax.annotation.Nullable)4 FileObject (org.apache.commons.vfs2.FileObject)4 Completion (org.metaborg.core.completion.Completion)4 ILanguageComponent (org.metaborg.core.language.ILanguageComponent)4 IStrategoTuple (org.spoofax.interpreter.terms.IStrategoTuple)4 ImploderAttachment (org.spoofax.jsglr.client.imploder.ImploderAttachment)4 HybridInterpreter (org.strategoxt.HybridInterpreter)4 ITermFactory (org.spoofax.interpreter.terms.ITermFactory)3 MetaborgException (org.metaborg.core.MetaborgException)2 CompletionKind (org.metaborg.core.completion.CompletionKind)2 ILanguageImpl (org.metaborg.core.language.ILanguageImpl)2