Search in sources :

Example 6 with IStrategoList

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

the class JSGLRCompletionService method getLeftRecursiveTerms.

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

Example 7 with IStrategoList

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

the class JSGLRCompletionService method getOptionals.

@Nullable
private Iterable<IStrategoTerm> getOptionals(final Iterable<IStrategoTerm> terms, Map<IStrategoTerm, Boolean> leftRecursiveTerms, Map<IStrategoTerm, Boolean> rightRecursiveTerms) {
    Collection<IStrategoTerm> optionals = Lists.newLinkedList();
    for (IStrategoTerm term : terms) {
        IToken left = ImploderAttachment.getLeftToken(term);
        IToken right = ImploderAttachment.getRightToken(term);
        if (!(term instanceof IStrategoList) && left.getStartOffset() > right.getEndOffset()) {
            optionals.add(term);
        } else if (term instanceof IStrategoList) {
            continue;
        // if term is not nullable, nor a list nor left or right recursive stop the search
        } else {
            boolean isLeftRecursive = leftRecursiveTerms.containsKey(term);
            boolean isRightRecursive = rightRecursiveTerms.containsKey(term);
            if (!isLeftRecursive && !isRightRecursive) {
                break;
            }
        }
    }
    return optionals;
}
Also used : IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) IToken(org.spoofax.jsglr.client.imploder.IToken) IStrategoList(org.spoofax.interpreter.terms.IStrategoList) Nullable(javax.annotation.Nullable)

Example 8 with IStrategoList

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

Example 9 with IStrategoList

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

the class JSGLRCompletionService method fromTokens.

