use of org.metaborg.core.completion.ICompletion in project spoofax by metaborg.
the class JSGLRCompletionService method optionalCompletions.
public Collection<ICompletion> optionalCompletions(Iterable<IStrategoTerm> optionals, boolean blankLineCompletion, String languageName, ILanguageComponent component, FileObject location) throws MetaborgException {
Collection<ICompletion> completions = Lists.newLinkedList();
final ITermFactory termFactory = termFactoryService.get(component, null, false);
for (IStrategoTerm optional : optionals) {
ImploderAttachment attachment = optional.getAttachment(ImploderAttachment.TYPE);
String sort = attachment.getSort().substring(0, attachment.getSort().length());
String placeholderName = sort + "-Plhdr";
IStrategoAppl optionalPlaceholder = termFactory.makeAppl(termFactory.makeConstructor(placeholderName, 0));
final IStrategoTerm strategoInput = termFactory.makeTuple(termFactory.makeString(sort), optional, optionalPlaceholder);
// call Stratego part of the framework to compute change
final HybridInterpreter runtime = strategoRuntimeService.runtime(component, location, false);
final IStrategoTerm proposalsOptional = strategoCommon.invoke(runtime, strategoInput, "get-proposals-optional-" + languageName);
if (proposalsOptional == null) {
logger.error("Getting proposals for {} failed", strategoInput);
continue;
}
for (IStrategoTerm proposalTerm : proposalsOptional) {
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, blankLineCompletion, "", "");
if (completion == null) {
logger.error("Unexpected proposal term {}, skipping", proposalTerm);
continue;
}
completions.add(completion);
}
}
}
return completions;
}
use of org.metaborg.core.completion.ICompletion in project spoofax by metaborg.
the class JSGLRCompletionService method completionEmptyProgram.
public Collection<? extends ICompletion> completionEmptyProgram(Iterable<String> startSymbols, int endOffset, ILanguageImpl language, FileObject location) throws MetaborgException {
Collection<ICompletion> completions = Lists.newLinkedList();
final String languageName = language.belongsTo().name();
for (ILanguageComponent component : language.components()) {
// 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);
for (String startSymbol : startSymbols) {
String placeholderName = startSymbol + "-Plhdr";
IStrategoAppl placeholder = termFactory.makeAppl(termFactory.makeConstructor(placeholderName, 0));
IStrategoTuple input = termFactory.makeTuple(termFactory.makeString(startSymbol), placeholder);
final IStrategoTerm proposalsPlaceholder = strategoCommon.invoke(runtime, input, "get-proposals-empty-program-" + languageName);
if (proposalsPlaceholder == null) {
logger.error("Getting proposals for {} failed", placeholder);
continue;
}
for (IStrategoTerm proposalTerm : proposalsPlaceholder) {
if (!(proposalTerm instanceof IStrategoTuple)) {
logger.error("Unexpected proposal term {}, skipping", proposalTerm);
continue;
}
final IStrategoTuple tuple = (IStrategoTuple) proposalTerm;
if (tuple.getSubtermCount() != 2 || !(tuple.getSubterm(0) instanceof IStrategoString) || !(tuple.getSubterm(1) instanceof IStrategoString)) {
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(1));
completions.add(new Completion(name, startSymbol, text, additionalInfo, 0, endOffset, CompletionKind.expansion));
}
}
}
return completions;
}
use of org.metaborg.core.completion.ICompletion 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);
}
use of org.metaborg.core.completion.ICompletion 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);
}
use of org.metaborg.core.completion.ICompletion 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);
}
Aggregations