Search in sources :

Example 1 with ModelElement

use of org.antlr.v4.codegen.model.ModelElement in project antlr4 by antlr.

the class OutputModelWalker method walk.

public ST walk(OutputModelObject omo, boolean header) {
    // CREATE TEMPLATE FOR THIS OUTPUT OBJECT
    Class<? extends OutputModelObject> cl = omo.getClass();
    String templateName = cl.getSimpleName();
    if (templateName == null) {
        tool.errMgr.toolError(ErrorType.NO_MODEL_TO_TEMPLATE_MAPPING, cl.getSimpleName());
        return new ST("[" + templateName + " invalid]");
    }
    if (header)
        templateName += "Header";
    ST st = templates.getInstanceOf(templateName);
    if (st == null) {
        tool.errMgr.toolError(ErrorType.CODE_GEN_TEMPLATES_INCOMPLETE, templateName);
        return new ST("[" + templateName + " invalid]");
    }
    if (st.impl.formalArguments == null) {
        tool.errMgr.toolError(ErrorType.CODE_TEMPLATE_ARG_ISSUE, templateName, "<none>");
        return st;
    }
    Map<String, FormalArgument> formalArgs = st.impl.formalArguments;
    // PASS IN OUTPUT MODEL OBJECT TO TEMPLATE AS FIRST ARG
    Set<String> argNames = formalArgs.keySet();
    Iterator<String> arg_it = argNames.iterator();
    // ordered so this is first arg
    String modelArgName = arg_it.next();
    st.add(modelArgName, omo);
    // COMPUTE STs FOR EACH NESTED MODEL OBJECT MARKED WITH @ModelElement AND MAKE ST ATTRIBUTE
    Set<String> usedFieldNames = new HashSet<String>();
    Field[] fields = cl.getFields();
    for (Field fi : fields) {
        ModelElement annotation = fi.getAnnotation(ModelElement.class);
        if (annotation == null) {
            continue;
        }
        String fieldName = fi.getName();
        if (!usedFieldNames.add(fieldName)) {
            tool.errMgr.toolError(ErrorType.INTERNAL_ERROR, "Model object " + omo.getClass().getSimpleName() + " has multiple fields named '" + fieldName + "'");
            continue;
        }
        // Just don't set @ModelElement fields w/o formal arg in target ST
        if (formalArgs.get(fieldName) == null)
            continue;
        try {
            Object o = fi.get(omo);
            if (o instanceof OutputModelObject) {
                // SINGLE MODEL OBJECT?
                OutputModelObject nestedOmo = (OutputModelObject) o;
                ST nestedST = walk(nestedOmo, header);
                //					System.out.println("set ModelElement "+fieldName+"="+nestedST+" in "+templateName);
                st.add(fieldName, nestedST);
            } else if (o instanceof Collection || o instanceof OutputModelObject[]) {
                // LIST OF MODEL OBJECTS?
                if (o instanceof OutputModelObject[]) {
                    o = Arrays.asList((OutputModelObject[]) o);
                }
                Collection<?> nestedOmos = (Collection<?>) o;
                for (Object nestedOmo : nestedOmos) {
                    if (nestedOmo == null)
                        continue;
                    ST nestedST = walk((OutputModelObject) nestedOmo, header);
                    //						System.out.println("set ModelElement "+fieldName+"="+nestedST+" in "+templateName);
                    st.add(fieldName, nestedST);
                }
            } else if (o instanceof Map) {
                Map<?, ?> nestedOmoMap = (Map<?, ?>) o;
                Map<Object, ST> m = new LinkedHashMap<Object, ST>();
                for (Map.Entry<?, ?> entry : nestedOmoMap.entrySet()) {
                    ST nestedST = walk((OutputModelObject) entry.getValue(), header);
                    //						System.out.println("set ModelElement "+fieldName+"="+nestedST+" in "+templateName);
                    m.put(entry.getKey(), nestedST);
                }
                st.add(fieldName, m);
            } else if (o != null) {
                tool.errMgr.toolError(ErrorType.INTERNAL_ERROR, "not recognized nested model element: " + fieldName);
            }
        } catch (IllegalAccessException iae) {
            tool.errMgr.toolError(ErrorType.CODE_TEMPLATE_ARG_ISSUE, templateName, fieldName);
        }
    }
    //st.impl.dump();
    return st;
}
Also used : ST(org.stringtemplate.v4.ST) OutputModelObject(org.antlr.v4.codegen.model.OutputModelObject) LinkedHashMap(java.util.LinkedHashMap) FormalArgument(org.stringtemplate.v4.compiler.FormalArgument) Field(java.lang.reflect.Field) ModelElement(org.antlr.v4.codegen.model.ModelElement) Collection(java.util.Collection) OutputModelObject(org.antlr.v4.codegen.model.OutputModelObject) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) HashSet(java.util.HashSet)

Aggregations

Field (java.lang.reflect.Field)1 Collection (java.util.Collection)1 HashSet (java.util.HashSet)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 ModelElement (org.antlr.v4.codegen.model.ModelElement)1 OutputModelObject (org.antlr.v4.codegen.model.OutputModelObject)1 ST (org.stringtemplate.v4.ST)1 FormalArgument (org.stringtemplate.v4.compiler.FormalArgument)1