use of org.spoofax.terms.StrategoTerm in project spoofax by metaborg.
the class JSGLRCompletionService method createCompletionInsertAtEnd.
private ICompletion createCompletionInsertAtEnd(String name, String text, String additionalInfo, StrategoAppl change, boolean blankLineCompletion) {
final StrategoTerm oldNode = (StrategoTerm) change.getSubterm(0);
final StrategoTerm newNode = (StrategoTerm) change.getSubterm(1);
// expected two lists
if (change.getSubtermCount() != 2 || !(oldNode instanceof IStrategoList) || !(newNode instanceof IStrategoList)) {
return null;
}
final String sort = ImploderAttachment.getElementSort(oldNode);
int insertionPoint, suffixPoint;
ITokens tokenizer = ImploderAttachment.getTokenizer(oldNode);
final ImploderAttachment oldListIA = oldNode.getAttachment(ImploderAttachment.TYPE);
int tokenPosition;
// node
if (oldNode.getSubtermCount() == 0) {
tokenPosition = oldListIA.getLeftToken().getIndex() - 1 > 0 ? oldListIA.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 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 - 1);
int leftIdx = elementBefore.getAttachment(ImploderAttachment.TYPE).getLeftToken().getIndex();
int rightIdx = elementBefore.getAttachment(ImploderAttachment.TYPE).getRightToken().getIndex();
while ((tokenizer.getTokenAt(rightIdx).getKind() == IToken.TK_LAYOUT || tokenizer.getTokenAt(rightIdx).getLength() == 0) && rightIdx > leftIdx) {
rightIdx--;
}
insertionPoint = tokenizer.getTokenAt(rightIdx).getEndOffset();
tokenPosition = rightIdx;
}
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;
}
}
}
}
return new Completion(name, sort, text, additionalInfo, insertionPoint + 1, suffixPoint, CompletionKind.expansion);
}
use of org.spoofax.terms.StrategoTerm 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);
}
use of org.spoofax.terms.StrategoTerm in project spoofax by metaborg.
the class JSGLRCompletionService method getCompletionTermsFromAST.
private Collection<IStrategoTerm> getCompletionTermsFromAST(ISpoofaxParseUnit completionParseResult) {
if (completionParseResult == null) {
return Lists.newLinkedList();
}
StrategoTerm ast = (StrategoTerm) completionParseResult.ast();
if (ast == null) {
return Lists.newLinkedList();
}
Collection<IStrategoTerm> completionTerm = findCompletionTerm(ast);
return completionTerm;
}
use of org.spoofax.terms.StrategoTerm 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);
}
use of org.spoofax.terms.StrategoTerm 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);
}
Aggregations