-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f273cb2
commit f8f5c92
Showing
4 changed files
with
175 additions
and
175 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
118 changes: 59 additions & 59 deletions
118
...notationAwareFollowElementCalculator.java → ...notationAwareFollowElementCalculator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,59 +1,59 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2016 Avaloq Group AG and others. | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v1.0 | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/legal/epl-v10.html | ||
* | ||
* Contributors: | ||
* Avaloq Group AG - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package com.avaloq.tools.ddk.xtext.ide.contentAssist; | ||
|
||
import java.util.ArrayDeque; | ||
import java.util.Deque; | ||
import java.util.Set; | ||
|
||
import org.eclipse.xtext.AbstractRule; | ||
import org.eclipse.xtext.EcoreUtil2; | ||
import org.eclipse.xtext.GrammarUtil; | ||
import org.eclipse.xtext.ParserRule; | ||
import org.eclipse.xtext.RuleCall; | ||
import org.eclipse.xtext.ide.editor.contentassist.antlr.FollowElementCalculator; | ||
|
||
import com.avaloq.tools.ddk.xtext.parser.ISemanticPredicates; | ||
import com.google.common.collect.Sets; | ||
import com.google.inject.Inject; | ||
|
||
|
||
public class AnnotationAwareFollowElementCalculator extends FollowElementCalculator { | ||
@Inject | ||
private ISemanticPredicates keywordPredicates; | ||
|
||
@Override | ||
public Boolean caseParserRule(final ParserRule object) { | ||
// copy of super class, but also descend into rules that contain keyword rules, rules that are just KeyWords, and rules that only delegate to other rules. | ||
if (GrammarUtil.isDatatypeRule(object) && !canContainKeywordRule(object) && !ParserRuleUtil.isEnumLikeDatatypeRule(object) | ||
&& !ParserRuleUtil.isDelegatingDatatypeRule(object)) { | ||
return Boolean.FALSE; | ||
} | ||
return doSwitch(object.getAlternatives()); | ||
} | ||
|
||
private boolean canContainKeywordRule(final ParserRule rule) { | ||
Set<AbstractRule> visitedRules = Sets.newHashSet(rule); | ||
Deque<RuleCall> ruleCallsToVisit = new ArrayDeque<>(EcoreUtil2.getAllContentsOfType(rule, RuleCall.class)); | ||
while (!ruleCallsToVisit.isEmpty()) { | ||
AbstractRule referencedRule = ruleCallsToVisit.pollFirst().getRule(); | ||
if (visitedRules.add(referencedRule)) { | ||
if (keywordPredicates.isKeywordRule(referencedRule.getName())) { | ||
return true; | ||
} | ||
ruleCallsToVisit.addAll(EcoreUtil2.getAllContentsOfType(referencedRule, RuleCall.class)); | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
} | ||
/******************************************************************************* | ||
* Copyright (c) 2016 Avaloq Group AG and others. | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v1.0 | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/legal/epl-v10.html | ||
* | ||
* Contributors: | ||
* Avaloq Group AG - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package com.avaloq.tools.ddk.xtext.ide.contentassist; | ||
|
||
import java.util.ArrayDeque; | ||
import java.util.Deque; | ||
import java.util.Set; | ||
|
||
import org.eclipse.xtext.AbstractRule; | ||
import org.eclipse.xtext.EcoreUtil2; | ||
import org.eclipse.xtext.GrammarUtil; | ||
import org.eclipse.xtext.ParserRule; | ||
import org.eclipse.xtext.RuleCall; | ||
import org.eclipse.xtext.ide.editor.contentassist.antlr.FollowElementCalculator; | ||
|
||
import com.avaloq.tools.ddk.xtext.parser.ISemanticPredicates; | ||
import com.google.common.collect.Sets; | ||
import com.google.inject.Inject; | ||
|
||
|
||
public class AnnotationAwareFollowElementCalculator extends FollowElementCalculator { | ||
@Inject | ||
private ISemanticPredicates keywordPredicates; | ||
|
||
@Override | ||
public Boolean caseParserRule(final ParserRule object) { | ||
// copy of super class, but also descend into rules that contain keyword rules, rules that are just KeyWords, and rules that only delegate to other rules. | ||
if (GrammarUtil.isDatatypeRule(object) && !canContainKeywordRule(object) && !ParserRuleUtil.isEnumLikeDatatypeRule(object) | ||
&& !ParserRuleUtil.isDelegatingDatatypeRule(object)) { | ||
return Boolean.FALSE; | ||
} | ||
return doSwitch(object.getAlternatives()); | ||
} | ||
|
||
private boolean canContainKeywordRule(final ParserRule rule) { | ||
Set<AbstractRule> visitedRules = Sets.newHashSet(rule); | ||
Deque<RuleCall> ruleCallsToVisit = new ArrayDeque<>(EcoreUtil2.getAllContentsOfType(rule, RuleCall.class)); | ||
while (!ruleCallsToVisit.isEmpty()) { | ||
AbstractRule referencedRule = ruleCallsToVisit.pollFirst().getRule(); | ||
if (visitedRules.add(referencedRule)) { | ||
if (keywordPredicates.isKeywordRule(referencedRule.getName())) { | ||
return true; | ||
} | ||
ruleCallsToVisit.addAll(EcoreUtil2.getAllContentsOfType(referencedRule, RuleCall.class)); | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
} |
128 changes: 64 additions & 64 deletions
128
...AnnotationAwareFollowElementComputer.java → ...AnnotationAwareFollowElementComputer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,64 +1,64 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2016 Avaloq Group AG and others. | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v1.0 | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/legal/epl-v10.html | ||
* | ||
* Contributors: | ||
* Avaloq Group AG - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package com.avaloq.tools.ddk.xtext.ide.contentAssist; | ||
|
||
import java.util.Collection; | ||
|
||
import org.eclipse.xtext.AbstractElement; | ||
import org.eclipse.xtext.GrammarUtil; | ||
import org.eclipse.xtext.ParserRule; | ||
import org.eclipse.xtext.RuleCall; | ||
import org.eclipse.xtext.ide.editor.contentassist.IFollowElementAcceptor; | ||
import org.eclipse.xtext.ide.editor.contentassist.antlr.FollowElement; | ||
import org.eclipse.xtext.ide.editor.contentassist.antlr.FollowElementCalculator; | ||
import org.eclipse.xtext.ide.editor.contentassist.antlr.FollowElementComputer; | ||
|
||
import com.avaloq.tools.ddk.xtext.parser.ISemanticPredicates; | ||
import com.google.inject.Inject; | ||
import com.google.inject.Provider; | ||
|
||
|
||
public class AnnotationAwareFollowElementComputer extends FollowElementComputer { | ||
@Inject | ||
private Provider<FollowElementCalculator> feCalculatorProvider; | ||
@Inject | ||
private ISemanticPredicates keywordPredicates; | ||
|
||
@Override | ||
public void computeFollowElements(final Collection<FollowElement> followElements, final IFollowElementAcceptor followElementAcceptor) { | ||
// copy of super class but initialisation of calculator moved to protected method. | ||
FollowElementCalculator calculator = feCalculatorProvider.get(); | ||
initialiseCalculator(calculator, followElementAcceptor); | ||
for (FollowElement element : followElements) { | ||
computeFollowElements(calculator, element); | ||
} | ||
} | ||
|
||
protected void initialiseCalculator(final FollowElementCalculator calculator, final IFollowElementAcceptor followElementAcceptor) { | ||
// copied from super class but calls to keyword rules are also accepted. | ||
calculator.setAcceptor(element -> { | ||
ParserRule rule = GrammarUtil.containingParserRule(element); | ||
if (rule == null || !GrammarUtil.isDatatypeRule(rule) || isKeywordRuleCall(element) || ParserRuleUtil.isEnumLikeDatatypeRule(rule)) { | ||
followElementAcceptor.accept(element); | ||
} | ||
}); | ||
} | ||
|
||
private boolean isKeywordRuleCall(final AbstractElement element) { | ||
if (element instanceof RuleCall) { | ||
RuleCall ruleCall = (RuleCall) element; | ||
return keywordPredicates.isKeywordRule(ruleCall.getRule().getName()); | ||
} | ||
return false; | ||
} | ||
|
||
} | ||
/******************************************************************************* | ||
* Copyright (c) 2016 Avaloq Group AG and others. | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v1.0 | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/legal/epl-v10.html | ||
* | ||
* Contributors: | ||
* Avaloq Group AG - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package com.avaloq.tools.ddk.xtext.ide.contentassist; | ||
|
||
import java.util.Collection; | ||
|
||
import org.eclipse.xtext.AbstractElement; | ||
import org.eclipse.xtext.GrammarUtil; | ||
import org.eclipse.xtext.ParserRule; | ||
import org.eclipse.xtext.RuleCall; | ||
import org.eclipse.xtext.ide.editor.contentassist.IFollowElementAcceptor; | ||
import org.eclipse.xtext.ide.editor.contentassist.antlr.FollowElement; | ||
import org.eclipse.xtext.ide.editor.contentassist.antlr.FollowElementCalculator; | ||
import org.eclipse.xtext.ide.editor.contentassist.antlr.FollowElementComputer; | ||
|
||
import com.avaloq.tools.ddk.xtext.parser.ISemanticPredicates; | ||
import com.google.inject.Inject; | ||
import com.google.inject.Provider; | ||
|
||
|
||
public class AnnotationAwareFollowElementComputer extends FollowElementComputer { | ||
@Inject | ||
private Provider<FollowElementCalculator> feCalculatorProvider; | ||
@Inject | ||
private ISemanticPredicates keywordPredicates; | ||
|
||
@Override | ||
public void computeFollowElements(final Collection<FollowElement> followElements, final IFollowElementAcceptor followElementAcceptor) { | ||
// copy of super class but initialisation of calculator moved to protected method. | ||
FollowElementCalculator calculator = feCalculatorProvider.get(); | ||
initialiseCalculator(calculator, followElementAcceptor); | ||
for (FollowElement element : followElements) { | ||
computeFollowElements(calculator, element); | ||
} | ||
} | ||
|
||
protected void initialiseCalculator(final FollowElementCalculator calculator, final IFollowElementAcceptor followElementAcceptor) { | ||
// copied from super class but calls to keyword rules are also accepted. | ||
calculator.setAcceptor(element -> { | ||
ParserRule rule = GrammarUtil.containingParserRule(element); | ||
if (rule == null || !GrammarUtil.isDatatypeRule(rule) || isKeywordRuleCall(element) || ParserRuleUtil.isEnumLikeDatatypeRule(rule)) { | ||
followElementAcceptor.accept(element); | ||
} | ||
}); | ||
} | ||
|
||
private boolean isKeywordRuleCall(final AbstractElement element) { | ||
if (element instanceof RuleCall) { | ||
RuleCall ruleCall = (RuleCall) element; | ||
return keywordPredicates.isKeywordRule(ruleCall.getRule().getName()); | ||
} | ||
return false; | ||
} | ||
|
||
} |
102 changes: 51 additions & 51 deletions
102
...ext/ide/contentAssist/ParserRuleUtil.java → ...ext/ide/contentassist/ParserRuleUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,51 +1,51 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2016 Avaloq Group AG and others. | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v1.0 | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/legal/epl-v10.html | ||
* | ||
* Contributors: | ||
* Avaloq Group AG - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package com.avaloq.tools.ddk.xtext.ide.contentAssist; | ||
|
||
import org.eclipse.xtext.GrammarUtil; | ||
import org.eclipse.xtext.ParserRule; | ||
|
||
|
||
public final class ParserRuleUtil { | ||
private ParserRuleUtil() { | ||
// prevent construction of util class. | ||
} | ||
|
||
/** | ||
* Determines whether a ParserRule is a datatype rule containing keywords only. | ||
* | ||
* @param rule | ||
* the rule to be tested | ||
* @return true if datatype rule contains keywords only | ||
*/ | ||
public static boolean isEnumLikeDatatypeRule(final ParserRule rule) { | ||
if (!GrammarUtil.isDatatypeRule(rule) || !GrammarUtil.containedRuleCalls(rule).isEmpty()) { | ||
return false; | ||
} | ||
return !GrammarUtil.containedKeywords(rule).isEmpty(); | ||
} | ||
|
||
/** | ||
* Determines whether a ParserRule is a datatype rule containing RuleCalls only. | ||
* | ||
* @param rule | ||
* the rule to be tested | ||
* @return true if datatype rule contains RuleCalls only | ||
*/ | ||
public static boolean isDelegatingDatatypeRule(final ParserRule rule) { | ||
if (!GrammarUtil.isDatatypeRule(rule) || !GrammarUtil.containedKeywords(rule).isEmpty()) { | ||
return false; | ||
} | ||
return !GrammarUtil.containedRuleCalls(rule).isEmpty(); | ||
} | ||
|
||
} | ||
/******************************************************************************* | ||
* Copyright (c) 2016 Avaloq Group AG and others. | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v1.0 | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/legal/epl-v10.html | ||
* | ||
* Contributors: | ||
* Avaloq Group AG - initial API and implementation | ||
*******************************************************************************/ | ||
|
||
package com.avaloq.tools.ddk.xtext.ide.contentassist; | ||
|
||
import org.eclipse.xtext.GrammarUtil; | ||
import org.eclipse.xtext.ParserRule; | ||
|
||
|
||
public final class ParserRuleUtil { | ||
private ParserRuleUtil() { | ||
// prevent construction of util class. | ||
} | ||
|
||
/** | ||
* Determines whether a ParserRule is a datatype rule containing keywords only. | ||
* | ||
* @param rule | ||
* the rule to be tested | ||
* @return true if datatype rule contains keywords only | ||
*/ | ||
public static boolean isEnumLikeDatatypeRule(final ParserRule rule) { | ||
if (!GrammarUtil.isDatatypeRule(rule) || !GrammarUtil.containedRuleCalls(rule).isEmpty()) { | ||
return false; | ||
} | ||
return !GrammarUtil.containedKeywords(rule).isEmpty(); | ||
} | ||
|
||
/** | ||
* Determines whether a ParserRule is a datatype rule containing RuleCalls only. | ||
* | ||
* @param rule | ||
* the rule to be tested | ||
* @return true if datatype rule contains RuleCalls only | ||
*/ | ||
public static boolean isDelegatingDatatypeRule(final ParserRule rule) { | ||
if (!GrammarUtil.isDatatypeRule(rule) || !GrammarUtil.containedKeywords(rule).isEmpty()) { | ||
return false; | ||
} | ||
return !GrammarUtil.containedRuleCalls(rule).isEmpty(); | ||
} | ||
|
||
} |