Search in sources :

Example 11 with IStrategoAppl

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

the class JSGLRCompletionService method findPlaceholderTerms.

private Collection<IStrategoTerm> findPlaceholderTerms(IStrategoTerm ast) {
    final Collection<IStrategoTerm> placeholderTerms = Lists.newLinkedList();
    final IStrategoTermVisitor visitor = new AStrategoTermVisitor() {

        @Override
        public boolean visit(IStrategoTerm term) {
            if (term instanceof IStrategoAppl) {
                IStrategoAppl appl = (IStrategoAppl) term;
                if (appl.getConstructor().getName().contains("-Plhdr") && appl.getSubtermCount() > 0) {
                    placeholderTerms.add(appl);
                    return false;
                }
            }
            return true;
        }
    };
    StrategoTermVisitee.topdown(visitor, ast);
    return placeholderTerms;
}
Also used : IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) AStrategoTermVisitor(org.spoofax.terms.visitor.AStrategoTermVisitor) IStrategoAppl(org.spoofax.interpreter.terms.IStrategoAppl) IStrategoTermVisitor(org.spoofax.terms.visitor.IStrategoTermVisitor)

Example 12 with IStrategoAppl

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

the class JSGLRCompletionService method placeholderCompletions.

public Collection<ICompletion> placeholderCompletions(IStrategoAppl placeholder, String languageName, ILanguageComponent component, FileObject location) throws MetaborgException {
    Collection<ICompletion> completions = Lists.newLinkedList();
    // call Stratego part of the framework to compute change
    final HybridInterpreter runtime = strategoRuntimeService.runtime(component, location, false);
    final ITermFactory termFactory = termFactoryService.get(component, null, false);
    IStrategoTerm placeholderParent = ParentAttachment.getParent(placeholder);
    if (placeholderParent == null) {
        placeholderParent = placeholder;
    }
    IStrategoInt placeholderIdx = termFactory.makeInt(-1);
    for (int i = 0; i < placeholderParent.getSubtermCount(); i++) {
        if (placeholderParent.getSubterm(i) == placeholder) {
            placeholderIdx = termFactory.makeInt(i);
        }
    }
    final String sort = ImploderAttachment.getSort(placeholder);
    final IStrategoTerm strategoInput = termFactory.makeTuple(termFactory.makeString(sort), placeholder, placeholderParent, placeholderIdx);
    final IStrategoTerm proposalsPlaceholder = strategoCommon.invoke(runtime, strategoInput, "get-proposals-placeholder-" + languageName);
    if (proposalsPlaceholder == null) {
        logger.error("Getting proposals for {} failed", placeholder);
        return completions;
    }
    for (IStrategoTerm proposalTerm : proposalsPlaceholder) {
        if (!(proposalTerm instanceof IStrategoTuple)) {
            logger.error("Unexpected proposal term {}, skipping", proposalTerm);
            continue;
        }
        final IStrategoTuple tuple = (IStrategoTuple) proposalTerm;
        if (tuple.getSubtermCount() != 4 || !(tuple.getSubterm(0) instanceof IStrategoString) || !(tuple.getSubterm(1) instanceof IStrategoString) || !(tuple.getSubterm(2) instanceof IStrategoString) || !(tuple.getSubterm(3) instanceof IStrategoAppl)) {
            logger.error("Unexpected proposal term {}, skipping", proposalTerm);
            continue;
        }
        final String name = Tools.asJavaString(tuple.getSubterm(0));
        final String text = Tools.asJavaString(tuple.getSubterm(1));
        final String additionalInfo = Tools.asJavaString(tuple.getSubterm(2));
        final StrategoAppl change = (StrategoAppl) tuple.getSubterm(3);
        if (change.getConstructor().getName().contains("REPLACE_TERM")) {
            final ICompletion completion = createCompletionReplaceTerm(name, text, additionalInfo, change, false, "", "");
            if (completion == null) {
                logger.error("Unexpected proposal term {}, skipping", proposalTerm);
                continue;
            }
            completions.add(completion);
        }
    }
    return completions;
}
Also used : IStrategoInt(org.spoofax.interpreter.terms.IStrategoInt) ICompletion(org.metaborg.core.completion.ICompletion) IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) HybridInterpreter(org.strategoxt.HybridInterpreter) IStrategoAppl(org.spoofax.interpreter.terms.IStrategoAppl) IStrategoTuple(org.spoofax.interpreter.terms.IStrategoTuple) IStrategoString(org.spoofax.interpreter.terms.IStrategoString) IStrategoString(org.spoofax.interpreter.terms.IStrategoString) ITermFactory(org.spoofax.interpreter.terms.ITermFactory) IStrategoAppl(org.spoofax.interpreter.terms.IStrategoAppl) StrategoAppl(org.spoofax.terms.StrategoAppl)

