Search in sources :

Example 16 with Tuple2

use of org.antlr.v4.runtime.misc.Tuple2 in project antlr4 by tunnelvisionlabs.

the class RuleFunction method getElementFrequenciesForAlt.

/**
 * Given list of X and r refs in alt, compute how many of each there are
 */
protected Tuple2<FrequencySet<String>, FrequencySet<String>> getElementFrequenciesForAlt(AltAST ast) {
    try {
        ElementFrequenciesVisitor visitor = new ElementFrequenciesVisitor(rule.g, new CommonTreeNodeStream(new GrammarASTAdaptor(), ast));
        visitor.outerAlternative();
        if (visitor.frequencies.size() != 1) {
            factory.getGrammar().tool.errMgr.toolError(ErrorType.INTERNAL_ERROR);
            return Tuple.create(new FrequencySet<String>(), new FrequencySet<String>());
        }
        return Tuple.create(visitor.getMinFrequencies(), visitor.frequencies.peek());
    } catch (RecognitionException ex) {
        factory.getGrammar().tool.errMgr.toolError(ErrorType.INTERNAL_ERROR, ex);
        return Tuple.create(new FrequencySet<String>(), new FrequencySet<String>());
    }
}
Also used : GrammarASTAdaptor(org.antlr.v4.parse.GrammarASTAdaptor) RecognitionException(org.antlr.runtime.RecognitionException) FrequencySet(org.antlr.v4.misc.FrequencySet) CommonTreeNodeStream(org.antlr.runtime.tree.CommonTreeNodeStream)

Example 17 with Tuple2

use of org.antlr.v4.runtime.misc.Tuple2 in project antlr4 by tunnelvisionlabs.

the class RuleDependencyChecker method getDependencies.

public static List<Tuple2<RuleDependency, AnnotatedElement>> getDependencies(Class<?> clazz) {
    List<Tuple2<RuleDependency, AnnotatedElement>> result = new ArrayList<Tuple2<RuleDependency, AnnotatedElement>>();
    List<ElementType> supportedTarget = Arrays.asList(RuleDependency.class.getAnnotation(Target.class).value());
    for (ElementType target : supportedTarget) {
        switch(target) {
            case TYPE:
                if (!clazz.isAnnotation()) {
                    getElementDependencies(clazz, result);
                }
                break;
            case ANNOTATION_TYPE:
                if (!clazz.isAnnotation()) {
                    getElementDependencies(clazz, result);
                }
                break;
            case CONSTRUCTOR:
                for (Constructor<?> ctor : clazz.getDeclaredConstructors()) {
                    getElementDependencies(ctor, result);
                }
                break;
            case FIELD:
                for (Field field : clazz.getDeclaredFields()) {
                    getElementDependencies(field, result);
                }
                break;
            case LOCAL_VARIABLE:
                System.err.println("Runtime rule dependency checking is not supported for local variables.");
                break;
            case METHOD:
                for (Method method : clazz.getDeclaredMethods()) {
                    getElementDependencies(method, result);
                }
                break;
            case PACKAGE:
                // package is not a subset of class, so nothing to do here
                break;
            case PARAMETER:
                System.err.println("Runtime rule dependency checking is not supported for parameters.");
                break;
        }
    }
    return result;
}
Also used : Field(java.lang.reflect.Field) ElementType(java.lang.annotation.ElementType) ArrayList(java.util.ArrayList) AnnotatedElement(java.lang.reflect.AnnotatedElement) Method(java.lang.reflect.Method) RuleDependency(org.antlr.v4.runtime.RuleDependency)

Example 18 with Tuple2

use of org.antlr.v4.runtime.misc.Tuple2 in project antlr4 by tunnelvisionlabs.

the class RuleDependencyProcessor method checkDependencies.

