use of org.eclipse.xtext.AbstractElement in project xtext-core by eclipse.
the class EntryPointFinder method findEntryPoint.
public ICompositeNode findEntryPoint(IParseResult parseResult, int offset) {
ICompositeNode rootNode = parseResult.getRootNode();
if (rootNode.getTotalLength() == offset) {
return null;
}
ILeafNode leafNode = NodeModelUtils.findLeafNodeAtOffset(rootNode, offset);
ICompositeNode parent = leafNode.getParent();
ICompositeNode result = findEntryPoint(parent, offset);
if (result != null) {
EObject grammarElement = result.getGrammarElement();
if (grammarElement instanceof AbstractElement) {
return result;
}
}
return null;
}
use of org.eclipse.xtext.AbstractElement in project xtext-core by eclipse.
the class EntryPointFinder method shouldUseParent.
protected boolean shouldUseParent(ICompositeNode result, int offset, ILeafNode leaf) {
if (leaf.getTotalEndOffset() == offset) {
return true;
}
if (result.getGrammarElement() instanceof RuleCall) {
RuleCall rc = (RuleCall) result.getGrammarElement();
if (!rc.getArguments().isEmpty()) {
return true;
}
Assignment assignment = GrammarUtil.containingAssignment(rc);
if (assignment != null && (GrammarUtil.isMultipleCardinality(assignment) || (assignment.eContainer() instanceof AbstractElement && GrammarUtil.isMultipleCardinality((AbstractElement) assignment.eContainer())))) {
return true;
}
}
return false;
}
use of org.eclipse.xtext.AbstractElement in project xtext-core by eclipse.
the class FollowElementCalculator method caseUnorderedGroup.
@Override
public Boolean caseUnorderedGroup(UnorderedGroup object) {
if (object == this.group) {
boolean more = true;
for (AbstractElement element : object.getElements()) {
if (handledAlternatives == null || !handledAlternatives.contains(element)) {
this.group = null;
more = doSwitch(element) && more;
this.group = object;
}
}
if (more && GrammarUtil.isMultipleCardinality(object)) {
handledAlternatives = null;
this.group = null;
return caseUnorderedGroup(object);
}
return more || isOptional(object);
} else {
boolean more = true;
for (AbstractElement element : object.getElements()) {
more = doSwitch(element) && more;
}
return more || isOptional(object);
}
}
use of org.eclipse.xtext.AbstractElement in project xtext-core by eclipse.
the class FollowElementComputer method computeFollowElements.
protected void computeFollowElements(FollowElementCalculator calculator, FollowElement element, Multimap<Integer, List<AbstractElement>> visited) {
List<AbstractElement> currentState = Lists.newArrayList(element.getLocalTrace());
if (currentState.isEmpty() || currentState.get(currentState.size() - 1) != element.getGrammarElement()) {
currentState.add(element.getGrammarElement());
}
if (!visited.put(element.getLookAhead(), currentState))
return;
if (element.getLookAhead() <= 1) {
List<Integer> paramStack = element.getParamStack();
int paramIndex = computeParamStackOffset(currentState, paramStack);
for (AbstractElement abstractElement : currentState) {
paramIndex = setParamConfigAndUpdateOffset(calculator, paramStack, paramIndex, abstractElement);
Assignment ass = EcoreUtil2.getContainerOfType(abstractElement, Assignment.class);
if (ass != null)
calculator.doSwitch(ass);
else {
if (abstractElement instanceof UnorderedGroup && abstractElement == element.getGrammarElement()) {
calculator.doSwitch((UnorderedGroup) abstractElement, element.getHandledUnorderedGroupElements());
} else {
calculator.doSwitch(abstractElement);
if (GrammarUtil.isOptionalCardinality(abstractElement)) {
EObject container = abstractElement.eContainer();
if (container instanceof Group) {
Group group = (Group) container;
int idx = group.getElements().indexOf(abstractElement);
if (idx == group.getElements().size() - 1) {
if (!currentState.contains(group) && GrammarUtil.isMultipleCardinality(group)) {
calculator.doSwitch(group);
}
} else if (idx < group.getElements().size() - 1 && "?".equals(abstractElement.getCardinality())) {
// loops are fine
AbstractElement nextElement = group.getElements().get(idx + 1);
if (!currentState.contains(nextElement)) {
calculator.doSwitch(nextElement);
}
}
}
} else if (isAlternativeWithEmptyPath(abstractElement)) {
EObject container = abstractElement.eContainer();
if (container instanceof Group) {
Group group = (Group) container;
int idx = group.getElements().indexOf(abstractElement);
if (!currentState.contains(group) && idx != group.getElements().size() - 1) {
AbstractElement next = group.getElements().get(idx + 1);
if (!currentState.contains(next)) {
calculator.doSwitch(next);
}
}
}
}
}
}
}
// we need a synthetic rule call
if (element.getTrace().equals(element.getLocalTrace())) {
ParserRule parserRule = GrammarUtil.containingParserRule(element.getGrammarElement());
if (parserRule != null) {
RuleCall ruleCall = XtextFactory.eINSTANCE.createRuleCall();
ruleCall.setRule(parserRule);
calculator.doSwitch(ruleCall);
}
}
return;
}
Collection<FollowElement> followElements = parser.getFollowElements(element);
for (FollowElement newElement : followElements) {
if (newElement.getLookAhead() != element.getLookAhead() || newElement.getGrammarElement() != element.getGrammarElement()) {
if (newElement.getLookAhead() == element.getLookAhead()) {
int originalTraceSize = element.getLocalTrace().size();
List<AbstractElement> newTrace = newElement.getLocalTrace();
if (newTrace.size() > originalTraceSize) {
if (Collections.indexOfSubList(element.getLocalTrace(), newTrace.subList(originalTraceSize, newTrace.size())) != -1) {
continue;
}
}
}
computeFollowElements(calculator, newElement, visited);
}
}
}
use of org.eclipse.xtext.AbstractElement in project xtext-core by eclipse.
the class RequiredRuleNameComputer method getRequiredRuleNames.
/**
* Returns the names of parser rules that should be called in order to obtain the follow elements for the parser
* call stack described by the given param.
*/
public String[][] getRequiredRuleNames(Param param) {
if (isFiltered(param)) {
return EMPTY_ARRAY;
}
AbstractElement elementToParse = param.elementToParse;
String ruleName = param.ruleName;
if (ruleName == null) {
return getRequiredRuleNames(param, elementToParse);
}
return getAdjustedRequiredRuleNames(param, elementToParse, ruleName);
}
Aggregations