Example 13 with IStrategoAppl

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

the class JSGLRCompletionService method createCompletionInsertionTermFixing.

private ICompletion createCompletionInsertionTermFixing(String name, String text, String additionalInfo, String prefix, String suffix, StrategoAppl change, String completionKind) {
    final StrategoTerm newNode = (StrategoTerm) change.getSubterm(0);
    if (change.getSubtermCount() != 1 || !(newNode instanceof IStrategoAppl)) {
        return null;
    }
    final String sort = ImploderAttachment.getSort(newNode);
    int insertionPoint, suffixPoint;
    ITokens tokenizer = ImploderAttachment.getTokenizer(newNode);
    final StrategoTerm topMostAmb = findTopMostAmbNode(newNode);
    final ImploderAttachment topMostAmbIA = topMostAmb.getAttachment(ImploderAttachment.TYPE);
    // get the last non-layout token before the topmost ambiguity
    int tokenPosition = topMostAmbIA.getLeftToken().getIndex() - 1 > 0 ? topMostAmbIA.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();
    if (topMostAmbIA.getRightToken().getEndOffset() < topMostAmbIA.getRightToken().getStartOffset()) {
        // keep all the characters after the last non-layout token if completion ends with a
        // placeholder
        tokenPosition = topMostAmbIA.getRightToken().getIndex();
        while (tokenPosition > 0 && (tokenizer.getTokenAt(tokenPosition).getEndOffset() < tokenizer.getTokenAt(tokenPosition).getStartOffset() || tokenizer.getTokenAt(tokenPosition).getKind() == IToken.TK_LAYOUT)) tokenPosition--;
        suffixPoint = tokenizer.getTokenAt(tokenPosition).getEndOffset() + 1;
    } else {
        // skip all the (erroneous) characters that were in the text already
        suffixPoint = topMostAmbIA.getRightToken().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) 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 IStrategoAppl

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

the class JSGLRCompletionService method createCompletionReplaceTerm.

private ICompletion createCompletionReplaceTerm(String name, String text, String additionalInfo, StrategoAppl change, boolean blankLineCompletion, String prefix, String suffix) {
    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 (tokenPosition > 0 && (tokenizer.getTokenAt(tokenPosition).getKind() == IToken.TK_LAYOUT || tokenizer.getTokenAt(tokenPosition).getKind() == IToken.TK_ERROR)) tokenPosition--;
        insertionPoint = tokenizer.getTokenAt(tokenPosition).getEndOffset();
        // if completion does not spam multiple lines preserve everything starting at the first non-layout char
        if (!additionalInfo.contains("\n")) {
            tokenPosition = oldNodeIA.getLeftToken().getIndex() + 1 < tokenizer.getTokenCount() ? oldNodeIA.getLeftToken().getIndex() + 1 : tokenizer.getTokenCount() - 1;
            while (tokenPosition < tokenizer.getTokenCount() && (tokenizer.getTokenAt(tokenPosition).getKind() == IToken.TK_LAYOUT || tokenizer.getTokenAt(tokenPosition).getKind() == IToken.TK_ERROR)) tokenPosition++;
            suffixPoint = tokenizer.getTokenAt(tokenPosition).getStartOffset();
        } else {
            // if completion spams multiple lines keep the lines
            suffixPoint = insertionPoint + 1;
        }
        // if completion is triggered in an empty line, consume that line
        IToken checkToken;
        boolean blankLine = false;
        if (blankLineCompletion) {
            for (; tokenPosition < tokenizer.getTokenCount(); tokenPosition++) {
                checkToken = tokenizer.getTokenAt(tokenPosition);
                if (tokenizer.toString(checkToken, checkToken).contains("\n")) {
                    suffixPoint = checkToken.getEndOffset();
                    if (!blankLine) {
                        blankLine = true;
                    } else {
                        break;
                    }
                }
            }
        }
    } else {
        // if not, do a regular replacement
        insertionPoint = oldNodeIA.getLeftToken().getStartOffset() - 1;
        suffixPoint = oldNodeIA.getRightToken().getEndOffset() + 1;
    }
    CompletionKind kind;
    if (prefix.equals("") && suffix.equals("")) {
        kind = CompletionKind.expansion;
    } else {
        kind = CompletionKind.expansionEditing;
    }
    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) IToken(org.spoofax.jsglr.client.imploder.IToken) 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 15 with IStrategoAppl

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

