Method: getTypeDataList()

1: package org.overture.codegen.vdm2jml.predgen.info;
2:
3: import java.util.HashSet;
4: import java.util.LinkedList;
5: import java.util.List;
6: import java.util.Set;
7:
8: import org.apache.log4j.Logger;
9: import org.overture.ast.analysis.AnalysisException;
10: import org.overture.ast.analysis.DepthFirstAnalysisAdaptor;
11: import org.overture.ast.types.ABracketType;
12: import org.overture.ast.types.AInMapMapType;
13: import org.overture.ast.types.ANamedInvariantType;
14: import org.overture.ast.types.AOptionalType;
15: import org.overture.ast.types.AProductType;
16: import org.overture.ast.types.ASeq1SeqType;
17: import org.overture.ast.types.AUnionType;
18: import org.overture.ast.types.AUnknownType;
19: import org.overture.ast.types.PType;
20: import org.overture.ast.types.SMapTypeBase;
21: import org.overture.ast.types.SSeqTypeBase;
22: import org.overture.ast.types.SSetType;
23: import org.overture.codegen.ir.IRInfo;
24: import org.overture.codegen.ir.STypeIR;
25:
26: public class NamedTypeInvDepCalculator extends DepthFirstAnalysisAdaptor
27: {
28:         private List<NamedTypeInfo> typeInfoList;
29:         private IRInfo info;
30:
31:         private static Logger log = Logger.getLogger(NamedTypeInvDepCalculator.class.getName());
32:
33:         public NamedTypeInvDepCalculator(IRInfo info)
34:         {
35:                 super();
36:                 this.info = info;
37:                 this.typeInfoList = new LinkedList<NamedTypeInfo>();
38:         }
39:
40:         public List<NamedTypeInfo> getTypeDataList()
41:         {
42:                 return typeInfoList;
43:         }
44:
45:         public static NamedTypeInfo findTypeInfo(List<NamedTypeInfo> typeInfoList,
46:                         String defModule, String typeName)
47:         {
48:                 for (NamedTypeInfo t : typeInfoList)
49:                 {
50:                         if (NamedTypeInfo.isSameTypeDef(t, defModule, typeName))
51:                         {
52:                                 return t;
53:                         }
54:                 }
55:
56:                 return null;
57:         }
58:
59:         public boolean containsExactly(ANamedInvariantType node)
60:         {
61:                 String module = node.getName().getModule();
62:                 String typeName = node.getName().getName();
63:
64:                 for (NamedTypeInfo t : typeInfoList)
65:                 {
66:                         if (NamedTypeInfo.isSameTypeDef(t, module, typeName))
67:                         {
68:                                 return true;
69:                         }
70:                 }
71:
72:                 return false;
73:         }
74:
75:         @Override
76:         public void caseANamedInvariantType(ANamedInvariantType node)
77:                         throws AnalysisException
78:         {
79:                 // Avoid unnecessary construction
80:                 if (!containsExactly(node))
81:                 {
82:                         AbstractTypeInfo typeInfo = create(info, node, new HashSet<PType>());
83:
84:                         if (typeInfo instanceof NamedTypeInfo)
85:                         {
86:                                 typeInfoList.add((NamedTypeInfo) typeInfo);
87:                         } else
88:                         {
89:                                 log.error("Expected a '" + NamedTypeInfo.class.getSimpleName()
90:                                                 + "' to be returned. Got: " + typeInfo);
91:                         }
92:                 }
93:         }
94:
95:         private static AbstractTypeInfo create(IRInfo info, PType type,
96:                         Set<PType> visited)
97:         {
98:                 if (visited.contains(type))
99:                 {
100:                         // Type recursion
101:                         return new RecursiveLeaf();
102:                 } else
103:                 {
104:                         visited.add(type);
105:                 }
106:
107:                 boolean optional = false;
108:                 while (type instanceof AOptionalType || type instanceof ABracketType)
109:                 {
110:                         if (type instanceof AOptionalType)
111:                         {
112:                                 type = ((AOptionalType) type).getType();
113:                                 optional = true;
114:                         } else if (type instanceof ABracketType)
115:                         {
116:                                 type = ((ABracketType) type).getType();
117:                         }
118:                 }
119:
120:                 if (type instanceof ANamedInvariantType)
121:                 {
122:                         ANamedInvariantType namedType = (ANamedInvariantType) type;
123:
124:                         AbstractTypeInfo domainInfo = create(info, namedType.getType(), visited);
125:                         NamedTypeInfo namedInfo = new NamedTypeInfo(namedType.getName().getName(), namedType.getName().getModule(), namedType.getInvDef() != null, optional, domainInfo);
126:
127:                         return namedInfo;
128:
129:                 } else if (type instanceof AUnionType)
130:                 {
131:                         List<AbstractTypeInfo> types = new LinkedList<>();
132:
133:                         for (PType t : ((AUnionType) type).getTypes())
134:                         {
135:                                 AbstractTypeInfo tInfo = create(info, t, visited);
136:
137:                                 if (tInfo != null)
138:                                 {
139:                                         types.add(tInfo);
140:                                 }
141:                         }
142:
143:                         return new UnionInfo(optional, types);
144:
145:                 } else if (type instanceof AProductType)
146:                 {
147:                         List<AbstractTypeInfo> types = new LinkedList<>();
148:
149:                         for (PType t : ((AProductType) type).getTypes())
150:                         {
151:                                 AbstractTypeInfo tInfo = create(info, t, visited);
152:
153:                                 if (tInfo != null)
154:                                 {
155:                                         types.add(tInfo);
156:                                 }
157:                         }
158:
159:                         return new TupleInfo(optional, types);
160:                 } else if (type instanceof SSeqTypeBase)
161:                 {
162:                         SSeqTypeBase seqType = (SSeqTypeBase) type;
163:                         boolean isSeq1 = seqType instanceof ASeq1SeqType;
164:
165:                         return new SeqInfo(optional, create(info, seqType.getSeqof(), visited), isSeq1);
166:                 } else if (type instanceof SSetType)
167:                 {
168:                         SSetType setType = (SSetType) type;
169:
170:                         return new SetInfo(optional, create(info, setType.getSetof(), visited));
171:                 } else if (type instanceof SMapTypeBase)
172:                 {
173:                         SMapTypeBase mapType = (SMapTypeBase) type;
174:
175:                         AbstractTypeInfo fromInfo = create(info, mapType.getFrom(), visited);
176:                         AbstractTypeInfo toInfo = create(info, mapType.getTo(), visited);
177:
178:                         boolean injective = type instanceof AInMapMapType;
179:
180:                         return new MapInfo(optional, fromInfo, toInfo, injective);
181:                 } else if (type instanceof AUnknownType)
182:                 {
183:                         return new UnknownLeaf();
184:                 } else
185:                 {
186:                         return new LeafTypeInfo(toIrType(type, info), optional);
187:                 }
188:         }
189:
190:         public static STypeIR toIrType(PType type, IRInfo info)
191:         {
192:                 try
193:                 {
194:                         STypeIR irType = type.apply(info.getTypeVisitor(), info);
195:
196:                         if (irType != null)
197:                         {
198:                                 irType.setOptional(false);
199:                         }
200:
201:                         return irType;
202:
203:                 } catch (AnalysisException e)
204:                 {
205:                         log.error("Problems encountered while attempting "
206:                                         + "to construct the IR type from a VDM type: "
207:                                         + e.getMessage());
208:                         e.printStackTrace();
209:                         return null;
210:                 }
211:         }
212: }