private void checkDependencies(List<Tuple2<RuleDependency, Element>> dependencies, TypeMirror recognizerType) {
    String[] ruleNames = getRuleNames(recognizerType);
    int[] ruleVersions = getRuleVersions(recognizerType, ruleNames);
    RuleRelations relations = extractRuleRelations(recognizerType);
    for (Tuple2<RuleDependency, Element> dependency : dependencies) {
        try {
            if (!processingEnv.getTypeUtils().isAssignable(getRecognizerType(dependency.getItem1()), recognizerType)) {
                continue;
            }
            // this is the rule in the dependency set with the highest version number
            int effectiveRule = dependency.getItem1().rule();
            if (effectiveRule < 0 || effectiveRule >= ruleVersions.length) {
                Tuple2<AnnotationMirror, AnnotationValue> ruleReferenceElement = findRuleDependencyProperty(dependency, RuleDependencyProperty.RULE);
                String message = String.format("Rule dependency on unknown rule %d@%d in %s", dependency.getItem1().rule(), dependency.getItem1().version(), getRecognizerType(dependency.getItem1()).toString());
                if (ruleReferenceElement != null) {
                    processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message, dependency.getItem2(), ruleReferenceElement.getItem1(), ruleReferenceElement.getItem2());
                } else {
                    processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message, dependency.getItem2());
                }
                continue;
            }
            EnumSet<Dependents> dependents = EnumSet.of(Dependents.SELF, dependency.getItem1().dependents());
            reportUnimplementedDependents(dependency, dependents);
            BitSet checked = new BitSet();
            int highestRequiredDependency = checkDependencyVersion(dependency, ruleNames, ruleVersions, effectiveRule, null);
            if (dependents.contains(Dependents.PARENTS)) {
                BitSet parents = relations.parents[dependency.getItem1().rule()];
                for (int parent = parents.nextSetBit(0); parent >= 0; parent = parents.nextSetBit(parent + 1)) {
                    if (parent < 0 || parent >= ruleVersions.length || checked.get(parent)) {
                        continue;
                    }
                    checked.set(parent);
                    int required = checkDependencyVersion(dependency, ruleNames, ruleVersions, parent, "parent");
                    highestRequiredDependency = Math.max(highestRequiredDependency, required);
                }
            }
            if (dependents.contains(Dependents.CHILDREN)) {
                BitSet children = relations.children[dependency.getItem1().rule()];
                for (int child = children.nextSetBit(0); child >= 0; child = children.nextSetBit(child + 1)) {
                    if (child < 0 || child >= ruleVersions.length || checked.get(child)) {
                        continue;
                    }
                    checked.set(child);
                    int required = checkDependencyVersion(dependency, ruleNames, ruleVersions, child, "child");
                    highestRequiredDependency = Math.max(highestRequiredDependency, required);
                }
            }
            if (dependents.contains(Dependents.ANCESTORS)) {
                BitSet ancestors = relations.getAncestors(dependency.getItem1().rule());
                for (int ancestor = ancestors.nextSetBit(0); ancestor >= 0; ancestor = ancestors.nextSetBit(ancestor + 1)) {
                    if (ancestor < 0 || ancestor >= ruleVersions.length || checked.get(ancestor)) {
                        continue;
                    }
                    checked.set(ancestor);
                    int required = checkDependencyVersion(dependency, ruleNames, ruleVersions, ancestor, "ancestor");
                    highestRequiredDependency = Math.max(highestRequiredDependency, required);
                }
            }
            if (dependents.contains(Dependents.DESCENDANTS)) {
                BitSet descendants = relations.getDescendants(dependency.getItem1().rule());
                for (int descendant = descendants.nextSetBit(0); descendant >= 0; descendant = descendants.nextSetBit(descendant + 1)) {
                    if (descendant < 0 || descendant >= ruleVersions.length || checked.get(descendant)) {
                        continue;
                    }
                    checked.set(descendant);
                    int required = checkDependencyVersion(dependency, ruleNames, ruleVersions, descendant, "descendant");
                    highestRequiredDependency = Math.max(highestRequiredDependency, required);
                }
            }
            int declaredVersion = dependency.getItem1().version();
            if (declaredVersion > highestRequiredDependency) {
                Tuple2<AnnotationMirror, AnnotationValue> versionElement = findRuleDependencyProperty(dependency, RuleDependencyProperty.VERSION);
                String message = String.format("Rule dependency version mismatch: %s has maximum dependency version %d (expected %d) in %s", ruleNames[dependency.getItem1().rule()], highestRequiredDependency, declaredVersion, getRecognizerType(dependency.getItem1()).toString());
                if (versionElement != null) {
                    processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message, dependency.getItem2(), versionElement.getItem1(), versionElement.getItem2());
                } else {
                    processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message, dependency.getItem2());
                }
            }
        } catch (AnnotationTypeMismatchException ex) {
            processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, String.format("Could not validate rule dependencies for element %s", dependency.getItem2().toString()), dependency.getItem2());
        }
    }
}
Also used : VariableElement(javax.lang.model.element.VariableElement) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) BitSet(java.util.BitSet) AnnotationTypeMismatchException(java.lang.annotation.AnnotationTypeMismatchException) AnnotationMirror(javax.lang.model.element.AnnotationMirror) Dependents(org.antlr.v4.runtime.Dependents) AnnotationValue(javax.lang.model.element.AnnotationValue) RuleDependency(org.antlr.v4.runtime.RuleDependency)