the class JSGLRCompletionService method completionCorrectPrograms.

public Collection<ICompletion> completionCorrectPrograms(int position, boolean blankLineCompletion, ISpoofaxParseUnit parseResult) throws MetaborgException {
    Collection<ICompletion> completions = Sets.newHashSet();
    final FileObject location = parseResult.source();
    final ILanguageImpl language = parseResult.input().langImpl();
    final String languageName = language.belongsTo().name();
    for (ILanguageComponent component : language.components()) {
        final HybridInterpreter runtime = strategoRuntimeService.runtime(component, location, false);
        final ITermFactory termFactory = termFactoryService.get(component, null, false);
        final Map<IStrategoTerm, Boolean> leftRecursiveTerms = new HashMap<IStrategoTerm, Boolean>();
        final Map<IStrategoTerm, Boolean> rightRecursiveTerms = new HashMap<IStrategoTerm, Boolean>();
        final Iterable<IStrategoTerm> terms = tracingTermsCompletions(position, parseResult.ast(), new SourceRegion(position), runtime, termFactory, languageName, leftRecursiveTerms, rightRecursiveTerms);
        final IStrategoAppl placeholder = getPlaceholder(position, terms);
        final Iterable<IStrategoList> lists = getLists(terms, leftRecursiveTerms, rightRecursiveTerms);
        final Iterable<IStrategoTerm> optionals = getOptionals(terms, leftRecursiveTerms, rightRecursiveTerms);
        final Iterable<IStrategoTerm> leftRecursive = getLeftRecursiveTerms(position, terms, leftRecursiveTerms);
        final Iterable<IStrategoTerm> rightRecursive = getRightRecursiveTerms(position, terms, rightRecursiveTerms);
        if (placeholder != null) {
            completions.addAll(placeholderCompletions(placeholder, languageName, component, location));
        } else {
            if (Iterables.size(lists) != 0) {
                completions.addAll(listsCompletions(position, blankLineCompletion, lists, languageName, component, location));
            }
            if (Iterables.size(optionals) != 0) {
                completions.addAll(optionalCompletions(optionals, blankLineCompletion, languageName, component, location));
            }
        // TODO Improve recursive completions
        // if(Iterables.size(leftRecursive) != 0 || Iterables.size(rightRecursive) != 0) {
        // completions
        // .addAll(recursiveCompletions(leftRecursive, rightRecursive, languageName, component, location));
        // }
        }
    }
    return completions;
}
Also used : ICompletion(org.metaborg.core.completion.ICompletion) IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) HashMap(java.util.HashMap) HybridInterpreter(org.strategoxt.HybridInterpreter) IStrategoAppl(org.spoofax.interpreter.terms.IStrategoAppl) IStrategoList(org.spoofax.interpreter.terms.IStrategoList) IStrategoString(org.spoofax.interpreter.terms.IStrategoString) SourceRegion(org.metaborg.core.source.SourceRegion) ISourceRegion(org.metaborg.core.source.ISourceRegion) ILanguageImpl(org.metaborg.core.language.ILanguageImpl) FileObject(org.apache.commons.vfs2.FileObject) ILanguageComponent(org.metaborg.core.language.ILanguageComponent) ITermFactory(org.spoofax.interpreter.terms.ITermFactory)

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