Search in sources :

Example 31 with IStrategoAppl

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

the class JSGLRCompletionService method createCompletionReplaceTermFixing.

private ICompletion createCompletionReplaceTermFixing(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);
    if (change.getSubtermCount() != 2 || !(newNode instanceof IStrategoAppl) || !(oldNode instanceof IStrategoAppl)) {
        return null;
    }
    final String sort = ImploderAttachment.getSort(oldNode);
    int insertionPoint, suffixPoint;
    final ImploderAttachment oldNodeIA = oldNode.getAttachment(ImploderAttachment.TYPE);
    ITokens tokenizer = ImploderAttachment.getTokenizer(oldNode);
    // check if it's an empty node
    if (oldNodeIA.getLeftToken().getStartOffset() > oldNodeIA.getRightToken().getEndOffset()) {
        // get the last non-layout token before the new node
        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 not, do a regular replacement
        insertionPoint = oldNodeIA.getLeftToken().getStartOffset() - 1;
    }
    // insert after the first non-layout token
    int tokenPositionEnd = oldNodeIA.getRightToken().getIndex();
    while ((tokenizer.getTokenAt(tokenPositionEnd).getEndOffset() < tokenizer.getTokenAt(tokenPositionEnd).getStartOffset() || tokenizer.getTokenAt(tokenPositionEnd).getKind() == IToken.TK_LAYOUT || tokenizer.getTokenAt(tokenPositionEnd).getKind() == IToken.TK_ERROR) && tokenPositionEnd > 0) tokenPositionEnd--;
    suffixPoint = tokenizer.getTokenAt(tokenPositionEnd).getEndOffset() + 1;
    CompletionKind kind;
    if (completionKind.equals("recovery")) {
        kind = CompletionKind.recovery;
    } 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) 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 32 with IStrategoAppl

use of org.spoofax.interpreter.terms.IStrategoAppl 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 33 with IStrategoAppl

use of org.spoofax.interpreter.terms.IStrategoAppl 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 34 with IStrategoAppl

use of org.spoofax.interpreter.terms.IStrategoAppl 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)

Example 35 with IStrategoAppl

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

the class ResolverFacetFromESV method createHover.

@Nullable
public static HoverFacet createHover(IStrategoAppl esv) {
    final IStrategoAppl hover = ESVReader.findTerm(esv, "HoverRule");
    if (hover == null) {
        return null;
    }
    final String strategyName = ESVReader.termContents(termAt(hover, 1));
    if (strategyName == null) {
        logger.error("Could not get contents of ESV HoverRule {}, cannot create hover facet", hover);
        return null;
    }
    return new HoverFacet(strategyName);
}
Also used : IStrategoAppl(org.spoofax.interpreter.terms.IStrategoAppl) Nullable(javax.annotation.Nullable)

Aggregations

IStrategoAppl (org.spoofax.interpreter.terms.IStrategoAppl)42 IStrategoTerm (org.spoofax.interpreter.terms.IStrategoTerm)26 IStrategoString (org.spoofax.interpreter.terms.IStrategoString)21 ICompletion (org.metaborg.core.completion.ICompletion)13 Nullable (javax.annotation.Nullable)12 IStrategoList (org.spoofax.interpreter.terms.IStrategoList)9 ITermFactory (org.spoofax.interpreter.terms.ITermFactory)8 ListImploderAttachment (org.spoofax.jsglr.client.imploder.ListImploderAttachment)8 Completion (org.metaborg.core.completion.Completion)7 ITokens (org.spoofax.jsglr.client.imploder.ITokens)7 ImploderAttachment (org.spoofax.jsglr.client.imploder.ImploderAttachment)7 StrategoTerm (org.spoofax.terms.StrategoTerm)7 HybridInterpreter (org.strategoxt.HybridInterpreter)7 FileObject (org.apache.commons.vfs2.FileObject)6 MetaborgException (org.metaborg.core.MetaborgException)6 IStrategoTuple (org.spoofax.interpreter.terms.IStrategoTuple)6 CompletionKind (org.metaborg.core.completion.CompletionKind)5 StrategoAppl (org.spoofax.terms.StrategoAppl)5 IToken (org.spoofax.jsglr.client.imploder.IToken)4 ISourceRegion (org.metaborg.core.source.ISourceRegion)3