// TODO: Do these strategies need to be specific for a language
@Nullable
protected ISourceLocation fromTokens(IStrategoTerm fragment, HybridInterpreter runtime, ITermFactory termFactory, int position, String languageName, Map<IStrategoTerm, Boolean> leftRecursiveTerms, Map<IStrategoTerm, Boolean> rightRecursiveTerms) {
    final FileObject resource = SourceAttachment.getResource(fragment, resourceService);
    final IToken left = ImploderAttachment.getLeftToken(fragment);
    final IToken right = ImploderAttachment.getRightToken(fragment);
    ITokens tokenizer = ImploderAttachment.getTokenizer(fragment);
    IToken leftmostValid = left;
    IToken rightmostValid = right;
    boolean isList = (fragment instanceof IStrategoList) ? true : false;
    boolean isOptional = false;
    String sort = ImploderAttachment.getSort(fragment);
    IStrategoTerm input = termFactory.makeString(sort);
    boolean isLeftRecursive = false;
    if (fragment instanceof IStrategoAppl && position > right.getEndOffset()) {
        try {
            isLeftRecursive = strategoCommon.invoke(runtime, input, "is-left-recursive") != null;
        } catch (MetaborgException e) {
            logger.error("Failed to check recursivity for term {} of sort {} - syntactic completion not activated for this language, please import the completion stratego library", fragment, sort);
        }
    }
    boolean isRightRecursive = false;
    if (fragment instanceof IStrategoAppl && position <= left.getStartOffset()) {
        try {
            isRightRecursive = strategoCommon.invoke(runtime, input, "is-right-recursive") != null;
        } catch (MetaborgException e) {
            logger.error("Failed to check recursivity for term {} of sort {} - syntactic completion not activated for this language, please import the completion stratego library", fragment, sort);
        }
    }
    if (isLeftRecursive) {
        leftRecursiveTerms.put(fragment, true);
    }
    if (isRightRecursive) {
        rightRecursiveTerms.put(fragment, true);
    }
    if (left == null || right == null) {
        return null;
    }
    if (!isList && left == right && left.getEndOffset() < left.getStartOffset()) {
        isOptional = true;
    }
    // if it's a list or a node that is empty make the element includes the surrounding layout tokens
    if (left.getStartOffset() > right.getEndOffset() || isList || isOptional || (isLeftRecursive && isRightRecursive)) {
        for (int i = left.getIndex() - 1; i >= 0; i--) {
            if (tokenizer.getTokenAt(i).getKind() == IToken.TK_LAYOUT || tokenizer.getTokenAt(i).getKind() == IToken.TK_ERROR) {
                leftmostValid = tokenizer.getTokenAt(i);
            } else {
                break;
            }
        }
        for (int i = right.getIndex() + 1; i < tokenizer.getTokenCount(); i++) {
            if (tokenizer.getTokenAt(i).getKind() == IToken.TK_LAYOUT || tokenizer.getTokenAt(i).getKind() == IToken.TK_EOF || tokenizer.getTokenAt(i).getKind() == IToken.TK_ERROR) {
                rightmostValid = tokenizer.getTokenAt(i);
            } else {
                break;
            }
        }
    // if it is left recursive include the layout only on the right
    } else if (isLeftRecursive) {
        for (int i = left.getIndex(); i < right.getIndex(); i++) {
            if (tokenizer.getTokenAt(i).getKind() == IToken.TK_LAYOUT || tokenizer.getTokenAt(i).getKind() == IToken.TK_ERROR) {
                leftmostValid = tokenizer.getTokenAt(i + 1);
            } else {
                break;
            }
        }
        for (int i = right.getIndex() + 1; i < tokenizer.getTokenCount(); i++) {
            if (tokenizer.getTokenAt(i).getKind() == IToken.TK_LAYOUT || tokenizer.getTokenAt(i).getKind() == IToken.TK_EOF || tokenizer.getTokenAt(i).getKind() == IToken.TK_ERROR) {
                rightmostValid = tokenizer.getTokenAt(i);
            } else {
                break;
            }
        }
    // if it is right recursive include the layout only on the left
    } else if (isRightRecursive) {
        for (int i = left.getIndex() - 1; i >= 0; i--) {
            if (tokenizer.getTokenAt(i).getKind() == IToken.TK_LAYOUT || tokenizer.getTokenAt(i).getKind() == IToken.TK_ERROR) {
                leftmostValid = tokenizer.getTokenAt(i);
            } else {
                break;
            }
        }
        for (int i = right.getIndex(); i > left.getIndex(); i--) {
            if (tokenizer.getTokenAt(i).getKind() == IToken.TK_LAYOUT || tokenizer.getTokenAt(i).getKind() == IToken.TK_EOF || tokenizer.getTokenAt(i).getKind() == IToken.TK_ERROR) {
                rightmostValid = tokenizer.getTokenAt(i - 1);
            } else {
                break;
            }
        }
    } else // if not make it stripes the surrounding layout tokens
    {
        for (int i = left.getIndex(); i < right.getIndex(); i++) {
            if (tokenizer.getTokenAt(i).getKind() == IToken.TK_LAYOUT || tokenizer.getTokenAt(i).getKind() == IToken.TK_ERROR) {
                leftmostValid = tokenizer.getTokenAt(i + 1);
            } else {
                break;
            }
        }
        for (int i = right.getIndex(); i > left.getIndex(); i--) {
            if (tokenizer.getTokenAt(i).getKind() == IToken.TK_LAYOUT || tokenizer.getTokenAt(i).getKind() == IToken.TK_EOF || tokenizer.getTokenAt(i).getKind() == IToken.TK_ERROR) {
                rightmostValid = tokenizer.getTokenAt(i - 1);
            } else {
                break;
            }
        }
    }
    final ISourceRegion region = JSGLRSourceRegionFactory.fromTokensLayout(leftmostValid, rightmostValid, (isOptional || isList || isLeftRecursive || isRightRecursive));
    return new SourceLocation(region, resource);
}
Also used : SourceLocation(org.metaborg.core.source.SourceLocation) ISourceLocation(org.metaborg.core.source.ISourceLocation) IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) IToken(org.spoofax.jsglr.client.imploder.IToken) MetaborgException(org.metaborg.core.MetaborgException) ISourceRegion(org.metaborg.core.source.ISourceRegion) IStrategoAppl(org.spoofax.interpreter.terms.IStrategoAppl) IStrategoList(org.spoofax.interpreter.terms.IStrategoList) FileObject(org.apache.commons.vfs2.FileObject) IStrategoString(org.spoofax.interpreter.terms.IStrategoString) ITokens(org.spoofax.jsglr.client.imploder.ITokens) Nullable(javax.annotation.Nullable)

Example 10 with IStrategoList

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

the class JSGLRCompletionService method getLists.

@Nullable
private Iterable<IStrategoList> getLists(final Iterable<IStrategoTerm> terms, Map<IStrategoTerm, Boolean> leftRecursiveTerms, Map<IStrategoTerm, Boolean> rightRecursiveTerms) {
    Collection<IStrategoList> lists = Lists.newLinkedList();
    for (IStrategoTerm term : terms) {
        if (term instanceof IStrategoList) {
            final IStrategoList list = (IStrategoList) term;
            lists.add(list);
        } else {
            IToken left = ImploderAttachment.getLeftToken(term);
            IToken right = ImploderAttachment.getRightToken(term);
            // if term is not nullable, nor a list nor left or right recursive stop the search
            if (left.getStartOffset() <= right.getEndOffset()) {
                boolean isLeftRecursive = leftRecursiveTerms.containsKey(term);
                boolean isRightRecursive = rightRecursiveTerms.containsKey(term);
                if (!isLeftRecursive && !isRightRecursive) {
                    break;
                }
            }
        }
    }
    return lists;
}
Also used : IStrategoTerm(org.spoofax.interpreter.terms.IStrategoTerm) IToken(org.spoofax.jsglr.client.imploder.IToken) IStrategoList(org.spoofax.interpreter.terms.IStrategoList) Nullable(javax.annotation.Nullable)

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