Example 19 with Tuple2

use of org.antlr.v4.runtime.misc.Tuple2 in project antlr4 by tunnelvisionlabs.

the class RuleDependencyProcessor method process.

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
    if (!checkClassNameConstants()) {
        return true;
    }
    List<Tuple2<RuleDependency, Element>> dependencies = getDependencies(roundEnv);
    Map<TypeMirror, List<Tuple2<RuleDependency, Element>>> recognizerDependencies = new HashMap<TypeMirror, List<Tuple2<RuleDependency, Element>>>();
    for (Tuple2<RuleDependency, Element> dependency : dependencies) {
        TypeMirror recognizerType = getRecognizerType(dependency.getItem1());
        List<Tuple2<RuleDependency, Element>> list = recognizerDependencies.get(recognizerType);
        if (list == null) {
            list = new ArrayList<Tuple2<RuleDependency, Element>>();
            recognizerDependencies.put(recognizerType, list);
        }
        list.add(dependency);
    }
    for (Map.Entry<TypeMirror, List<Tuple2<RuleDependency, Element>>> entry : recognizerDependencies.entrySet()) {
        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, String.format("ANTLR 4: Validating %d dependencies on rules in %s.", entry.getValue().size(), entry.getKey().toString()));
        checkDependencies(entry.getValue(), entry.getKey());
    }
    return true;
}
Also used : TypeMirror(javax.lang.model.type.TypeMirror) HashMap(java.util.HashMap) VariableElement(javax.lang.model.element.VariableElement) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) RuleDependency(org.antlr.v4.runtime.RuleDependency)

Example 20 with Tuple2

use of org.antlr.v4.runtime.misc.Tuple2 in project antlr4 by tunnelvisionlabs.

the class RuleDependencyProcessor method getDependencies.

public static List<Tuple2<RuleDependency, Element>> getDependencies(RoundEnvironment roundEnv) {
    List<Tuple2<RuleDependency, Element>> result = new ArrayList<Tuple2<RuleDependency, Element>>();
    Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(RuleDependency.class);
    for (Element element : elements) {
        RuleDependency dependency = element.getAnnotation(RuleDependency.class);
        if (dependency == null) {
            continue;
        }
        result.add(Tuple.create(dependency, element));
    }
    elements = roundEnv.getElementsAnnotatedWith(RuleDependencies.class);
    for (Element element : elements) {
        RuleDependencies dependencies = element.getAnnotation(RuleDependencies.class);
        if (dependencies == null || dependencies.value() == null) {
            continue;
        }
        for (RuleDependency dependency : dependencies.value()) {
            result.add(Tuple.create(dependency, element));
        }
    }
    return result;
}
Also used : RuleDependencies(org.antlr.v4.runtime.RuleDependencies) VariableElement(javax.lang.model.element.VariableElement) TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) Element(javax.lang.model.element.Element) ArrayList(java.util.ArrayList) RuleDependency(org.antlr.v4.runtime.RuleDependency)

Aggregations

ArrayList (java.util.ArrayList)12 Tuple2 (org.antlr.v4.runtime.misc.Tuple2)7 GrammarAST (org.antlr.v4.tool.ast.GrammarAST)7 RuleDependency (org.antlr.v4.runtime.RuleDependency)5 AltAST (org.antlr.v4.tool.ast.AltAST)5 HashMap (java.util.HashMap)4 List (java.util.List)4 Lexer (org.antlr.v4.runtime.Lexer)4 Parser (org.antlr.v4.runtime.Parser)4 LinkedHashMap (java.util.LinkedHashMap)3 Element (javax.lang.model.element.Element)3 ExecutableElement (javax.lang.model.element.ExecutableElement)3 TypeElement (javax.lang.model.element.TypeElement)3 VariableElement (javax.lang.model.element.VariableElement)3 RecognitionException (org.antlr.runtime.RecognitionException)3 GrammarASTAdaptor (org.antlr.v4.parse.GrammarASTAdaptor)3 HashSet (java.util.HashSet)2 LinkedHashSet (java.util.LinkedHashSet)2 Map (java.util.Map)2 CommonToken (org.antlr.runtime.CommonToken)2