/** * Removes all expected elements that refer to the same terminal. Attention: This method assumes * that the given list of expected terminals contains only elements that start at the same * position. */ protected void removeDuplicateEntriesFromBucket( List<org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedTerminal> expectedElements) { int size = expectedElements.size(); for (int i = 0; i < size - 1; i++) { org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedTerminal elementAtIndex = expectedElements.get(i); org.emftext.language.xpath3.resource.xpath3.IXpath3ExpectedElement terminal = elementAtIndex.getTerminal(); for (int j = i + 1; j < size; ) { org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedTerminal elementAtNext = expectedElements.get(j); EClass metaClass = elementAtIndex.getContainmentTrace().getStartClass(); EClass nextMetaClass = elementAtNext.getContainmentTrace().getStartClass(); org.emftext.language.xpath3.resource.xpath3.IXpath3ExpectedElement nextTerminal = elementAtNext.getTerminal(); // Terminals that have a different root meta class in the containment trace must // be kept because they can the decision whether an expected terminals is valid or // not depends on the root of the containment trace. boolean differentMetaclass = metaClass != nextMetaClass; if (terminal.equals(nextTerminal) && !differentMetaclass) { expectedElements.remove(j); size--; } else { j++; } } } }
protected void removeInvalidEntriesAtEnd( List<org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedTerminal> expectedElements) { org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3FollowSetGroupList followSetGroupList = new org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3FollowSetGroupList( expectedElements); List<org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3FollowSetGroup> followSetGroups = followSetGroupList.getFollowSetGroups(); int lastStartExcludingHiddenTokens = -1; for (org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3FollowSetGroup followSetGroup : followSetGroups) { boolean sameStartExcludingHiddenTokens = followSetGroup.hasSameStartExcludingHiddenTokens(lastStartExcludingHiddenTokens); lastStartExcludingHiddenTokens = followSetGroup.getStartExcludingHiddenTokens(); EObject container = followSetGroup.getContainer(); EClass currentRule = null; if (container != null) { currentRule = container.eClass(); } List<org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedTerminal> expectedTerminals = followSetGroup.getExpectedTerminals(); for (org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedTerminal expectedTerminal : expectedTerminals) { org.emftext.language.xpath3.resource.xpath3.IXpath3ExpectedElement terminalAtIndex = expectedTerminal.getTerminal(); EClass ruleMetaclass = terminalAtIndex.getRuleMetaclass(); boolean differentRule = currentRule != ruleMetaclass; // If the two expected elements have a different parent in the syntax definition, // we must not discard the second element, because it probably stems from a parent // rule. org.emftext.language.xpath3.resource.xpath3.grammar.Xpath3ContainmentTrace containmentTrace = expectedTerminal.getContainmentTrace(); boolean fitsAtCurrentPosition = fitsAtCurrentPosition(container, containmentTrace); boolean inContainmentTrace = pathToRootContains(container, expectedTerminal.getTerminal().getRuleMetaclass()); boolean keepElement = true; if (differentRule && !inContainmentTrace) { if (!fitsAtCurrentPosition) { keepElement = false; } } if (sameStartExcludingHiddenTokens) { keepElement = false; } if (keepElement) { } else { // We must not call expectedElements.remove(expectedTerminal) because the // hashCode() method of ExpectedTerminal does not consider the start positions and // remove the wrong elements. for (int i = 0; i < expectedElements.size(); i++) { org.emftext.language.xpath3.resource.xpath3.mopp.Xpath3ExpectedTerminal next = expectedElements.get(i); if (next == expectedTerminal) { expectedElements.remove(i); break; } } } } } }